No tienes acceso a esta clase

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

Envío de notificaciones utilizando eventos

13/21
Recursos

Con cada transacción que un contrato inteligente procesa correctamente, puede haber partes involucradas e interesadas en ser notificadas de estos cambios de estado de un proyecto.

Envío de notificaciones al exterior de la Blockchain

Los Eventos en Solidity se utilizan para notificar los cambios realizados en un contrato. Cuando un usuario envía ETH y se quiere notificar a otro de su recepción, puedes emplear este mecanismo para que una aplicación externa reciba el mensaje e informe a dicho usuario.

Los eventos deben ser recibidos por medio de aplicaciones Web3 que se encuentren observando el contrato y respondiendo a los eventos. Librerías de Javascript como Web3.js permiten desarrollar este tipo de aplicaciones front end y notificar al usuario de eventos en un contrato.

En Platzi encontrarás el Curso de Dapps: Introducción al Desarrollo de Aplicaciones Descentralizadas y el Curso de Desarrollo Frontend de Aplicaciones Descentralizadas con Web3.Js en donde aprenderás a desarrollar toda una aplicación que responda y notifique eventos en un contrato. Pero tranquilo que aún es pronto para llegar a eso.
:::

Implementando eventos

La declaración de un evento y la emisión de una notificación del mismo se realiza de forma simple:

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

contract Event {

    event Log(address sender, string message);

    function sendMessage() public {
        emit Log(msg.sender, "Este es el mensaje");
    }
}

Utilizando la palabra reservada event, declara el evento que puede recibir por parámetro todos los datos que el mismo necesite. Para emitir un evento, utiliza la palabra reservada emit seguido de la declaración del evento y el pasaje de datos que necesita.

Si emiten un evento, la consola de Remix te permitirá observa los datos de este.

image.png

También puedes emplear este mecanismo para generar un registro de actividad en un contrato, además de notificar usuarios.

Conclusión

Estos conceptos son algo avanzado de Solidity debido a que, sin un front-end, puede no tener tanto sentido su implementación. Es importante para ti en este punto de tu aprendizaje conocer su existencia para usarlos en el futuro.


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

Aportes 30

Preguntas 12

Ordenar por:

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

Eventos

  • Permite conectar lo que pasa dentro de la Blockchain con el exterior porque a tráves de un protocolo otras aplicaciones se pueden suscribir a ellos y escuchar todo lo que está pasando en el Smart Contract.

Se usan para

  • Registrar cambios que se hicieron
  • Feedback (Retroalimentación)

Después de la clase anterior esto se puso genial.

Los modifiers son parecidos a los middlewares de node.js ! 😄

No se si estará del todo correcto, pero se compilo y pude hacer el deploy después de rezarle al dios de los Smart contracts 😂. Acepto criticas

    
    event currentDonation(address donatedFrom, uint256 newFund, uint256 totalFunds);
 
    function fundProject() public payable noAuthorFunds {
        author.transfer(msg.value);
        funds += msg.value;
        emit currentDonation(msg.sender, msg.value, funds);
    }
    
    event ChangeState(string newState);

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

Se que Remix me ayuda a probar el contracto, pero todavía no estoy seguro de como debe funcionar en la vida real. Hay un vacío que todavía no entiendo …

Asi lo hice.

pragma solidity ^0.7.0;


contract KickstarterPoor {
        
    string name;
    string description;
    string state = "opened";
    uint256 goal;
    uint256 funds;
     address private owner;
    
    address payable creatorPayable;
    
    
    constructor(string memory _name, string memory _description, uint256 _goal) payable{
        
        name = _name;
        description = _description;
        owner = msg.sender;
        creatorPayable = payable(owner);
        goal = _goal;
        funds = 0;
        
    }
    
   
    function checkStatus () public view returns (string  memory){
        
    return state;
    }
    
    function getFunds() public view returns (uint256){
        return 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 FundProyect() public payable noFundOwner{
         creatorPayable.transfer(msg.value);
        funds += msg.value;
    }
    
    function changeProjectState(string calldata newState) public  onlyOwner{
        
        state = newState;
    }
    
    
}

Wow esto se ve tan sencillo que parece mentira. Muchas gracias al profesor por todas las clases. Están geniales.

Los eventos en Solidity son herramientas utilizadas por los contratos inteligentes para comunicar que algo ha sucedido en la blockchain. Cuando un contrato inteligente emite un evento, este se registra en un log de transacciones asociado con esa transacción en particular. Estos logs son esencialmente registros de datos que se almacenan en la blockchain de manera inmutable. No ocupan espacio en el almacenamiento del estado del contrato, lo que los hace más eficientes en términos de costos de gas que almacenar datos directamente en el estado del contrato. Los desarrolladores de aplicaciones externas, como las interfaces de usuario, pueden programar sus aplicaciones para que "escuchen" estos eventos. Cuando un evento es emitido y registrado en el log de la blockchain, las aplicaciones que están escuchando estos eventos pueden detectarlos y reaccionar a ellos, por ejemplo, actualizando la interfaz de usuario o ejecutando alguna lógica de aplicación en respuesta al evento. Lo entiendo como algo asi: ```js Bloque #123456 Transacciones: - Transacción A De: 0x123...abc Para: Contrato: RegistroDeTransacciones Valor: 1 ETH Datos: realizarTransaccion(0x456...def, 0.5 ETH, "Pago por servicios") Gas Usado: 21000 Resultado: Éxito Logs: - Evento: TransaccionRealizada Emisor: 0x123...abc Cantidad: 0.5 ETH Mensaje: "Pago por servicios" - Evento: SaldoActualizado Usuario: 0x456...def NuevoSaldo: 1.5 ETH - Transacción B ... Logs: - Evento: AccesoContrato Usuario: 0x789...ghi ContratoAccedido: 0xabc...def - Evento: CambioDeEstado EstadoAnterior: "Pendiente" EstadoNuevo: "Completado" - Transacción C ... Logs: - Evento: CreacionDeToken Creador: 0x987...stu Cantidad: 100 Tokens TokenID: 12345 Hash del Bloque: 0x789...xyz Hash del Bloque Anterior: 0x456...uvw Timestamp: 1234567890 ```

Cumpliendo el reto

<h5>Evento para informar que un usuario ha hecho un aporte</h5>
  event SendFunding(
      address funder,
      uint fund
  );
<h5>Evento para informar que se ha alcanzado el objetivo de fondeo</h5>
  event RaisingFundGoal(
      string idProject,
      uint fundRaising,
      string mensaje
  );

Función funProject() que incluye los eventos

  function fundProject() public payable notFundFronAuthor onlyFundingIfOpened{
    author.transfer(msg.value); // to passe value fund to the author project
    funds += msg.value;
    emit SendFunding(msg.sender, msg.value);
    if (funds >= fundraisingGoal) {
        emit RaisingFundGoal(
            id, 
            funds,
            "fundRaisingGoal reached");
    }
  }
<h5>Evento para informar que el proyecto cambió de estado</h5>
    event ChangeState(
        string idProject,
        string newState
    );

Mi reto:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Project {

    address private owner;
    string public state = "open";

    constructor() {
        owner = msg.sender;
    }

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

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

    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" 
        );
        _donator.transfer(msg.value);
        uint amount = msg.value;
        emit addFunds("Gracias por su aporte", _donator, amount);
    }

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

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

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

}

Eventos

  • Son miembros hereditarios de los contratos.
    -Al momento de llamar un evento, hacen que los argumentos, se almacenen en el registro de transacciones

  • Son usados para informar que algo sucedio en la blockchain, es decir retornan un valor de transaccion.

  • Los smartContacts en si mismos, no pueden escuchar ningun evento.

  • Estan desarrollados para facilitar el desarrollo de sistemas externos.

  • Los eventos facilitan el desarrollo de sistemas externos, en cooperacion con smart contracts.

Reto #3

// 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() {
        owner = msg.sender;
        author = payable(msg.sender);
    }

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

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

    //Evento que muestra la dirección del financiador
    event FundProject(address editor);

    //Evento que muestra el estado cambiado
    event ChangeProjectState(string newState);

    function fundProject() public payable projectFunders {
        author.transfer(msg.value);
        funds += msg.value;
        emit FundProject(msg.sender);
    }
    
    function changeProjectState(string calldata newState) public onlyOwner {
        state = newState;
        emit ChangeProjectState(newState);
    }

}

Así me quedó:

    event FundProject(address colaborator, uint amount, uint totalFunds, uint fundraisingGoal);

    function fundProject() public payable onlyNotOwner {
    owner.transfer(msg.value);
    totalFunds += msg.value;
    emit FundProject(msg.sender, msg.value, totalFunds, fundraisingGoal);
    }

Ya que el evento sirve para informar al user, creo que mientras más info reciba sobre el evento, mejor.

// 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"
     );
     _;
 }
 event fundProjectData(address sender,uint256 quantity);
 function fundProject(address payable direction)public payable notOwnerfund{
    direction.transfer(msg.value);
    emit fundProjectData(msg.sender,msg.value);
}
modifier onlyOwnerState(){
    require(
        msg.sender==owner,"No eres el owner"
    );
    _;
}
event changeProjectStateData(address sender, string newState);
function changeProjectState(string memory _projectState) public onlyOwnerState{
    projectState=_projectState;
    emit changeProjectStateData(msg.sender,_projectState);
}

}

RESUMEN CLASE 13:
EVENTOS

I.- EVENTOS

  • Registran logs.

  • Dan feedback sobre operaciones.

  • Es posible suscribirse a ellos y escucharlos.

II.- RETO 3:

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

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

    event ChangeState(
        bool state
    );

    function fundProject() public payable notOwner onlyActive{
        ownerWallet.transfer(msg.value);
        totalFounded += msg.value;
        emit FundProject(msg.value, msg.sender, name);
    }

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

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

Poco a poco va tomando forma

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

    event FundedProject(
        address contributor,
        uint256 donation
    );

    event ProjectStateChanged(
        address author,
        bool newState
    );

    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;
        emit FundedProject(msg.sender, msg.value);
    }

    function changeProjectState() public onlyOwner{
        isOpen = !isOpen;
        emit ProjectStateChanged(msg.sender, isOpen);
    }

}

Funcion de los eventos

RETO 3

// 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;
    string private tokenLog = "Log: project status changed";
    string private tokenFeedback = "Feedback: Gracias";
  
    constructor(
        string memory _name
        ){
            name = _name;
            isFundable = true;
            deposits = 0;
            depositsGoal=1000;
            autor = msg.sender; 
    }
    event newFundFeedback(
        address autor,
        string Feedback
    );
    event newFundLog(
        string Log
    );
    modifier notOnlyOwnerPay{
        require (autor != msg.sender, "El propietario no puede abonar fondos al proyecto" );
        //la funcion es insertada donde aparece este simbolo _
        _;
    }
    modifier ownerRequired {
        require (msg.sender == autor, "Esta accion es restringida al propietario.");
        _;
    }
    function viewDeposits() public view returns (uint){
        return deposits;
    }

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

    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;
            emit newFundFeedback (autor, tokenFeedback);
        }
        else{
        changeProjectState();
        }
    }

    function changeProjectState() public ownerRequired {
       isFundable = !isFundable;
       emit newFundLog (tokenLog);
    }
}

Alguien me podría apoyar para ejecutar el código en Remix? . . intente importar el repositorio de Github, pero no lo logre …

Adiciona le agregue que pudiera indicar si fondeable o no
//SPDX-License-Identifier:GPL-3.0

pragma solidity >=0.4.22 <0.9.0;

contract platziProject{
//Creacion de variables
bool isFundeable;
uint256 Goal;
uint256 totalFunded;
address owner;
//address payable ownerWallet;
uint256 requiredFunds;

//inicializando los valores
 constructor() {
    Goal = 0;
    owner = msg.sender;
    totalFunded = 0;
    isFundeable = true;
    //ownerWallet = payable(msg.sender);
}

//Valida que el owner no pueda aportar al proyecto
modifier NotOwner{
    require(msg.sender != owner, "The owner cant not contribuite the project");
    _;
}

// modifier permite cambiar el compartamiento de funciones, en este ejemplo solo es para 
modifier onlyOwner{
    require(msg.sender == owner, "You need to be the owner from this contract to change the goal");
    _;
}

//se agrega la meta a recaudar, solamente el creador puede modificar este valor
function setGoal(uint256 goal) public onlyOwner {
    Goal = goal;
}

function viewGoal() public view returns(uint256){
    return Goal;
}
//Muestra si es fondeable o no
function viewisFundeable() public view returns(bool){
    return isFundeable;
}

function changeProjectState(bool change) public onlyOwner{
    isFundeable = change;
}

//inica funcion para fondear el proyecto
function fundproject()public NotOwner payable{
    //Donacion
    //ownerWallet.transfer(msg.value);
    //validacion para que el owner/autor del contrato no pueda aportar al proyecto
    //require(NotOwner, "Owner cant not contribuite this Project");
    //validacion si se mantiene abiertas las donaciones
    require (isFundeable, "Owner has decided to stop this fundraising for a while.Stay tuned");
    //valida que el total fondeado sea menor a la meta
    require(totalFunded < Goal, "Goal already archieved so you are not able to fund this anymore");
    //Validacion de un monto minimo, en este caso mayor a 0
    require(msg.value != uint(0), "Please add some funds to contribuite to Kaoz Project");
    //Valida que el valor que se fondeara no exceda con la meta que se tiene
    require(totalFunded + msg.value <= Goal,"unable to add more funds, check amount remaining for our goal");
    //Actualiza el total que se ha fondeado al contrato
    totalFunded += msg.value;
}

function viewRemaining() public view returns(uint256){
    uint256 remainingFunds = Goal - totalFunded;
        return remainingFunds;
}

}

Este es mi avance con los eventos del reto #3:

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

    event ChangeState(
        string previousState,
        string newState
    );

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

    function fundProject() public payable differentToTheOwner{
        if(isOpenToFund == true){
        ownerWallet.transfer(msg.value);
        currentFund += msg.value;
        emit FundValueGiven(msg.value, (goal - msg.value), "Thanks for your contribution");
        }
    }

    function changeProjectState(string calldata newState) public onlyOwner{
        if(msg.sender == ownerWallet){
            isOpenToFund = !isOpenToFund;
            emit ChangeState(projectState, newState);
            projectState = newState;
            
        }
    }
}
<//SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract CrowdFound {
    string public name;
    string public description;
    address payable public founder;
    uint public funds;
    uint public goal;
    string public state = "Opened";

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

    constructor(string memory _name, string memory _description, uint _goal){
        name = _name;
        description = _description;
        goal = _goal;
        founder = payable(msg.sender);
    }
    modifier excluyeFounder(){
        require(founder != msg.sender , "The founder cannot invest here");
        _;
    }
    modifier onlyFounder(){
        require(founder == msg.sender , "Only Founder can modifier state Project");
        _;
    }
    function fundProject() public payable excluyeFounder{
        founder.transfer(msg.value);
        funds = funds + msg.value;
        emit financedProject (msg.sender, msg.value);
    }
    function changeProjectState(string calldata newState ) public onlyFounder{
        state = newState;
        emit modifiedProject(msg.sender, state);
    }
}> 

Reto 3

//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 isAuthor() {
        require(
            author == msg.sender,
            "You need to be the project author"
            );
            _;
    }
            
    modifier isNotAuthor() {
        require(author != msg.sender , "As author you can not found your own project");
        _;
    }
                
    
    modifier onlyauthor() {
        require(
            msg.sender == author,
            "Only author can change the project name"
            );
            _;
    }
    
    event newcontribution(adress inversor , uint amount, uint statusfunds, uint gasUsed);
    
    event isChangeState(adress author , string statusstate);
    
    function fundProject() public payable isNotAuthor {
        author.transfer(msg.value);
        funds += msg.value;
        emit newcontribution(msg.sender, msg.value, funds, tx.gasprice)
        
    }
    
    function changeProjectState(string calldata newstate) public isAuthor {
        state = newstate;
        emit isChangeState(msg.sender, newstate)
    }
    
}```

Cada clase tu sueldo aumenta un 10%

Esta fue mi solución de este reto:

// 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");
        _;
    }
    
    event FundProject(address donador, uint donacion, uint gasDonacion);
    
    function fundProject() payable public noAuthor{
        author.transfer(msg.value);
        totalFounds += msg.value;
        
        emit FundProject(msg.sender, msg.value, tx.gasprice);
    }
    
    modifier onlyAuthor() {
        require(author == msg.sender, "Solamente el propietario puede cerrar el contrato");
        _;
    }
    
    event ChangeProject(address editor, string newName);
    
    function changeProject(string calldata newState) public onlyAuthor{
        state = newState;
        
        emit ChangeProject(msg.sender, newState);
    }
}

Decidi qu es importante notificar que el autor ha decidido modificar la meta o cuando ha decidido cerrar temporalmente el fondeo al proyecto. Este es mi código

// 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");
         _;
     }
     //Creamos el evento el cual va a necesitar quien lo hizo y en este caso  preferia que cambie la meta de fndeo
     event changeGoal(
         address editor,
         uint256 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;
         emit changeGoal(msg.sender, goal);
     }
     
     function viewGoal() public view returns(uint256) {
         return Goal;
     }
     //Creamos el evento para notificar a los demas que el autor decidio cerrar el fondeo  temporalmente
     event changeState(
         address editor,
         bool change);
         
     function changeProjectState(bool change)public onlyOwner{
         isFundable = change;
         emit changeState(msg.sender, 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;
     }
     
     
 }

Mi resultado agregando eventos al reto #3 💪

// 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;
    }
    
    event NewFundNotification(
        address sender,
        uint fundAmount
    );
    
    event NewStatusChange(
        bool newStatus
    );
    
    function sendFunds() public payable OnlyActiveProjects NotOwner {
        ownerWallet.transfer(msg.value);
        currentFunds += msg.value;
        emit NewFundNotification(msg.sender, msg.value);
    }

    function changeFundStatus() public OnlyOwner {
        isActive = !isActive;
        emit NewStatusChange(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;
    }
}

Para cambiar en nombre del token se usa emit para cambiarlo

Reto #3

    
    event newFund (
        uint256 amount, address whoPay);
        
    event newState (
        bool state);