No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

17 Días
19 Hrs
55 Min
20 Seg

Tipos de almacenamiento de datos: memory, storage y call data

11/21
Recursos

Las variables pueden tener una ubicación distinta dentro de su almacenamiento en el contrato dependiendo del uso que se les vaya a dar y cómo se utilicen.

Tipos de almacenamiento de datos

Para especificar la localización de los datos en un contrato, veremos a continuación tres posibilidades y dependiendo la misma, una variable tendrá un comportamiento u otro.

Storage

Indica que una variable será guardada dentro de la Blockchain. Siempre podremos obtener un valor desde el storage dado que todo en Blockchain es inmutable. A este tipo de memoria se le conoce como memoria persistente.

Memory

Las variables del tipo memory solo pueden ser usadas mientras se llama a una función. Después de esto, la misma se borrará. Este tipo de variable puede modificarse mientras está en uso.

Calldata

Similar a memory, con la diferencia de que aquí las variables no se pueden modificar mientras estén en uso. Si se sabe de antemano que una variable no necesitará modificarse, es buena práctica usar calldata para reducir el consumo de gas.

Por defecto, las variables de estado del contrato son guardadas en el storage, mientras que los parámetros de una función son guardados en memory. Los únicos tipos de datos a los que se les puede asignar un almacenamiento distinto son los tipos string, array, struct y mapping.

El tipo de almacenamiento de una variable cambiará el ciclo de vida de la misma. Haciendo que esta sea modificable o persistente dentro del contrato. Es muy importante entender la diferencia entre cada tipo para saber cuándo es conveniente utilizar cada uno y mejorar el rendimiento de un contrato.


Contribución creada por: Luis Enrique Herrera y Kevin Fiorentino (Platzi Contributors).

Aportes 38

Preguntas 8

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Copien y peguen el siguiente código en remix si necesitan apoyo visual. Espero que las notas les sirvan de mucho

// SPDX-License-Identifier: GPL-3.0
 pragma solidity >=0.7.0 <0.9.0;
 
 contract platziProject{
     //Aqui creamos nuestras variables
     bool isFundable;
     uint256 Goal; 
     uint256 totalFunded;
     address owner;
     uint256 requiredFunds;
     
     //Inicializamoslos valores, hay que recordar que el constructor se ejecuta solo una vez cuando se crea el contrato
     constructor(){
         Goal = 0;
         owner = msg.sender;
         totalFunded = 0;
         isFundable = true;
     }
     //No te  preocupes por esto,luego loaprenderemos. El modifier permite cambiar el comppoprtamiento de funciones, ene ste caso solo queria asegurarme que solo el creador del contrato pudiera mover el Goal
     modifier onlyOwner{
         require(msg.sender == owner, "You need to be thhe owner from this contract to change the goal");
         _;
     }
     //Aqui ponemos la meta a recaudar,solamente el que iniciaiza el contrato puede cambiar este valor
     function setGoal(uint256 goal) public onlyOwner {
         Goal = goal;
     }
     
     function viewGoal() public view returns(uint256) {
         return Goal;
     }
     
     function changeProjectState(bool change)public onlyOwner{
         isFundable = change;
     }
     //Aqui inicia la funcion para fondear el proyecto
     function fundproject() public payable {
         //Primero evaluamos si el owner del contrato mantiene abiertas las donaciones (tal vez necesita reevaluar algo)
         require(isFundable, "Owner has decided to stop this fundraising for a while. Stay tuned");
         //Comprobamos que el total que se ha fondeado sea menor a la meta
         require(totalFunded < Goal, "Goal already achieved so you are  not able to fund this anymore");
         //Despues nos aeguramos que la persona mande un minimo,en este caso arriba de 0
         require(msg.value != uint(0), "Please add some funds to  contribuite to Platzi project");
         //Comprobamos que el valor que quiere fondear no exceda con a meta que tenemos
         require(totalFunded + msg.value <= Goal,"unable to add more funds, check amount remaining for our goal");
         //Actualizamos el total que se ha fondeado al contrato
         totalFunded += msg.value;
     }
     //Esta funcion nos sirve para que lla persona pueda ver cuanto se necesita para alcanzar la meta, asi no tendra que estar adivinando cuanto depositar maximo
     function viewRemaining() public view returns(uint256){
         uint256 remainingFunds = Goal - totalFunded;
         return remainingFunds;
     }
     
 }

Data Location

  • Storage: Queda guardada dentro de la blockchain, siempre vamos a poder obtener el valor almacenado, pues este nunca se va borrar. Memoria Persistente.

  • Memory (Modificable): Solo existe mientras se llama una función y no podemos acceder de nuevo a el dato.

  • Call data (inmodificable): Solo existe mientras se llama la función

  • Por defecto las variables de estado se almacenan en el storage y los parámetros en memory.

Les dejo una cheatsheet que encontré, trae datos útiles.

Estuve un par de dias haciendo el desafio #1 pero aqui esta el resultado!!

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract CrowdFunding {
    string projectName;
    string projectDescription;
    uint256 goal;
    bool isActive;
    uint currentFunds;
    address payable ownerWallet;
    address owner;
    
    constructor(string memory _projectName, string memory _projectDescription, uint256 _goal) {
        projectName = _projectName;
        projectDescription = _projectDescription;
        goal = _goal;
        currentFunds = 0;
        isActive = true;
        
        // Owner Information
        ownerWallet = payable(msg.sender);
        owner = msg.sender;
    }

    function sendFunds() public payable {
        require(isActive == true, "Current project is not available!");
        ownerWallet.transfer(msg.value);
        currentFunds += msg.value;
    }

    function changeFundStatus() public {
        require(owner == msg.sender, "You must be the project owner!");
        isActive = !isActive;        
    }

    
    function getGoal() public view returns(uint) {
        return goal;
    }
    
    function getStatus() public view returns(bool) {
        return isActive;
    }
    
    function getFunds() public view returns (uint) {
        return currentFunds;
    }
}

No se pero me parece que esta mal…

Minuto 0:30, seria, este no se Deberia borrar nunca, Nunca es mucho tiempo.

  • Data location
    • Dentro de Solidity las variables pueden tener un lugar distinto de almacenamiento, dependiendo para qué los utilicemos y donde los utilicemos
    • Storage
      • Memoria Persistente
      • Variable guardada en el Storage de un contrato
        • Storage se guarda en la Blockchain
        • Siempre se va a mantener el valor almacenado pues este nunca se va a borrar
    • Memoria
      • no persistente
      • Una variable almacenada en memoria es no persistente
      • Memory (Modificable) solo existe mientras se llama la función
      • Esta variable también se puede modificar mientras estemos dentro de la función
    • CallData
      • También es no persistente
      • Se almacena solo mientras se está usando
      • No puede ser modificada mientras se usa
      • Esto hace que se reduzca el GAS necesario para ejecutar una función
  • Por defecto las variables de estado se almacenan en el storage
  • Los parámetros de una función se almacenan en memoria
  • Los únicos tipos de variables a los que se les puede definir un almacenamiento distinto son las variables de tipo String y las variables de tipo Array y Mapping

Este es mi resultado del reto, fue muy divertido lograr este resultado y finalmente verlo (aunque sea solo un juguete 😄 ), use un poco de ayuda de los aportes anteriores.

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract PlatziCrowdFunding {
    //Initial variables
    string ProjectName;
    string ProjectDescription;
    address Owner;
    address payable ownerWallet;
    bool Isfondeable;
    uint256 Goal;
    uint256 RequiredFunds;
    uint256 totalFunded;

    constructor(string memory _projectName, string memory _projectDescription){
        Owner = msg.sender;
        ownerWallet = payable(msg.sender);

        ProjectName = _projectName;
        ProjectDescription = _projectDescription;

        Isfondeable = true;
        Goal = 0;
        totalFunded = 0;
    }

    modifier OnlyOwner {
        require(msg.sender == Owner, "You are not the owner of this project");
        _;
    }

    function setProjectGoal(uint256 _goal) public OnlyOwner {
        Goal = _goal;
    }

    function ChangeProjectState(bool change) public OnlyOwner {
        Isfondeable = change;
    }

    function ViewGoal() public view returns(uint256) {
        return Goal;
    }

    function ViewTotalFounds() public view returns(uint256) {
        return totalFunded;
    }

    function ViewRemaining() public view returns(uint256) {
        uint256 remaining = Goal - totalFunded;
        return remaining;
    }

    function FoundProject() public payable {
        require(msg.sender != Owner, "The Owner can't found its own project");

        //IF the project is still alive
        require(Isfondeable, "The project is not longer available");

        //If the goal is not reach yet
        require(totalFunded < Goal, "The Goal is already reach");

        //Check valid amount
        require(msg.value != uint(0), "Please add a amount to contribute to the project");

        //Check not exceed the goal
        require(totalFunded + msg.value <= Goal, "unable to add more funds, check amount remaining for our goal");

        ownerWallet.transfer(msg.value);
        totalFunded += msg.value;
    }
}
Hola a todos soy muy nuevo en esto pero quiero hacerles mi aporte es como lo entendi y lo que aprendi lo hice muy sencillo, gracias: // SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0; contract Project {     address public owner; // Guardará la dirección del dueño del contrato    uint public fondos;    // Guardará la cantidad de fondos    bool public activo;    // Indica si el proyecto está activo     // Constructor: se ejecuta una sola vez cuando se despliega el contrato    constructor() {        owner = msg.sender;  // 'msg.sender' es quien despliega el contrato (el dueño)        activo = true;     // El proyecto comienza activo por defecto    }     // Funcion que permite enviar ether a un proyecto    function fundProject() public payable {        require(activo, "El proyecto no esta activo.");  // Verifica si el proyecto está activo        fondos+=msg.value;  // `msg.value` es la cantidad de ether que se envía    }    // Funcion que nos va a permitir cambiar el estado del proyecto    function changeProjectState() public{        require(msg.sender == owner, "Solo el dueno puede cambiar el estado.");        activo = !activo;  // Cambia el estado: si está activo lo desactiva, y viceversa     }}```js // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; contract Project { address public owner; // Guardará la dirección del dueño del contrato uint public fondos; // Guardará la cantidad de fondos bool public activo; // Indica si el proyecto está activo // Constructor: se ejecuta una sola vez cuando se despliega el contrato constructor() { owner = msg.sender; // 'msg.sender' es quien despliega el contrato (el dueño) activo = true; // El proyecto comienza activo por defecto } // Funcion que permite enviar ether a un proyecto function fundProject() public payable { require(activo, "El proyecto no esta activo."); // Verifica si el proyecto está activo fondos+=msg.value; // `msg.value` es la cantidad de ether que se envía } // Funcion que nos va a permitir cambiar el estado del proyecto function changeProjectState() public{ require(msg.sender == owner, "Solo el dueno puede cambiar el estado."); activo = !activo; // Cambia el estado: si está activo lo desactiva, y viceversa } } ```
Siguiendo mi ejemplo de sensor de temperatura, supongamos que el sensor forma parte de un proyecto agrícola de alta tecnología donde se quiere monitorear la temperatura de un campo en tiempo real. Este proyecto agrícola busca financiamiento, y la comunidad puede enviar fondos (ether) para apoyarlo. **fundProject**: Los interesados pueden financiar el proyecto enviando ether. Esto podría ser usado para mantener el sensor, para realizar investigaciones relacionadas con los datos recopilados, o para expandir el proyecto y agregar más sensores. **changeProjectStatus**: A medida que el proyecto avanza, el propietario puede cambiar el estado del proyecto para informar a la comunidad sobre su progreso. **Funciones de visibilidad**: `public`: Pueden ser llamadas desde fuera y dentro del contrato. Por ejemplo, `geoposition` es una variable pública, por lo que se genera automáticamente una función getter que permite a cualquier persona ver la geoposición. `external`: Solo pueden ser llamadas desde fuera del contrato. Es más eficiente que `public` para funciones que siempre serán llamadas desde fuera. Ejemplo: `updateTemperature`. `internal`: Solo pueden ser llamadas desde el mismo contrato o contratos derivados. Son útiles para funciones de utilidad que no deben ser expuestas. Ejemplo: `internalFunction`. `private`: Solo pueden ser llamadas desde el mismo contrato. Son útiles para funciones y variables que no deben ser accesibles de ninguna otra manera. Ejemplo: `privateFunction` Este contrato ahora no solo registra y actualiza la temperatura, sino que también permite el financiamiento del proyecto y la actualización del estado del mismo. En un contexto real, esto podría representar un sistema de crowdfunding para proyectos agrícolas que desean utilizar sensores IOT para mejorar sus operaciones. // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.7 <0.9.0; contract TemperatureSensor { // Datos del sensor string public geoposition; string public macAddress; int public temperature; address public owner; address public wallet; uint public funds; enum ProjectStatus { NotStarted, InProgress, Completed } ProjectStatus public status; modifier onlyOwner() { require(msg.sender == owner, "Only the owner can perform this action"); \_; } constructor( string memory \_geoposition, string memory \_macAddress, int \_initialTemperature, address \_wallet ) { geoposition = \_geoposition; macAddress = \_macAddress; temperature = \_initialTemperature; owner = msg.sender; wallet = \_wallet; funds = 0; status = ProjectStatus.NotStarted; } function updateTemperature(int \_newTemperature) external onlyOwner { temperature = \_newTemperature; } function fundProject() external payable { funds += msg.value; } function changeProjectStatus(ProjectStatus \_newStatus) external onlyOwner { status = \_newStatus; } // Función con visibilidad internal function internalFunction() internal view returns(uint) { return funds \* 2; } // Función con visibilidad private function privateFunction() private view returns(uint) { return funds / 2; } // Estas funciones son solo para demostrar la visibilidad. No tienen un propósito real en este contrato. }

Dentro de Solidity las variables se pueden almacenar en diferentes lugares.

Una variable en el Storage de la blockchain nunca se borrará, es memoria persistente.
Una variable en la memoria se borra, solo sirve en funciones.
Una variable almacenada en el calldata, es lo mismo que la variable en memoria, PERO el parametro NO se cambia, útil para usar variables que sepas que no se van a modificar. Recuerda que todo aquí usa GAS como en Attack on Titan.

Les comparto mi solución

// SPDX-License-Identifier: GPL-3.0
 pragma solidity >=0.7.0 <0.9.0;

 contract Project {
     bool completed;
     uint256 goal;
     uint256 totalFunded;
     address payable owner;
     string statusLog;
    

     constructor(uint256 _goal, address payable _owner) public payable{
        goal = _goal;
        completed = false;
        totalFunded = 0;
        owner = _owner;
        statusLog = "Open for donations";

     }

     function getGoal() public view returns(uint256) {
         return goal;
     }

     function fundProject() public payable {
         if (!completed) {
            owner.transfer(msg.value);
            totalFunded += msg.value;
            changeProjectState();
         } else {
             statusLog = "This projects has been fully fundeed";
         }
     }

     function changeProjectState() public {
         if (goal >= totalFunded) {
            completed = true;
            statusLog = "This projects has been fully founded";
         } 
         statusLog = "Thanks for support our project";
     }
 }

Cosas que se pueden mejorar

  • ver quienes hacen el fund y si no se cumple meta, devolver el dinero
  • ver cuanto falta para completar
  • agregar tiempo limite

Tipos de almacenamientos

  • Persistentes -> STORAGE las variables guardadas en la blockchain, siempre podran ser accedidas.
    -No Persistentes -> Memory (modificables) solo pueden ser usadas para realizar calculos y llamar una funcion. Luego de que se usen, jamas volveran a ser accedidas.
    Calldata (no modificables) se almacena solo mientras se esta usando
// SPDX-License-Identifier: MIT

pragma solidity >=0.7.0 <0.9.0;

contract CrowdFunding {
    string projectName;
    bool isActive;
    address mainOwnerAddress;
    uint256 public balance;

    constructor(string memory _projectName, bool _isActive) {
        projectName = _projectName;
        isActive = _isActive;
        mainOwnerAddress = payable(msg.sender);
    }

    function sendEther(address payable receiver) public payable {
        require(receiver != mainOwnerAddress, "Que raro mandarte dinero a ti mismo");
        require(isActive, "El proyecto ya no esta activo, lo hubieses hecho antes BRO.");
        receiver.transfer(msg.value);
        balance += msg.value;
    }

    function getBalance() public view returns (uint256) {
        return balance;
    }

    function getProjectName() public view returns (string memory) {
        return projectName;
    }

    function changeProjectState (bool _newState) public {
        isActive = _newState;
    }

    function changeProjectName (string memory _newProjectName) public {
        require(bytes(_newProjectName).length >= 3, 'El nombre del proyecto es demasiado corto');
        projectName = _newProjectName;
    }
}

/*
Variable almacenadas en el store del contrato

Es una variable guardad en la memoria de la blockchain, siempre se a poder obtener el valor almancenado -> memoria persistente

variable almacenada en memoria es una variable no persistente solo dispoinble miestras se usando dentro de la funciion

variable almacneada en el call data , es una variable no persistente y no puede ser modificada mientras se usa

variables de estado se alamcenan en el storage
parametros de una funcion se almacena en memoria
*/

Simple pero funciona

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;
contract reto1{
    string public nameProject;
    bool public isFoundable;


     constructor(
         string memory _nameProject,
         bool _isFoundable
     ){
         nameProject = _nameProject;
         isFoundable=_isFoundable;
     }
     function fundProject(address payable direction)public payable {
        direction.transfer(msg.value);
    }
    function changeProjectState(uint256 state) public{
        if (state==1){
            isFoundable=true;
        } else{
            isFoundable=false;
        }
    }
}

RESUMEN CLASE 11:
MEMORY STORAGE Y
CALL DATA

I.- Storage “Memoria persistente”

Se guarda en la blockchain.

II.- Memory (modificable) “Memoria no-persistente”

Solo existe mientras se llama una función.

III.- Calldata (inmodificable) “Memoria no-persistente”

Solo existe mientras se llama una función.

IV.- Donde se almacenan

  • Variables de Estado: En el Storage

  • Parametros: En memoria

RETO:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract CrowdFunding {
    string public id;
    string public name;
    string public description;
    address payable public author;
    string public state = "Opened";
    uint256 public funds;
    uint256 public fundraisingGoal;

    constructor(
        string memory _id,
        string memory _name,
        string memory _description,
        uint256 _fundraisingGoal
    ) {
        id = _id;
        name = _name;
        description = _description;
        fundraisingGoal = _fundraisingGoal;
        author = payable(msg.sender);
    }

    function fundProject() public payable {
        author.transfer(msg.value);
        funds += msg.value;
    }

    function changeProjectState(string calldata newState) public {
        state = newState;
    }
}

Mi solución

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity >=0.7.0 <0.9.0;

contract FundNewProject {
    address owner;
    address payable private ownerWallet;
    uint goal;
    uint total;
    string name;
    bool isOpen;

    constructor (uint _goal, string memory _name){
        owner = msg.sender;
        ownerWallet = payable(msg.sender);
        name = _name;
        goal = _goal;
        total = 0;
        isOpen = true;
    }

    modifier onlyOwner {
        require(msg.sender == owner, "You are not the owner of this project");
        _;
    }

    function viewTotal() public view returns(uint){
        return total;
    }

    function reachToGoal() public view returns(uint){
        return goal - total;
    }

    function changeProjectState(bool change) public onlyOwner{
        isOpen = change;
    }
    
    function foundProject() public payable {
        require(msg.sender != owner, "The Owner can't found its own project");

        //IF the project is still alive
        require(isOpen, "The project is not longer available");

        //If the goal is not reach yet
        require(total < goal, "The Goal is already reach");

        //Check valid amount
        require(msg.value != uint(0), "Please add a amount to contribute to the project");

        //Check not exceed the goal
        require(total + msg.value <= goal, "Unable to add more funds, check amount remaining for our goal");

        ownerWallet.transfer(msg.value);
        total += msg.value;
    }
}

Acá está el mío por si les sirve:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract Crowdfunding {

    address payable projectAddress;
    string projectName;
    uint256 fundraisingGoal;
    uint256 moneyReceived;
    bool isOpen;

    constructor (address payable _projectAddress, uint256 _fundraisingGoal){
        projectAddress = _projectAddress;
        projectName = "Crowdfunding";
        fundraisingGoal = _fundraisingGoal;
        moneyReceived = 0;
        isOpen = true;
    }

    function fundProject (uint256 _amountToAdd) public payable{
        require(isOpen, "Crodwfunding is closed");
        require (moneyReceived + msg.value <= fundraisingGoal, "Fundarising is almost full. Fund with less money.");
        projectAddress.transfer(msg.value);
        moneyReceived = moneyReceived + msg.value;
    }

    function changeProjectState() public{
        isOpen = !isOpen;
    }

}

Reto 1

Pude completar el reto. Para el desarrollo usé Truffle y escribí un par de pruebas. Este es el resultado.

Smart Contract que permite una contribución a un artista desde un 1 Ether:

// SPDX-License-Identifier: GPL-3.0
 pragma solidity >=0.7.0 <0.9.0;

contract crowfundingPlatzi{

    //Iniciamos variables
    uint public objetivo = 10 ether;
    uint public balance;
    uint public totalRecaudado;
    bool public estaDisponible;

    address private owner;
    address payable public artista;

    //Iniciamos modificador de acceso
    modifier isOwner(){
        require(owner == msg.sender);
        _;
    }

    //Iniciamos funciones
    function fundProject() public isOwner payable {
        
        require(msg.value > 1 ether); //aportacion minima 1 eth
        
        balance += msg.value;
        
        if(balance >= objetivo){
            payOut();
        }
        
    }
    
    function payOut() private {

        totalRecaudado = balance;
        balance = 0;

        artista.transfer(totalRecaudado);
    }

    function changeProjectState(bool change)public {
        estaDisponible = change;
    }        
}

Sólo quería compartir oficialmente mi primer smart contract!!! Tuve que compilar como 20 veces pero así está. Nothing fancy pero mínimo hace lo que pidió el profe 🤪

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Project {
    string private name;
    address payable private owner;
    bool private isFundable;

    constructor(string memory _name) {
        isFundable = true;
        owner = payable(msg.sender);
        name = _name;
    }

    function getStatus() public view returns (string memory) {
        if (isFundable) {
            return string(abi.encodePacked(name, " is Fundable"));
        } else {
            return string(abi.encodePacked(name, " is not Fundable"));
        }
    }

    function fundProject() public payable {
        require(isFundable, "Project is not fundable");
        owner.transfer(msg.value);
    }

    function changeProjectState(bool _isFundable) public {
        require(msg.sender == owner, "Only the project owner can change the project state");
        isFundable = _isFundable;
    }
}

Esta es mi solucion:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Reto1 {
    address projectWallet = 0x0...;
    uint256 minimunFounds = 100;
    uint256 currentFounds = 0;
    string currentState = "In progress...";

    function fundProject() public payable returns (string memory){
        address payable wallet = payable(projectWallet);
        wallet.transfer(msg.value);
        currentFounds += msg.value;
        changeProjectState();
        return currentState;
    }

    function changeProjectState() private {
        if (currentFounds >= minimunFounds){
            currentState = "Succesfully!";
        }
    }
}

Aporto aqui el resultado del Reto

// SPDX-License-Identifier: GPL-3.0

pragma solidity >= 0.7.0 < 0.9.0;

contract CursoReto1 {

    string projectName;
    bool isOpen = true;
    uint256 amount;

    constructor(string  memory _projectName) {
        projectName = _projectName;
        amount = 0;
    }

    function  getProjectName() public view returns (string memory){
        return projectName;
    }

    function changeStatus(bool state) public returns(bool){
        isOpen = state;
        return isOpen;
    }

    function addFounds(address payable receiver) public payable returns (string memory){
        if(!isOpen){
            return "The project is close";
        } else {
            receiver.transfer(msg.value);
            amount = amount + msg.value;
            return "Amount added";
        }

    }

    function getProjectAmout() public view returns(uint256){
        return amount;
    }



}

Serviría para entender de forma muy básica, no tiene una verificación de quién esta autorizado a cambiar el state del proyecto

// SPDX-License-Identifier: MIT

pragma solidity >=0.7.0 <0.9.0;

contract Crowdfunding {
    uint public idNumber;
    bool public funded = false;
    address payable public wallet;
    string public projectName;

    constructor(address payable _wallet) {
        wallet = _wallet;
        projectName = "My Startup";
    }

    function fundProject() public payable {
        wallet.transfer(msg.value);
    }

    function changeProjectState(bool _isFunded) public {
        funded = _isFunded;
    }
}

también se encuentra en este gist: https://gist.github.com/carloscarvallo/324135b842127ec66775dd5a4484c79c

Esta es mi solución al reto #1

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract Reto_1_Platzi{
    string public projectName;
    string public projectOwner;
    string public projectState = "Open";
    address payable ownerWallet;
    uint public goal;
    uint public currentFund;
    bool isOpenToFund;

    constructor(string memory _projectName, string memory _projectOwner, address payable _ownerWallet, uint _goal){
    projectName = _projectName;
    projectOwner = _projectOwner;
    ownerWallet = _ownerWallet;
    goal = _goal;
    isOpenToFund = true;
    }

    function fundProject() public payable{
        if(isOpenToFund == true){
        ownerWallet.transfer(msg.value);
        currentFund += msg.value;
        }
    }

    function changeProjectState(string calldata newState) public{
        if(msg.sender == ownerWallet){
            isOpenToFund = !isOpenToFund;
            if(isOpenToFund == true){
                projectState = newState;
            }
            else{
                projectState = newState;
            }
        }
    }
}

Espero estar haciendolo bien…

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract CrowFunding {
    string public id;
    string public name;
    string public description;
    bool public isFundable;
    uint256 public fundGoal
    address public wallet;

    constructor(string public _id, string public _name, string public _description, uint256 _fundGoal){
        id = _id;
        name = _name;
        description = _description;
        fundGoal = _fundGoal;
        author = payable(msg.sender);
    }

    function fundProject() public payable {
        author.transfer(msg.value);
        funds += msg.value;
    }

    function changeProjectState(string calldata newState) public {
        state = newState;
    }

}

Aca esta mi reto

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Founding {
    //DEFINIMOS LAS VARIABLES DEL PROYECTO
    address payable public wal = payable(msg.sender);
    string public projectName;
    string public description;
    uint256 public balanceNeeded;
    bool public foundingCompleted;
    uint256 public founded;
    
    //CREAMOS EL CONSTRUCTOR PARA QUE EL USUARIO PUEDA PUBLICAR EL PROYECTO
    constructor(string memory _projectName, string memory _description, uint _balanceNeeded) {
        projectName = _projectName;
        description = _description;
        balanceNeeded = _balanceNeeded;
        foundingCompleted = false;
        
    }
    
    //CREAMOS LA FUNCION QUE ACTUALIZA EL ESTADO DEL PROYECTO
    function changeProjectState() private {
        foundingCompleted = true;
    }
    
    // ESTA FUNCION PERMITE FONDEAR EL PROYECTO SIEMPRE Y CUANDO NO SE HAYA COMPLETADO YA EL FOUNDING. ADEMAS CAMBIA AUTOMATICAMENTE EL ESTADO DEL PROYECTO SI ES QUE LLEGA A ALCANZAR EL FOUNDING NECESARIO
    function foundProject() public payable {
        require(foundingCompleted == false, "This project already achieved its goal!");
        wal.transfer(msg.value);
        founded += msg.value;
        if(founded >= balanceNeeded) {
            changeProjectState();
        }
    }
    
}

RETO 1#

//SPDX-License-Identifier: GPL-3.0 
pragma solidity >0.7.0 <0.9.0;

contract uniqueproject {
    struct Project{
        bool isFunded;
        uint totalFunded;
        uint goal;
        
    }
    
    constructor(string memory _id, string memory _name, bool _isFunded, uint256 _totalFunded, uint256 _goal){
        isFunded = _isFunded;
        totalFunded = _totalFunded;
        goal = _goal
        id  = _id
        name = _name
        author = payable(msg.sender)
        mount = payable(msg.value);
    }
    
    
    function fundProject() public payable {
        author.transfer(msg.value);
        totalFunded += msg.value
    }
    
    
    function changeProjectState() public returns (string memory){
        return isFunded = false;
    }
    
}

Reto #1

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.0;

contract CrowdFunding {
    string projectName;
    uint targetAmount;
    uint amountFunded;
    bool isFundable;
    address payable ownerAddress;
    
    constructor(string memory _projectName, uint _targetAmount, address payable _ownerAddress){
        projectName = _projectName;
        targetAmount = _targetAmount;
        ownerAddress = _ownerAddress;
        amountFunded = 0;
        isFundable = true;
    }
    
    function fundProject() public payable {
        require(isFundable == true, "This project is not available for funding!");
        ownerAddress.transfer(msg.value);
        amountFunded += msg.value;
    }
    
    function changeProjectState() public {
        require(ownerAddress == msg.sender, "You must be the project owner!");
        isFundable = false;
    }
    
    function getGoal() public view returns(uint){
        return targetAmount;
    }
    
    function getFunds() public view returns(uint){
        return amountFunded;
    }
    
    function getStatus() public view returns(string memory){
        return isFundable ? 'Active': 'Inactive';
    }
}

Solución reto 1

// SPDX-License-Identifier: MIT

pragma solidity ^0.5.0;

contract Project {
    
    string public name;
    bool public isActive;
    address payable public owner;
    
    constructor(string memory _name) public {
        name = _name;
        isActive = true;
        owner = msg.sender;
    }
    
    function fundProject() public payable {
        require(isActive, "This project is not active.");
        owner.transfer(msg.value);
    }
    
    function changeProjectState() public {
        require(owner == msg.sender, "You are not the project owner");
        isActive = !isActive;
    }
}
pragma solidity ^0.7.0;


contract KickstarterPoor {
        
    string name;
    string description;
    string state = "opened";
    uint256 goal;
    uint256 funds;
    
    address payable creator;
    
    
    constructor(string memory _name, string memory _description, uint256 _goal) payable{
        
        name = _name;
        description = _description;
        creator = payable(msg.sender);
        goal = _goal;
        
    }
    
    function FundProyect() public payable{
         creator.transfer(msg.value);
        funds += msg.value;
    }
    
    function changeProjectState(string calldata newState) public {
        
        state = newState;
    }
    
    function checkStatus () public view returns (string  memory){
        
    return state;
    }
    
    function getFunds() public view returns (uint256){
        return funds;
    }
    
}
// SPDX-License-Identifier: GPL-3.0

pragma solidity >= 0.7.0 <0.9.0;

contract projectFundPlatzi{
    string public name;
    bool public isFundable;
    uint public marketCap;
    
    constructor(
        string memory _name
        ){
            name = _name;
            isFundable = true;
            marketCap = 0;
        }
    
    function fundProject(address payable reciever) public payable{
        if (isFundable == true){
            reciever.transfer(msg.value);
            marketCap = marketCap + msg.value;
        }
    }
    
    function changeProjectState() public {
        if (isFundable == true){
            isFundable = false;
        } else if (isFundable == false){
            isFundable = true;
        }
    }
    
    function getMarketCap() public view returns (uint){
        return marketCap;
    }
}

Memory- modificable solo existe mientras se llama una función
Storage- se guarda en la blockchain
Calldata- inmodificable solo existe mientras se llama una función

Reto #1

//SPDX-License-Identifier: MIT 
pragma solidity ^0.8.0;

contract Project {
    
    address projectId; //Project addresss for send fund
    string public projectName;
    string public descriptionProject;
    bool public projectState;
    address owner;
    
    constructor () {
        projectState = true; //initalizer state project 
        descriptionProject = "Everithing in one click";
        projectName = "Xevar";
        owner = msg.sender;// The owner is who deploy the contract
    }
    
    function fundProject(address payable receiver) public payable {
        require(projectState == true, "This project is closed!");
        receiver.transfer(msg.value);
    }
    
    function changeProjectState(bool state) public  returns(bool){
        require(msg.sender == owner, "This function only change for the owner");//Only the owner can change this state
        projectState = state;
        return projectState;
    }
    
} 

Por si a alguien le sirve el mío. Me parece que funciona batante bien:

//La idea es crear un contrato para un crowfunding

contract crowfunding{
    uint progress;              //progress es el monto que el proyecto haya recibido hasta el momento
    address owner;              //Servirá para establecer premisos. Solo el creador puede modificar ciertas variables
    address payable public receiver= payable(0x617F2E2fD72FD9D5503197092aC168c91465E7f2); //la dirección de la wallet que recibirá los fondos
    bool stop;                  //Switch para detener y continuar el contrato
    uint Goal;                  //Cantidad de dinero solicitada

    constructor(){          //El constructor se ejecuta una sola vez: Al desplegar el contrato
        progress=0;         //El conteo de dinero empieza en 0
        owner=msg.sender;   //La dirección de la wallet que despliegue el contrato será declarada como "owner", utilizaremos esta dirección para establecer permisos de creador
        Goal=100;           //La cantidad de dinero que buscamos
    }

        //Función para revisar la cantidad faltante:
    function FondosRestantes() public view returns(string memory,uint,string memory,uint,string memory,uint){
        uint remainingFunds = Goal - progress;
        return ("Restante:",remainingFunds,"Progreso",progress,"Meta:",Goal);
    }

        //Función para aportar dinero al proyecto
    function FondearProyecto() public payable returns(string memory message){ 
        require (progress != Goal,"La meta se alcanzo previamente");             //No se debe haber alcanzado la meta previamente
        require (stop != true,"no se estan recibiendo fondos en el momento");    //No se debe haber activado la función DetenerFondeo
        require (progress + msg.value <= Goal,"la cantidad excede el fondeo");   //No se aceptan fondos que excedan la meta
        receiver.transfer(msg.value);           //Esta es la transacción como tal                    
        progress = progress + msg.value;        //Añadimos la transacción al conteo de fondos
        if(progress==Goal){     //si la transacción alcanza la meta
            message="Has completado la meta";
        } else{
            message="Gracias por contribuir";
        }
    }

        //Función para detener el proyecto
    function DetenerFondeo() public returns (string memory state){
        require (owner == msg.sender,"solo el administrador puede detener el fondeo");  //Solo quien desplego el contrato puede activar esta función
        stop=true;
        state = "no se estan recibiendo fondos";
    }

        //Función para desactivar la función DetenerProyecto
    function ContinuarFondeo() public returns (string memory state){
        require (owner == msg.sender,"solo el administrador puede detener el fondeo");  //Solo quien desplego el contrato puede activar esta función
        stop=false;
        state = "se recibiran fondos hasta alcanzar la meta";
    }

        //Función para modificar la meta que se estableció al desplegar el contrato
    function NuevaMeta(uint newgoal) public returns (string memory,uint){
        require (owner == msg.sender,"solo el administrador puede realizar cambios");   //Solo quien desplego el contrato puede activar esta función
        Goal=newgoal;
        return ("la nueva meta es:", Goal);
    }

        //Función para volver a empezar de cero el conteo de dinero
    function ReiniciarMeta() public returns(string memory){
        require (owner == msg.sender,"solo el administrador puede reiniciar el fondeo");    //Solo quien desplego el contrato puede activar esta función
        progress=0;
        return "el fondeo se ha reiniciado";
    }
}