No tienes acceso a esta clase

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

Qué son los enum types

16/21
Recursos

Un enum type o tipo enumerado es un grupo de datos especiales a los que se les puede asignar una variable que corresponda a un conjunto de constantes predefinidas. Son implementados en muchos lenguajes de programación fuertemente tipados y Solidity los utiliza para la creación de tipos personalizados de datos y definir los valores que estos puedan tener.

Los enumerados emplean una lista de los valores que una variable puede tomar haciendo uso de un texto para visualizar el nombre a cada valor, pero guardándose un número entero por detrás. Podemos tener una máquina de estados cuyos valores sean 0, 1 y 2. Para que sea más intuitivo y fácilmente legible el significado de cada número, podemos asignarle un “pendiente” al 0, “en proceso” al 1 y “finalizado” al 2.

De esta forma, no necesitamos recortar que “finalizado” se representa por un 2, solo con utilizar el texto de cada valor del enumerado, el compilador de Solidity lo hará por nosotros. En programación, cuando necesitamos clasificar y limitar los posibles valores de una variable, podemos utilizar listas y crear nuestros propios tipos de datos con todos los valores que una variable puede tener gracias a la enumeración.

Cómo implementar enumerados en Solidity

La implementación de Solidity es muy sencilla, basta con utilizar la palabra reservada enum seguido del nombre del enumerado y sus posibles valores.

enum State { Pendiente, EnProceso, Finalizado };

La posición de cada valor del enumerado determina el índice que le corresponde siendo Pendiente = 0, EnProceso = 1 y Finalizado = 2.Ahora puedes declarar variables de este nuevo tipo de dato personalizado.

State status;

Dentro de esta variable guardas el enumerado y puedes utilizarlo como condicionante para determinar el flujo de tu programa o asignarle nuevos valores a través del propio enumerado.

status = State.Finalizado;    // 2

if (status == State.Finalizado) {
    // ...
}

El simple uso del enumerado State nos ayuda a no tener que recordar el valor de cada elemento del enumerado utilizando el “Finalizado” y volviendo el código fuente mucho más legible y mantenible.

Aprovecha esta característica del lenguaje para escribir mejor código el día de mañana y que otro desarrollador o desarrolladora de software pueda entender rápidamente. Las buenas prácticas de programación hacen a la calidad del código y este tipo de característica te permitirá ser más claro con el propósito de un programa.


Contribución creada por: Kevin Fiorentino (Platzi Contributor).

Aportes 22

Preguntas 6

Ordenar por:

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

Enum types

Las enumeraciones son la forma de crear tipos de datos definidos por el usuario, generalmente se usa para proporcionar nombres para constantes integrales, lo que hace que el contrato sea mejor para el mantenimiento y la lectura. Las enumeraciones restringen la variable con uno de los pocos valores predefinidos, estos valores de la lista enumerada se denominan enumeraciones. Las opciones de se representan con valores enteros comenzando desde cero, también se puede dar un valor predeterminado para la enumeración. Mediante el uso de enumeraciones es posible reducir los errores en el código.

enum <enumerator_name> { 
            element 1, elemenent 2,....,element n
} 

Más información aquí

no se por que, pero el modulo 16 no me funciona en la pc…pero si en el celular.

Este es mi avance con los estados como Enum del reto #6:

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

contract Proyecto_Platzi{
    enum State {Open, Closed}

    struct projectInfo{
        string name;
        string description;
        string owner;
        address payable ownerWallet;
        State state;
        uint goal;
        uint currentFund;
    }

    projectInfo public CrowFundingProject;


    constructor(string memory _name, string memory _owner, string memory _description, uint _goal, State _state){
        CrowFundingProject = projectInfo(_name, _description, _owner, payable(msg.sender), _state, _goal, 0);
    }

    modifier onlyOwner() {
        require(
            msg.sender == CrowFundingProject.ownerWallet,
            "Only owner can change the project state"
        );
        //la función es insertada en donde aparece este simbolo
        _;
    }


    modifier differentToTheOwner() {
        require(
            msg.sender != CrowFundingProject.ownerWallet,
            "The owner can't fund the project"
        );
        //la función es insertada en donde aparece este simbolo
        _;
    }

    event ChangeState(
        State previousState,
        State newState
    );

    event FundValueGiven(
        uint fundGiven,
        uint valueToGoal,
        string greetingMessage
    );

    function fundProject() public payable differentToTheOwner{
        require(CrowFundingProject.state != State.Closed, "Sorry, this project is closed and cannot receive funds");
        require(msg.value > 0, "Sorry, fund value must be greater than 0, try again");
        CrowFundingProject.ownerWallet.transfer(msg.value);
        CrowFundingProject.currentFund += msg.value;
        emit FundValueGiven(msg.value, (CrowFundingProject.goal - msg.value), "Thanks for your contribution");
    }

    function changeProjectState(State newState) public onlyOwner{
        require(CrowFundingProject.state != newState, "Sorry, to change the state you must put a different state from the current one");
        emit ChangeState(CrowFundingProject.state, newState);
        CrowFundingProject.state = newState;
    }
}

Mi avance 😃

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

contract crowfundingContract {

    
    enum Status { Opened, Closed }
    struct ProjectData {
        string id;
        string name;
        string description;
        string status;
        address payable author;
        uint fundingGoal;
        uint funds;
        Status statusID;
    }
    ProjectData public project;

    event fundedBy (
        string project,
        address participant,
        uint vulue
    );
    event changedBy (
        string project,
        address author,
        string newStatus
    );

    constructor(string memory _id, string memory _projectName, string memory _description, uint _fundingGoal){
        project = ProjectData(_id,_projectName,_description,"Opened",payable(msg.sender),_fundingGoal,0,Status.Opened);
    }
    
    function fundProject() public payable fundRestriction {
        require(project.statusID == Status.Opened, "Project is closed! you cannot fund");
        require(msg.value > 0, "You cannot fund 0 wei!");
        project.author.transfer(msg.value);
        project.funds += msg.value;
        emit fundedBy(project.id, msg.sender, msg.value);
    }

    function changeProjectStatus(Status newStatus) public changeStatusRestriction {
        require(newStatus != project.statusID, "Status already selected!");
        if(newStatus == Status.Opened){
            project.status = "Opened";
        }else{
            project.status = "Closed";
        }
        project.statusID = newStatus;
        emit changedBy(project.id, msg.sender, project.status);
    }

    modifier changeStatusRestriction(){
        require(
            msg.sender == project.author,
            "Only the owner can change the status"
        );
        _;
    }

    modifier fundRestriction(){
        require(
            msg.sender != project.author,
            "You as the author cannot fund this project"
        );
        _;
    }
}

Cumpliendo el reto:

// SPDX-License-Identifier: SEE LICENSE IN LICENSE

pragma solidity >= 0.7.0;

contract crowdfunding {
    enum State {Opened, Closed}
    struct Project {
        string id;
        string name;
        string description;
        address payable author; //who create o represent the project
        State state; 
        uint funds; // to acumulate project funds
        uint fundraisingGoal; // the goal of the funding
    }


    Project public project;
    constructor(string memory _id, string memory _name, string memory _description, uint  _fundraisingGoal) {
        project = Project(
            _id,
            _name,
            _description,
            payable(msg.sender),
            State.Opened,
            0,
            _fundraisingGoal
        );
    }

    modifier notFundFronAuthor {
        require(
            msg.sender != project.author,
             "Author don't funding his ouw project"
        );
        _;
    }

    event SendFunding(
        address funder,
        uint fund
    );

    event RaisingFundGoal(
        string idProject,
        uint fundRaising,
        string mensaje
    );

    function fundProject() public payable notFundFronAuthor{
        require(msg.value > 0,"Fund value must be greater then 0");
        //require(project.state != 1,"The project can not receive funds, it's closed");
        project.author.transfer(msg.value);
        project.funds += msg.value;
        emit SendFunding(msg.sender, msg.value);
        if (project.funds >= project.fundraisingGoal) {
            emit RaisingFundGoal(
                project.id, 
                project.funds,
                "fundRaisingGoal reached");
        }
    }

    modifier onlyAuthorOrRaisingGoal {
        require(
            msg.sender == project.author || project.funds >= project.fundraisingGoal,
            "Only author can change state or if the fundraidingGoal is raising"
        );
        _; // identifica desde donde se inserta la función, define cuando se continua la función
    }

    event ChangeState(
        string idProject,
        State newState
    );

    function changeProjectState(State newState) public onlyAuthorOrRaisingGoal {
        //require(
        //    newState == 1 || newState == 0,
        //    "Invalid new state. It'll be 0 to Opened and 1 to Closed"
        //);
        project.state = newState;
        emit ChangeState(project.id, newState);
    }
}
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Project {

    struct FundProjectData {
        string id;
        string name;
        string description;
        address payable author;
        string state;
        uint funds;
        uint fundraisingGoal;

    }

    FundProjectData public fundData;

    constructor(string memory _id, string memory _name, string memory _description, uint fundraisingGoal ) {
        fundData = FundProjectData(_id, _name, _description, payable(msg.sender), "open", 0, fundraisingGoal);
    }

    modifier difOwner() {
        require(
            fundData.author != msg.sender,
            "Owner can't fund the project"
        );
        // La función es insertada en donde aparece este símbolo
        _;
    }

    modifier onlyOwnerState() {
        require(
            fundData.author == msg.sender,
            "Only owner can change the project name"
        );
        // La función es insertada en donde aparece este símbolo
        _;
    }

    error projectClosed(string message, string _state);
    event addFunds(string message, address donator, uint amount );

    function fundProject(address payable _donator) public payable difOwner  {
        require(
            msg.value > 0,
            "Debe ingresar un monto mayor a 0" 
        );
    
        if(keccak256(abi.encodePacked(fundData.state)) == keccak256(abi.encodePacked("closed"))) {
            string memory msgError = "El proyecto esta cerrado";
            revert projectClosed(msgError, fundData.state);
        }else {
            _donator.transfer(msg.value);
            uint amount = msg.value;
            emit addFunds("Gracias por su aporte", _donator, amount);
            fundData.funds += amount;
        }   
    }

    event changeState(string message, string oldState, string newState);

    function changeProjectState(string memory _newState) public onlyOwnerState {
        string memory oldState = fundData.state;
        fundData.state = _newState;

        emit changeState("El autor ha cambiado el estado", oldState, fundData.state);
    }

}

Ahí me ven como tonto escribiento Active sin terminar de ver el video ajjajaa

Enum Types

  • Conjunto de valores finitos, que son creados por el propio usuario.
  • Son Explicitamente convertibles desde todos los tipos de entero. No permite conversion implicita.
  • Las conversiones explicitas revisan los valores de rango en tiempo de ejecucion y algun fallo causa una excepcion.
  • Los enums necesitan al menos un miembro

Codigo con el reto #6!

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Crowfounding {
enum State { Open, Close }

struct Project {
    string id;
    string name;
    string description;
    address payable owner;
    bool receive_funds;
    State state;
    uint funds;
    uint fundraisingGoal;
}

Project public project;

constructor(string memory _name, string memory _description, uint _fundraisingGoal) {
    project = Project(
        "1", _name, _description, payable(msg.sender), true, State.Close, 0, _fundraisingGoal
    );
}

modifier notOwnerPay() {
    require (
        msg.sender != project.owner,
        "The author can't funder the project"
    );
    _;
}

modifier onlyOwnerChangeState() {
    require (
        msg.sender == project.owner,
        "Only owner can change the state of project"
    );
    _;
}

modifier onlyOwnerChangeName() {
    require (
        msg.sender == project.owner,
        "Only owner can change the project name"
    );
    _;
}

event FundProject(
    string name,
    string description,
    address owner,
    bool receive_funds,
    State state,
    uint value
);

event ChangeProjectState(
    string name,
    bool receive_funds,
    State newState
);

function fundProject() public payable notOwnerPay {
    require(project.state != State.Open, "The project can not receive funds");
    require(msg.value > 0, "Fund value must be greater than 0");
    if(project.receive_funds) {
        project.owner.transfer(msg.value);
        project.funds += msg.value;
    }
    emit FundProject(project.name, project.description, project.owner, project.receive_funds, project.state, msg.value);
}

function changeFundProject() public payable {
    if (project.funds > project.fundraisingGoal) {
        project.receive_funds = false;
    }
}

function changeProjectState(State newState) public onlyOwnerChangeState {
    require(project.state != newState, "New state must be different");
    project.state = newState;
    emit ChangeProjectState(project.name, project.receive_funds, newState);
}

function receiveFunds() public view returns (bool) {
    return project.receive_funds;
}


function changeProjectName(string memory _name) public onlyOwnerChangeName {
    project.name = _name;
}

}

Hola 😄 les comparto mi solución para el Reto #6

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

contract Crowfunding {

    enum State {Open, Closed} 

    struct Project{
        string id;
        string name;
        string description;
        address payable author;
        State state;
        uint funds;
        uint fundraisingGoal;
    }

    Project public project;

    event FundProject(string id, uint value);

    event ChangeProjectState(State newState);

    constructor(string memory _id, string memory _name, string memory _description, uint _fundraisingGoal) {
        project=Project(_id, _name, _description, payable(msg.sender), State.Open, 0, _fundraisingGoal);
    }

    modifier onlyOwner() {
        require(msg.sender == project.author, "No eres el owner");
        _;
    }

    modifier projectFunders() {
        require(msg.sender != project.author , "No puedes colaborar a tu propio proyecto");
        _;
    }

    error StateError(State state, string message);

    error ValueOrStateNotValid(uint unit, State state);

    //Todos pueden colaborar excepto el owner 
    function fundProject() public payable projectFunders {
        if(msg.value!=0 && project.state==State.Open){
            project.author.transfer(msg.value);
            project.funds += msg.value;
            emit FundProject(project.id, msg.value);
        }
        else{
            revert ValueOrStateNotValid(msg.value, project.state);
        }
    }
    
    //Solo el dueño puede cambiar el estado
    function changeProjectState(State newState) public onlyOwner {
        if(newState!=project.state){
            project.state=newState;
        }
        else{
            revert StateError(newState, "You cannot rewrite the same state");
        }
    }

}

Tambien es util crearlos fuera del contrato e importarlos en los contratos donde es sea necesario
Aca una referencia https://solidity-by-example.org/enum/

Ain’t much but its honest work:

RESUMEN CLASE 16:
ENUM TYPES

  • Tipos personalizados que definen estados.

  • Cada estado representa un entero.

enum Directions {Left, Right, Up, Down}

Directions choice;

  • choice = Directions.Left //0

  • choice = Directions.Right //1

  • choice = Directions.Up //2

  • choice = Directions.Down //3

RETO 6:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract CrowdFunding {
    enum FundraisingState {
        Opened,
        Closed
    }

    struct Project {
        string id;
        string name;
        string description;
        address payable author;
        FundraisingState state;
        uint256 funds;
        uint256 fundraisingGoal;
    }

    Project public project;

    event ProjectFunded(string projectId, uint256 value);

    event ProjectStateChanged(string id, FundraisingState state);

    constructor(
        string memory _id,
        string memory _name,
        string memory _description,
        uint256 _fundraisingGoal
    ) {
        project = Project(
            _id,
            _name,
            _description,
            payable(msg.sender),
            FundraisingState.Opened,
            0,
            _fundraisingGoal
        );
    }

    modifier isAuthor() {
        require(
            project.author == msg.sender,
            "You need to be the project author"
        );
        _;
    }

    modifier isNotAuthor() {
        require(
            project.author != msg.sender,
            "As author you can not fund your own project"
        );
        _;
    }

    function fundProject() public payable isNotAuthor {
        require(
            project.state != FundraisingState.Closed,
            "The project can not receive funds"
        );
        require(msg.value > 0, "Fund value must be greater than 0");
        project.author.transfer(msg.value);
        project.funds += msg.value;
        emit ProjectFunded(project.id, msg.value);
    }

    function changeProjectState(FundraisingState newState) public isAuthor {
        require(project.state != newState, "New state must be different");
        project.state = newState;
        emit ProjectStateChanged(project.id, newState);
    }
}

Los Enum Types son tipos personalizados que nos permiten restringir los valores que puede tener una variable
Ejemplo: directions: Adelante, atrás, derecha, izquierda

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract CreateProject {
    struct Project {
        string name;
        address owner;
        address payable ownerWallet;
        uint totalFounded;
        State state;
    }

    Project public project;

    constructor(string memory _name, State _state) {
       project = Project(
        _name,
        msg.sender,
        payable(msg.sender),
        0,
        _state
        );
    }

    enum State {
        Active,
        Paused,
        Closed
    }

    modifier onlyOwner() {
        require(msg.sender == project.owner,
        "You aren't the owner of the project.");
        _;
    }

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

    event FundProject(
        uint amount,
        address founder,
        string projectName
    );

    event ChangeState(
        State state
    );

    function fundProject() public payable notOwner {
        require(project.state == State.Active, "The project isn't active.");
        require(msg.value > 0, "You should donate more than 0 ETH.");
        project.ownerWallet.transfer(msg.value);
        project.totalFounded += msg.value;
        emit FundProject(msg.value, msg.sender, project.name);
    }

    function changeState(State _newState) public onlyOwner {
        require(project.state != _newState, "You should add a new state.");
        project.state = _newState;
        emit ChangeState(project.state);
    }

    function changeName(string calldata _newName) public onlyOwner {
        project.name = _newName;
    }
}

Enum

RETO 6 - ENUM

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

contract projectFundPlatzi{
    struct Datos {  
        string  name;
        bool  isFundable;
        uint  deposits;
        uint  depositsGoal;
        uint  depositTest;
        address  autor;
        string  tokenLog;
        string  tokenFeedback;
        Estado estados;
    }

    Datos public dato;

    enum Estado { 
            Abierto, Cerrado
    } 

    Estado public state = Estado.Abierto;

    constructor(
        string memory _name, Estado _state, uint _depositsGoal
        ){
            dato.name = _name;
            dato.isFundable = true;
            dato.deposits = 0;
            dato.depositsGoal=_depositsGoal;
            dato.autor = msg.sender; 
            dato.tokenLog = "Log: project status changed";
            dato.tokenFeedback = "Feedback: Gracias";
            dato.estados = _state;


    }
    error stateNotDefined (Estado newState);

    event newFundFeedback(
        address autor,
        uint256 deposit,
        string Feedback
    );
    event newFundLog(
        uint256 depositsGoal,
        uint256 deposits,
        string Log
    );
    modifier notOnlyOwnerPay{
        require (dato.autor != msg.sender, "El propietario no puede abonar fondos al proyecto" );
        //la funcion es insertada donde aparece este simbolo _
        _;
    }
    modifier ownerRequired {
        require (msg.sender == dato.autor, "Esta accion es restringida al propietario.");
        _;
    }
    function viewDeposits() public view returns (uint){
        return dato.deposits;
    }

    function viewRemaining() public view returns(uint256){
        return dato.depositsGoal - dato.deposits;
    }

    function fundProject(address payable benefactor) public payable notOnlyOwnerPay {    

        require (msg.value > 0, "No se acepta abonos sin valor.");

        dato.depositTest = dato.deposits + msg.value;
       
        if (dato.isFundable == true && dato.depositTest <= dato.depositsGoal) {
            benefactor.transfer(msg.value);
            dato.deposits +=  msg.value;
            emit newFundFeedback (dato.autor, msg.value,dato.tokenFeedback);
        }
    }

    function changeProjectState(Estado _newState) public ownerRequired{

        require (_newState != dato.estados, "El nombre de estado es igual al actual y no es actualizable");

        if (_newState == Estado.Abierto){
            dato.isFundable = true;
        }else if (_newState == Estado.Cerrado){
            dato.isFundable = false;
        } else {
            revert stateNotDefined (_newState);
        }          
       dato.isFundable = !dato.isFundable;

       emit newFundLog (dato.depositsGoal, dato.deposits, dato.tokenLog);
    }
}

como el tipo de dato en bases de datos

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract CrowdFunding {
     enum State {Active,Inactive}

    struct Project {
        string id;
        string name;
        string description;
        address payable author;
        State state;
        uint256 funds;
        uint256 fundraisingGoal;
    }

    Project public project;

    event ProjectFunded(string projectId, uint256 value);

    event ProjectStateChanged(string id, State state);

    constructor(
        string memory _id,
        string memory _name,
        string memory _description,
        uint256 _fundraisingGoal
    ) {
        project = Project(
            _id,
            _name,
            _description,
            payable(msg.sender),
            State.Inactive,
            0,
            _fundraisingGoal
        );
    }

    modifier isAuthor() {
        require(
            project.author == msg.sender,
            "You need to be the project author"
        );
        _;
    }

    modifier isNotAuthor() {
        require(
            project.author != msg.sender,
            "As author you can not fund your own project"
        );
        _;
    }

    function fundProject() public payable isNotAuthor {
        require(project.state != State.Inactive, "The project can not receive funds");
        require(msg.value > 0, "Fund value must be greater than 0");
        project.author.transfer(msg.value);
        project.funds += msg.value;
        emit ProjectFunded(project.id, msg.value);
    }

    function changeProjectState(State newState) public isAuthor {
        require(project.state != newState, "New state must be different");
        project.state = newState;
        emit ProjectStateChanged(project.id, newState);
    }
}

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

pragma solidity >=0.7.0 <0.9.0;

contract CrowdFound {
    struct Project {
        string name;
        string description;
        address payable founder;
        uint funds;
        uint goal;
        string state;
    }
    Project public project;

    event financedProject (address contributor, uint amount);
    event modifiedProject (address modifiers, string status);

    constructor(string memory _name, string memory _description, uint _goal){
        project = Project(_name, _description, payable(msg.sender), 0, _goal, "Opened");
    }

    modifier excluyeFounder(){
        require(project.founder != msg.sender , "The founder cannot invest here");
        _;
    }

    modifier onlyFounder(){
        require(project.founder == msg.sender , "Only Founder can modifier state Project");
        _;
    }

    function fundProject() public payable excluyeFounder{
        project.founder.transfer(msg.value);
        project.funds = project.funds + msg.value;
        emit financedProject (msg.sender, msg.value);
    }

    function changeProjectState(string calldata newState ) public onlyFounder{
        project.state = newState;
        emit modifiedProject(msg.sender, project.state);
    }
}> 

Mi aporte modificando los estados por enums, reto #6

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

contract CrowdFunding {
    
    enum Status { Active, Inactive }

    struct Project {
        string name;
        string description;
        uint fundraisingGoal;
        address payable wallet;
        address owner;
        uint funds;
        Status status;
    }

    // Project Struct
    Project public project;

    // Funds starts in zero.
    uint private initialFunds = 0;
    
    
    constructor(string memory _name, string memory _description, uint _fundraisingGoal) {
        project = Project(
            _name,
            _description,
            _fundraisingGoal,
            payable(msg.sender),
            msg.sender,
            initialFunds,
            Status.Active
        );
    }

    function fundProject() public payable ownerNotSendFunds {
        require(project.status == Status.Active, "This project state is Closed!");
        require(msg.value > 0, "Funds can not be Zero!");

        project.wallet.transfer(msg.value);
        project.funds += msg.value;
        emit NewFundNotification(msg.sender, msg.value);
    }

    function changeProjectStatus(Status newStatus) public onlyOwnerModifyStates {
        require(project.status != newStatus, "Project has that state already, choose another!");
        project.status = newStatus;
        emit NewStatusChange(newStatus);
    }

    event NewFundNotification(
        address sender,
        uint fundAmount
    );
    
    event NewStatusChange(
        Status newStatus
    );


    modifier ownerNotSendFunds() {
        require(project.owner != msg.sender, "Owners shouldnt send funds to its own projects!");
        _;
    }

    modifier onlyOwnerModifyStates() {
         require(project.owner == msg.sender, "You must be the project owner!");
         _;
    }

}

Reto Clase anterior

pragma solidity ^0.7.0;


contract KickstarterPoor {
        
    
    address private owner;
    
    address payable creatorPayable;
    
    struct Project {
        string id;
        string name;
        string description;
        uint256 goal;
        uint256 funds;
        bool opened;
    }
    
    Project creator;
    constructor(string memory _id,string memory _name, string memory _description, uint256 _goal) payable{
        
        creator = Project(_id,_name,_description,_goal,0, true);
      
        owner = msg.sender;
        creatorPayable = payable(owner);
        
    }
   
    
    event newFunds(
        address sender,
        uint256 funds
        );
        
    event projectState(
        uint256 goal,
        uint256 funds,
        string state
        );
    
    
    function checkStatus () public view returns (bool){
        
    return creator.opened;
    }
    
    function getFunds() public view returns (uint256){
        return creator.funds;
    }
        
    
    
    modifier noFundOwner (){
          require(msg.sender != owner, "You can't donate to yourself, I'll call the police.");
        _;
    }
    
   modifier onlyOwner (){
        require(msg.sender == owner, "You are not admin, go away");
        _;
    }
    
     function FundProJect() public payable noFundOwner{
         require(creator.opened, "The project is already closed");
         require(msg.value > 0 , "Funds > 0");
     
              creatorPayable.transfer(msg.value);
        creator.funds += msg.value;
        emit newFunds(msg.sender,msg.value);
        
       
    }
    
    
    function changeProjectState(bool  newState) public  onlyOwner{
        require(creator.opened != newState, "The same status cannot be reapplied");
        
        creator.opened = newState;
        
        emit projectState(creator.goal,creator.funds,creator.opened ? "Opened" : "Closed");
    }
    
    
}```