No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Reg铆strate

Comienza en:

0D
17H
22M
20S

Modificadores de funciones

12/21
Recursos

Solidity implementa un tipo de funci贸n especial denominada Modificadores que nos permiten ejecutar una pieza de c贸digo antes o despu茅s del comportamiento de la propia funci贸n.

Comportamiento de una funci贸n

Los usos m谩s frecuentes de los modificadores suelen ser la validaci贸n de datos o la restricci贸n de acceso a una funci贸n si el usuario no tiene permisos. Dichas validaciones puedesn realizarse con modificadores que adem谩s permiten ser reutilizadas.

Estos nos permiten hacer validaciones antes de ejecutar las funciones. De esta forma, podemos evitar comportamientos inesperados o que alguien sin autorizaci贸n ejecute la funci贸n.

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

contract FunctionModifier {

    address public owner;

    constructor() {
        // Guardamos la informaci贸n del due帽o del contrato para validar al mismo
        owner = msg.sender;
    }

    // Modificador para validar que la llamada la realiza el due帽o del contrato
    modifier onlyOwner() {
        require(msg.sender == owner, "No eres el owner");
        _;
    }

    // Solo el due帽o del proyecto puede cambiar al mismo
    function changeOwner(address _newOwner) public onlyOwner {
        owner = _newOwner;
    }
}

La sintaxis de un modificador es sencilla, utilizando la palabra reservada modifier, declaramos la funci贸n y dentro del mismo utilizamos un require para realizar una validaci贸n y un _ para indicarle al compilador de Solidity que contin煤e ejecutando el resto de la funci贸n si la condici贸n se cumpli贸 correctamente.

En el caso de que la condici贸n no se cumpla y el modificador rechace la transacci贸n, el require realizar谩 un revert para volver atr谩s todos los cambios de estado del contrato por nosotros y que no tengamos que preocuparnos. Las operaciones en Solidity son at贸micas, lo que quiere decir que se ejecuta correctamente cada una de las instrucciones o no se ejecuta ninguna.

Finalmente, una funci贸n puede implementar el modificador en la declaraci贸n de la misma. A lo igual que indicamos que una funci贸n es public o pure, tambi茅n le implementamos el nombre del modificador que utilizar谩.

 function changeOwner(address _newOwner) public onlyOwner { }

La l贸gica dentro del modificador puede ser del nivel de complejidad que necesitemos, usando condicionales u otros flujos de control. Con esta caracter铆stica de Solidity, ya est谩s listo o lista para desarrollar contratos con permisos y validaciones de datos para que el flujo del mismo sea el esperado.


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

Aportes 52

Preguntas 14

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Yo estaba haciendo cosas extra帽as con el if para evitar eso que alguien mas cambiara el nombre, debi terminar la clase primero XD

Modificadores de funciones

  • Nos permiten hacer validaciones antes de ejecutar nuestra funci贸n, de esta forma podemos evitar comportamientos inesperados o que la funci贸n sea ejecutada por alguien que no tiene permisos de hacerlo.

El c贸digo est谩 genial, pero si creo que deber铆an ponerle comentarios, no s茅 qu茅 tan bueno sea esto para los Smart Contracts.

Me parece que los modifiers son azucar sintactica que implementa el patron decorador, un poco parecido a los decoradores en Python
Mas info: https://medium.com/coinmonks/solidity-tutorial-all-about-modifiers-a86cf81c14cb

Ahora con modifier 鈥 muy chevere como fluye todo

// SPDX-License-Identifier: GPL-3.0

// enmarca las versiones del compilador que soporta el smart contract
pragma solidity >=0.7.0 <0.9.0;

// nombre del contrato 
contract FondosProyecto {
    
    
    // variables de estado del contrato
    // se etablecen a publicas para que se puedan ver 
    int public idProyecto;
    string public nameProyecto;
    uint256 public objetivoFondos;
    bool private recibeFondos;
    // esta variable es address payable por que maneja la cartera que vamos a recibir los fondos
    address payable public autor;
    // variable para almacenar el proietario de la wallet
    address private owner;
    
    uint256 public fondos;
    // constructor que permite registrar la informacion del proyecto y su objetivo 
    constructor (int _idProyecto, string memory _nameProyecto, uint256 _objetivoFondos){
        idProyecto = _idProyecto;
        nameProyecto=_nameProyecto;
        objetivoFondos = _objetivoFondos;
        autor = payable(msg.sender); // se inicializa con la cartera actual
        recibeFondos = true; // es verdareo cuando inicia a re驴cibir fondos
        //se inicializa la cartera del propuetario
        owner = msg.sender;
    }
    
    // esta funcion permite realizar la transaccion de una carte a la cartera propia 
    // no sin antes verificar si no se ha legado al tope del objetivo de los fondos
    function fundProyect () public payable {
        // si aun recibe fondos 
        if (recibeFondos){
            autor.transfer (msg.value);
            fondos += msg.value;    
        }
        // verifica si cumplio con el objetivo para no recibir mas fondos
        changeFundProyect(); // cambia el estado de la variable a falso
    }
    
    // modifier no permite abonar fondos por el propietario del proyecto 
    modifier notOnlyOwnerPay (){
        require (autor != owner, "El propietario no puede abonar fondos al proyecto" );
        //la funcion es insertada donde aparece este simbolo _
        _;
    }
    
    
    // cambia el estado de la variable si los fondos recibidos son superiores a los objetivo
    function changeFundProyect () public payable notOnlyOwnerPay {
        if (fondos > objetivoFondos) {
            recibeFondos = false;
        }
    }
    
    // funcion que retorna el estado de la variable si recibe fondos
    function getRecibeFondos () public view returns (bool){
        return recibeFondos;
    }
    
    // restringe a que solo el propietario de la Wallet permita cambiar un estado
    modifier onlyOwner (){
        require (msg.sender == owner, "Solo el propietario pude realizar estos cambios" );
        //la funcion es insertada donde aparece este simbolo _
        _;
    }
    
    
    // aplicamos la funcion modiifer para restringir el cambio del la ariable recibe-fondos 
    function changeRecibeFondos () public onlyOwner {
        if (recibeFondos) {
            recibeFondos = false;
        } else {
            recibeFondos = true;
        }
        
        
    }

}

Hola, para comentarles que yo puse el mensaje del modifier en espa帽ol y el compilador no me acept贸 la 帽, uno creer铆a que al ser un string no hay problema pero no, da error de 鈥渋nvalid character鈥.

Espero que a alguien le sirva.

Estaba medio loco en la anterior clase, pero ya voy avanzando y entendiendo 鈥 me esta gustandoo 鈥!

aqui mi version

// SPDX-License-Identifier: GPL-3.0

// enmarca las versiones del compilador que soporta el smart contract
pragma solidity >=0.7.0 <0.9.0;

// nombre del contrato 
contract FondosProyecto {
    // variables de estado del contrato
    // se etablecen a publicas para que se puedan ver 
    int public idProyecto;
    string public nameProyecto;
    uint256 public objetivoFondos;
    bool private recibeFondos;
    // esta variable es address payable por que maneja la cartera que vamos a recibir los fondos
    address payable public autor;
    uint256 public fondos;
    // constructor que permite registrar la informacion del proyecto y su objetivo 
    constructor (int _idProyecto, string memory _nameProyecto, uint256 _objetivoFondos){
        idProyecto = _idProyecto;
        nameProyecto=_nameProyecto;
        objetivoFondos = _objetivoFondos;
        autor = payable(msg.sender); // se inicializa con la cartera actual
        recibeFondos = true; // es verdareo cuando inicia a re驴cibir fondos
    }
    
    // esta funcion permite realizar la transaccion de una carte a la cartera propia 
    // no sin antes verificar si no se ha legado al tope del objetivo de los fondos
    function fundProyect () public payable {
        // si aun recibe fondos 
        if (recibeFondos){
            autor.transfer (msg.value);
            fondos += msg.value;    
        }
        // verifica si cumplio con el objetivo para no recibir mas fondos
        changeFundProyect(); // cambia el estado de la variable a falso
    }
    
    // cambia el estado de la variable si los fondos recibidos son superiores a los objetivo
    function changeFundProyect () public payable {
        if (fondos > objetivoFondos) {
            recibeFondos = false;
        }
    }
    
    // funcion que retorna el estado de la variable si recibe fondos
    function getRecibeFondos () public view returns (bool){
        return recibeFondos;
    }

}

Este es el verdadero curso de Introducci贸n a Solidity, no dir茅 mas

Me ha costado un poco entener todo y tuve que corregir errores pero lo logr茅 y me alegr贸 el d铆a jajajaja. Aqu铆 les dejo el c贸digo:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

/**
 * @title Storage
 * @dev Store & retrieve value in a variable
 */
contract platziProject {
    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);
        }

    modifier onlyOwner(){
        require(
            msg.sender == author,
            "Only owner can change the project state"
        );

        _;
    }

    modifier exceptOwner(){
        require(
            msg.sender != author,
            "Owner can't send funds"
        );

        _;
    }

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

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

Convalidacion del due帽o(owner)

  • El constructor s贸lo se ejecuta 1 vez , y es al momento de crearlo por eso al colocar (owner=msg.sender) , solo se guarda nuestra direcci贸n de wallet como 鈥渙wner鈥 que es nuestra direccion , el modifiere convalidara que la direccion de otras wallets(msg.sender) no se igual a la original 鈥渙wner鈥.
    Asi evita que pueda ser cambiada.

Llamar la funcion modifiere onlyOwner para evitar modificaciones externas.

Soluci贸n reto 2

Notar que se puede agregar mas de un modifier por funci贸n:

function fundProject() public payable notOwner onlyWhenActive {
	owner.transfer(msg.value);
        founds += msg.value;
}
// SPDX-License-Identifier: MIT

pragma solidity ^0.5.0;

contract Project {
    
    string public name;
    bool public isActive;
    address payable public owner;
    uint public founds;
    uint public goal;
    
    constructor(string memory _name, uint _goal) public {
        name = _name;
        goal = _goal;
        isActive = true;
        owner = msg.sender;
    }
    
    modifier onlyOwner() {
        require(owner == msg.sender, "You are not the project owner");
        _;
    }
    
    modifier notOwner() {
        require(owner != msg.sender, "You cannot transfer to your own project");
        _;
    }
    
    modifier onlyWhenActive() {
        require(isActive, "This project is not active.");
        _;
    }
    
    function fundProject() public payable notOwner onlyWhenActive {
        owner.transfer(msg.value);
        founds += msg.value;
    }
    
    function changeProjectState() public onlyOwner {
        isActive = !isActive;
    }
}

Modificadores de funciones
-Es utilizado para modificar el comportamiento de tu contrato inteligente.
Uso:
-Nos permite reducir la redundancia del c贸digo; si estamos verificando la misma condici贸n, podemos reutilizarlo siempre y cuando estemos realizando la misma condici贸n.
Cuando lo debo usar?

  • Se usa antes de ejecutar una funci贸n de manera autom谩tica. Si la funcion NO CUMPLE con el requisito del modificador, lanzamos una excepcion y la ejecucion de la FUNCION se detiene.

NOTA: Para entender varios aspectos de los cuales se han hablado aqui, es importante tener conocimiento en POO.
(https://platzi.com/cursos/oop/)

// SPDX-License-Identifier: MIT

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";
    uint public funds;
    uint public fundraisingGoal;

    constructor(string memory _id, string memory _name, string memory _description, uint _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;
    }

    modifier onlyAuthor() {
        require(
            msg.sender == author,
            "Only author can change the project name"
        );
        //la funci贸n es insertada en donde aparece este simbolo
        _;
    }

    function changeCrowdFundingName(string memory _crowdFundingName) public onlyAuthor {
        name = _crowdFundingName;
    }
}

Me va gustando como va todo!

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Crowdfunding {

    string public project_name;
    bool public status;
    uint256 public goal;
    uint256 public funded;
    address payable public owner;

    constructor(string memory _project_name, bool _status, uint256 _goal) payable {
        project_name = _project_name;
        status = _status;
        goal = _goal;
        funded = 0;
        owner = payable(msg.sender);
    }

     modifier owner_permission() {
        require(
            owner == msg.sender, 
            "Actualizar el proyeto solo es para el propietario."
        );
        // La funcion a modificar sera insertada en este simbolo, funciona como un decorador.
        _;  
    }

    modifier owner_fund() {
        require(owner != msg.sender, "El propietario no puede agregar dinero a su proyecto.");
        _;
    }

    function fundProject() public payable owner_fund {
        require(status, "No se aceptan mas entradas de dinero.");
        require(funded != goal, "Ya se llego a la meta, no se necesita mas dinero.");
        require(msg.value != uint(0), "Agregue dinero al proyecto.");
        require(funded+msg.value <= goal, "No se puede agregar mas dinero que la meta.");
        funded = funded + msg.value;
        owner.transfer(msg.value);
    }

    function chageProjectState(bool _status) public owner_permission {
        status = _status;
    }
}

Si antes han trabajado con frameworks que hacen uso de decoradores, los modificadores analogicamente funcionan parecido. Le dan un comportamiento adicional a las funciones donde se invocan.

Reto #2

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

contract Permission {

    address private owner;
    string public projectName="Platzi";
    string public state="Open";
    address payable public author;
    uint256 public funds;

    constructor() {
        // Guardamos la informaci贸n del due帽o del contrato para validar al mismo
        owner = msg.sender;
        author = payable(msg.sender);
    }

    // Modificador para validar que la llamada la realiza el due帽o del contrato
    modifier onlyOwner() {
        require(msg.sender == owner, "No eres el owner");
        _;// indicarle al compilador de Solidity que contin煤e ejecutando el resto de la funci贸n si la condici贸n se cumpli贸 correctamente
    }

    // Modificador para validar que la llamada la realizan otros excepto el owner
    modifier projectFunders() {
        require(msg.sender != owner , "No puedes colaborar a tu propio proyecto");
        _;
    }

    //Todos pueden colaborar excepto el owner 
    function fundProject() public payable projectFunders {
        author.transfer(msg.value);
        funds += msg.value;
    }
    
    //Solo el due帽o puede cambiar el estado
    function changeProjectState(string calldata newState) public onlyOwner {
        state = newState;
    }

}
// 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;
    address payable public author;
    string public state = 'Opened';
    uint public funds;
    uint public fundraisingGoal;

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

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

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

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

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

Mi aporte del reto 馃槂

  modifier onlyOwner() {
    require(
      msg.sender == author,
      'Only owner can do this operation!'
    );
    _;
  }

  modifier differentOwner() {
    require(
      msg.sender != author,
      'You can do this as owner'
    );
    _;
  }
// SPDX-License-Identifier: GPL - 3.0 

pragma solidity >=0.7.0 < 0.9.0; 

contract Crowfunding {
    // Variables de estado
    string idProject;
    string public nameProject; 
    string public descriptionProject; 
    string public stateProject  = "Open"; 
    address payable public walletProject; 
    uint public limiteFund; 
    uint public collectFund; 

    constructor(string memory _idProject, string memory _nameProject, string memory _descriptionProject, uint  _limiteFund  ){
        idProject = _idProject;
        nameProject = _nameProject;
        descriptionProject = _descriptionProject;
        limiteFund = _limiteFund;
        walletProject = payable(msg.sender);
    }

    function fundProject() public payable {
        walletProject.transfer(msg.value);   
        collectFund += msg.value;
    }

    function changeProjectState(string memory newState) public  {
        stateProject = newState;
    }

}

Aqu铆 mi respuesta,

// 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 owner;
    string public state = 'Opened';
    uint public funds;
    uint public fundraisingGoal;

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

    modifier onlyNotOwner(){
        require(
            msg.sender != owner,
            "The owner can't fund is own project"
        );
        _;
    }

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


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

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

}

RETO #2

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract reto_dos{
   address payable public owner;
   string public state = 'Opened';

   constructor(){
        owner = payable(msg.sender);
   }
//mofifier que indica que solo el owner puede modificar el estado.
   modifier changeState(){
       require(owner == msg.sender, "solo el owner puede modificar el estado");
       _;
   }
  
   function stateFinally(string memory _state) public changeState{
       state = _state;
   }
//modifier que evita que el owner deposite en su propio proyecto.
   modifier onlyCommunity(){
       require(msg.sender != owner,"Los owners no pueden aportar a su propio proyecto");
       _;
   }
   function community() public onlyCommunity payable{
        owner.transfer(msg.value);
   }
}
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;
contract reto1{
    string public nameProject;
    string public projectState="open";
    address private owner;


     constructor(
         string memory _nameProject
     ){
         nameProject = _nameProject;
         owner=msg.sender;
     }
     modifier notOwnerfund(){
         require(
             msg.sender!=owner,"No puede depositar el owner"
         );
         _;
     }
     function fundProject(address payable direction)public payable notOwnerfund{
        direction.transfer(msg.value);
    }
    modifier onlyOwnerState(){
        require(
            msg.sender==owner,"No eres el owner"
        );
        _;
    }
    function changeProjectState(string memory _projectState) public onlyOwnerState{
        projectState=_projectState;
    }
}

RESUMEN CLASE 12:
MODIFICADORES
DE FUNCIONES

I.- FUNCTION MODIFIERS

  • Validan informaci贸n al usar una funci贸n.

  • suelen llevar un require.

RETO 2:

// 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;

    event ProjectFunded(string projectId, uint256 value);

    event ProjectStateChanged(string id, string state);

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

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

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

    function fundProject() public payable isNotAuthor {
        author.transfer(msg.value);
        funds += msg.value;
        emit ProjectFunded(id, msg.value);
    }

    function changeProjectState(string calldata newState) public isAuthor {
        state = newState;
        emit ProjectStateChanged(id, newState);
    }
}

As铆 va quedando!

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract CreateProject {
    string public name;
    bool public isActive;
    address public owner;
    address payable ownerWallet;
    uint public totalFounded;

    constructor(string memory _name, bool _isActive){
        name = _name;
        isActive = _isActive;
        owner = msg.sender;
        ownerWallet = payable(msg.sender);
        totalFounded = 0;
    }

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

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

    modifier onlyActive(){
        require(isActive, "The project isn't active.");
        _;
    }

    function fundProject() public payable notOwner onlyActive{
        ownerWallet.transfer(msg.value);
        totalFounded += msg.value;
    }

    function changeState(bool _newState) public onlyOwner{
        isActive = _newState;
    }

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

Agregados los modificadores. Antes hab铆a agregado los require dentro de las funciones.

// 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;
    }

    modifier onlyOwner(){
        require(msg.sender == projectAddress, "Only owner can do this action");
        _;
    }

    modifier notOwnProject(){
        require(msg.sender != projectAddress, "Owner cannot fund his own project");
        _;
    }

    function fundProject () public notOwnProject 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 onlyOwner{
        isOpen = !isOpen;
    }

}

Modifiers

Parte 1

// Modifier to only the owner can change the state of the project
    modifier onlyOwner {
        require(msg.sender == author, "Only the owner can change the state of the project");
        _;
    }
    // Function to change the state of the project
    function changeState(string calldata newState) public onlyOwner{
        state = newState;
    }

Parte 2

// Modifier to evit that an author can apport to their own project
    modifier notAuthor {
        require(msg.sender != author, "You can't fund your own project");
        _;
    }    

    // Function to evit that an author can apport to their own project
    function fund(uint _amount) public payable notAuthor {
        funds += _amount;
    }

Con lo que llevamos visto hasta ahora y sin adelantar comparto mi soluci贸n, espero a alguien le pueda ayudar

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract crowdfunder {
    uint public goal;
    bool state;
    uint public funds;
    address owner;

    constructor(uint _goal, bool _state, uint _funds){
        goal = _goal;
        funds = _funds;
        state = _state;
        owner = msg.sender;
    }
    modifier onlyOwner{
        require(msg.sender == owner, "you need to be the owner to set the goal or change the state"); _;
    }
    modifier differentThenOwner{
        require(msg.sender != owner, "You cant fund your own proyect"); _;
    }
    function setGoal(uint Goal) public onlyOwner {
        goal = Goal;
    }
    function fundProyect(address payable receiver) public payable differentThenOwner returns(string memory message, uint total){
        if(funds < goal && state){
            funds += msg.value;
            total = funds;
            receiver.transfer(msg.value);
            message = "your founds have been received";
        }
        else {
            message = "we cant process your transaction";
            total = funds;
        }
    }
    function changeProjectState() public onlyOwner returns (bool status){
        state = !state;
        status = state;
    }
}

RESPUESTA

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

contract projectFundPlatzi{
    string public name;
    bool public isFundable;
    uint public deposits;
    uint public depositsGoal;
    uint private depositTest;
    address private autor;
  
    constructor(
        string memory _name
        ){
            name = _name;
            isFundable = true;
            deposits = 0;
            depositsGoal=1000;
            autor = msg.sender; 
    }
      
    function viewDeposits() public view returns (uint){
        return deposits;
    }

    function viewRemaining() public view returns(uint256){
         return depositsGoal - deposits;
     }
    
    modifier notOnlyOwnerPay{
        require (autor != msg.sender, "El propietario no puede abonar fondos al proyecto" );
        //la funcion es insertada donde aparece este simbolo _
        _;
    }
    
    function fundProject(address payable benefactor) public payable notOnlyOwnerPay {     

        depositTest = deposits + msg.value;
       
        if (isFundable == true && msg.value>0 && depositTest <= depositsGoal) {
            benefactor.transfer(msg.value);
            deposits +=  msg.value;
        }
        else{
        changeProjectState();
        }
    }

    modifier ownerRequired {
        require (msg.sender == autor, "Esta accion es restringida al propietario.");
        _;
    }
    function changeProjectState() public ownerRequired {
       isFundable = !isFundable;
    }
}
> 

RETO 2

dejo mi ejemplo al reto 2

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract CrowdFunding {
// variables (q uso en el contructor)
string public id;
string public name;
string public description;
address payable public author;

//variables ....q no uso en el costructor
string public state = "Opened";
uint256 public funds;
uint256 public fundraisingGoal;

// constructor (solo se ejecutal al momento del despliegue)
constructor(
    string memory _id,
    string memory _name,
    string memory _description,
    uint256 _fundraisingGoal
) {
    id = _id;
    name = _name;
    description = _description;
    fundraisingGoal = _fundraisingGoal;
    author = payable(msg.sender);
}

// controlo q solo el due帽o pueda cambiar el estado
modifier onlyOwner() {
    require(msg.sender == author, "Only owner can change the project state.");
    //la funci贸n es insertada en donde aparece este s铆mbolo
    _;
}

// controlo q el due帽o no pueda aportar
modifier notOwner() {
    require(msg.sender != author, "Owner cannot add to the proyect.");
    //la funci贸n es insertada en donde aparece este s铆mbolo
    _;
}

// funcion para aportar
function fundProject() public payable notOwner {
    author.transfer(msg.value);
    funds += msg.value;
}


// funcion para cambiar el estado del proyecto
function changeProjectState(string calldata newState) public onlyOwner {
    state = newState;
}

}

Los function modifiers permiten hacer validaciones antes de ejecutar una funci贸n, as铆 podemos evitar comportamientos inesperados o que la funci贸n se ejecutada por alguien que no tenga los permisos para hacerlo.

En el codigo de ejemplo tenemos que en el constructor se guarda la direcci贸n de quien lo despliega como owner. Solo el owner debe cambiar la variable de estado projectName.

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Permission {
    address private owner;
    string public projectName = "Platzi";

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can change the project name");
        //la funci贸n es insertada en donde aparece este s铆mbolo
        _;
    }

    function changeProjectName(string memory _projectName) public onlyOwner {
        projectName = _projectName;
    }
}

Usamos la palabra 鈥渕odifier鈥 para definir el modificador, dentro de el llamamos a la funci贸n require, donde su primer par谩metro es la condici贸n que se va a validar, en nuestro caso validamos que el que ejecuta la funci贸n (msg.sender) es el owner. El segundo par谩metro es un mensaje que se lanza en caso de que la validaci贸n falle.

El s铆mbolo 鈥;鈥 identifica donde se insertara el c贸digo de la funci贸n. 驴Cu谩l funci贸n? La funci贸n que queremos validar con nuestro modificador. Es decir donde se encuentra 鈥;鈥 se insertar铆a el c贸digo de 鈥渃hangeProjectName鈥

Excelente clase, aveces se me hace bastante dificil enteder ya que soy totalmente nuevo en la programacion, pero la verdad es emocionante aprender y mas sobre smartcontracts 馃槃

Como comentario, creo que cuando eres nuevo lo mas dificil es es entender la funciones, variables y etc. hasta el punto que parece chino jajaja

Dejo mi ejercicio, usando un modifier y con un if directo en la funci贸n.
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract CrowdFunding {
string public idProject;
string public nameProject;
string public description;
address payable public author;
address private owner;
string public state = 鈥極pened鈥;
uint public funds;
uint public fundraisingGoal;

constructor(string memory _idProject, string memory _nameProject, string memory _description, uint _fundraisingGoal){
    idProject = _idProject;
    nameProject = _nameProject;
    description = _description;
    fundraisingGoal = _fundraisingGoal;
    owner = msg.sender;
    author = payable(msg.sender);
}

modifier onlyOwner() {
  if (msg.sender == owner) {
     _;
  }
}

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

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

}

// 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);
    }
    modifier onlyOwner(){
        require(msg.sender == author,"Just the owner can do this action");
         _;
    }
    modifier excludeOwner(){
        require(msg.sender != author,"Owner can not do this action");
         _;
    }

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

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

Las validaciones que hice al contrato usando los modifiers:


  // Se valida que solo el autor pueda reaalizar ciertas operaciones en el contrato
     modifier onlyOwner {
         require(msg.sender == owner, "You need to be the owner from this contract to change the goalAmount");
         _;
     }
     
     // Se valida que el author no puede agregar fondos al proyeto
     modifier onlyOtherFunders {  
         require(msg.sender != owner, "The author of the contract can't fund the project");
         _;
     } 

Aqui el contrato

Mi c贸digo en respuesta al reto 2:

// 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);
    }

    modifier chageState() {
        require(msg.sender == author, "Solo el autor puede cambiar el estado");
        _;
    }

    modifier canFund() {
        require(msg.sender != author, "El autor no puede invertir en su propio projecto");
        _;
    }

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

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

Mi soluci贸n : D

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

contract crowfundingContract {
    //Definir los datos iniciales de quien despliegue el contrato (i.e. el que empieza su crowfunding con la
    //estructura de este contrato)
    string public id;
    string public projectName;
    string public description;
    string public status = "Opened";
    address payable public author;
    uint public fundingGoal;
    uint public funds;

    //Crear el constructor que inicializa variables relevantes a qui茅n inicie un corwfunding
    constructor(string memory _id, string memory _projectName, string memory _description, uint _fundingGoal){
        author = payable(msg.sender);
        id = _id;
        projectName = _projectName;
        description = _description;
        fundingGoal = _fundingGoal;
    }
    //Crear una funci贸n que permita a qui茅n la llame aportar al crowfunding deseado
    function fundProject() public payable fundRestriction {
        author.transfer(msg.value);
        funds += msg.value;
    }

    //Crear la funci贸n que permita cambiar el estado del proyecto
    function changeProjectStatus(string calldata newStatus) public changeStatusRestriction {
        status = newStatus;
    }
    //Crear el modificador para que s贸lo qui茅n despliega el contraro en la red de ethereum pueda modificar el estado
    //del proyecto a financiar
    modifier changeStatusRestriction(){
        require(
            msg.sender == author,
            "Only the owner can change the status"
        );
        _;
    }
    //Crear la funci贸n modifier que evita que el creador del crowfunding aporte a su propio proyecto
    modifier fundRestriction(){
        require(
            msg.sender != author,
            "You as the author cannot fund this project"
        );
        _;
    }

}

Mi solucion:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

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

    constructor(string memory _id, string memory _name, string memory _description, uint _fundtraisingGoal){
        id = _id;
        name = _name;
        descrition = _description;
        fundraisingGoal = _fundtraisingGoal;
        author = payable(msg.sender);
    }

    modifier onlyOwner(){
        require(
            msg.sender == author,
            "Only owner can change the project name"
        );
        // La funcion es insertada en donde aparece este simbolo
        _;
    }

    modifier differentFromOwner(){
        require(
            msg.sender != author,
            "Only owner can change the project name"
        );
        // La funcion es insertada en donde aparece este simbolo
        _;
    }

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

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

}

Este es mi avance del proyecto con los modifiers del reto #2:

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

contract Proyecto_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, uint _goal){
    projectName = _projectName;
    projectOwner = _projectOwner;
    ownerWallet = payable(msg.sender);
    goal = _goal;
    isOpenToFund = true;
    }

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


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

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

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

No me funciona el noSelfFunds()

// 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;
    bool public projectState = true; //por defecto abierto a recibir aporter
    uint public funds;
    uint256 public fundGoal; //define cuanto espero ganar con la ronda de levantamento de capital
    
    

    constructor(string memory _id, string memory _name, string memory _description, uint256 _fundGoal){
        id = _id;
        name = _name;
        description = _description;
        fundGoal = _fundGoal;
        author = payable(msg.sender); //msg.sender por defecto no recibe ETH pero la convertimos a 'payable'
        projectState = true;
    }


    // solo podemos modificar el estado del projecto siendo el propietario
    modifier onlyAuthor() {
        require(msg.sender == author,
        'Only owner can change state of project'
        );
        _;
    }

    modifier noSelfFunds() {
        require(
             author != msg.sender,
            'Autofinance is not available'
        );
        _;
    }


    //caulquier persona la puede ver y se puede enviar ETH sin problemas
    function fundProject() public payable noSelfFunds {
        
        author.transfer(msg.value); //transfiere el valor del usuario al autor
        funds += msg.value; //despues lo agrego a los fundos del proyecto para registrar el aporte
    }

    //modifica el estado del proyecto. Calldata ahorra gas, solo existe cuando se le llama a la funcion
    function changeProjectState(bool newState) public onlyAuthor returns(bool){
        projectState = newState;
        return projectState;
    }

}

Permission.sol

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

contract Permission {
    address private owner;

    string public projectName = 'Solidity en Platzi';

    constructor(){
        owner = msg.sender;

    }

    //valida que el que ejecuta la funcion es el Owner del contracto 
    modifier onlyOwner() {
        require ( //require: 1er parametro la condicion que va a validad, 2do param mensaje cuando la validacion falla
            msg.sender == owner,
            'Only owner can change project name'
        );
        _; //el guion bajo identificara de donde se insertara el codigo de la funcion 
    }

    function changeProjectName(string memory _projectName) public onlyOwner{
        projectName = _projectName;
    }
}

No entendi mucho en el reto 1 pero ahora todo me queda mucho mas claro.

dejo mi codigo:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract crowdfounding {
    string public id;
    string public name;
    string public description;
    address payable public author;
    string public state = "Opened";
    uint public founds;
    uint public foundsGoal;

    constructor(string memory _id, string memory _name, string memory _description, uint _foundsGoal){
        id = _id;
        name = _name;
        description = _description;
        foundsGoal = _foundsGoal;
        author = payable(msg.sender);
    }

    modifier onlyAuthor(){
        require(
            msg.sender == author,
            "Only author can change the state"
        );
        //Modificacion por author
        _;
    }

    modifier noAuthorPay(){
        require(
            author != msg.sender,
            "Autofinance is not avaible" 
        );
        _;
    }

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

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

}

RETO #2:

//SPDX-License-Identifier: GLP-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';
    uint public funds;
    uint public fundraisingGoal;
    
    constructor(string memory _id,
                string memory _name,
                string memory _description,
                uint _fundraisinGoal){
        id = _id;
        name = _name;
        description = _description;
        fundraisingGoal = _fundraisinGoal;
        author = payable(msg.sender);
                }
                
    modifier noauthor() {
        require(
            msg.sender != author,
            "Author cannot send money to his own project "
            );
            _;
                
    function fundProject() public payable {
        author.transfer(msg.value);
        funds += msg.value;
    }
    
     
    }
    modifier onlyauthor() {
        require(
            msg.sender == author,
            "Only author can change the project name"
            );
            _;
    }
    
    function changeProjectState(string memory _projectName) public  {
        projectName = _projectName;
    }
    
}

Pues este reto me gusto bastante. Tambi茅n por que por que me di cuenta que muchas veces la soluci贸n no es nada complejo, si no algo sencillo que mejora el proyeto:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.7 <0.9.0;

contract reto1 {
    
    string public id;
    string public name;
    string public description;
    address payable public author;
    string public state = "Opened";
    uint public dreamFounds;
    uint public totalFounds = 0;
    
    constructor(string memory _id, string memory _name, string memory _description, uint _dreamFounds) {
        id = _id;
        name = _name;
        description = _description;
        dreamFounds = _dreamFounds;
        author = payable(msg.sender);
    }
    
    modifier noAuthor() {
        require(author != msg.sender, "El author no puede enviar dinero a su propio proyecto");
        _;
    }
    
    function fundProject() payable public noAuthor{
        author.transfer(msg.value);
        totalFounds += msg.value;
    }
    
    modifier onlyAuthor() {
        require(author == msg.sender, "Solamente el propietario puede cerrar el contrato");
        _;
    }
    
    function changeProject(string calldata newState) public onlyAuthor{
        state = newState;
    }
}

Por lo que tengo entendido los strings son muy caros en GAS

Soluci贸n del reto n潞 2, utilice el modifier dentro de la funcion para ahorrar lineas de codigo y funciona perfecto

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';
    uint public funds;
    uint public fundraisingGoal;
    
    constructor(string memory _id, string memory _name, string memory _description, uint _fundraisingGoal){
        id = _id;
        name = _name;
        description = _description;
        fundraisingGoal = _fundraisingGoal;
        author = payable(msg.sender);
    }
    
    modifier onlyOwner() {
        require(
            msg.sender == author,
            "Only author can change the project name");
            _;
    }
    
    function changeName(string memory _name) public onlyOwner {
        name = _name;
    }
    
    
    function fundProject() public payable  {
        require(
            msg.sender != author,
            "Author can't fund the project");
        author.transfer(msg.value);
        funds += msg.value;
    }
    
    function changeProyectState(string calldata  newState) public {
        state = newState;
    }
    
}

En pocas palabras le dije a la funcion que requiera que el inversor no sea el autor ( con esta operacion: != que limita exclusivamente al autor del contrato)

  modifier noAuthorFunds() {
        require(msg.sender != author, "The author can not fund the project");
        _;
    }
    
 
    function fundProject() public payable noAuthorFunds {
        author.transfer(msg.value);
        funds += msg.value;
    }
    
    modifier justAuthor() {
        require(msg.sender == author, "The project state can only be changed by the author");
        _;
    }

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

Me ayudo bastante esta clase para entender mejor como funciona el constructor.

Mi version utilizando function modifiers 馃挭

// 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 OnlyActiveProjects NotOwner {
        ownerWallet.transfer(msg.value);
        currentFunds += msg.value;
    }

    function changeFundStatus() public OnlyOwner {
        isActive = !isActive;        
    }
    
    modifier OnlyActiveProjects() {
        require(isActive == true, "Current project is not available!");
        _;
    }
    
    modifier NotOwner() {
        require(owner != msg.sender, "Owners shouldnt send funds to its own projects!");
        _;
    }
    
    modifier OnlyOwner() {
         require(owner == msg.sender, "You must be the project owner!");
         _;
    }

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

Los modificadores pueden tener la logica que queramos

Ojal谩 se pudieran dar Likes a estos cursos :')

RETO 2

//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
    }
    
    modifier onlyOwner () {
       require(msg.sender == owner, "This function only change for the owner");
       _;
    }
    modifier notYourself () {
       require(msg.sender != owner, "The author cannot send fund for yourself");
       _;
    }
    
    function fundProject(address payable receiver) public notYourself payable {
        require(projectState == true, "This project is closed!");
        receiver.transfer(msg.value);
    }
    
    function changeProjectState(bool state) public  onlyOwner returns(bool){
        projectState = state;
        return projectState;
    }
    
}