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.
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.
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?
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 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 …
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
```
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>
// 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(stringmessage, addressdonator, uintamount );
function fundProject(addresspayable_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(stringmessage, stringoldState, stringnewState);
function changeProjectState(stringmemory_newState) public onlyOwnerState {
string memory oldState = state;
state = _newState;
emit changeState("El autor ha cambiado el estado", oldState, state);
}
}
//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;
}
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 variablesbool 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 valorfunctionsetGoal(uint256 goal)publiconlyOwner{
Goal = goal;
emit changeGoal(msg.sender, goal);
}
functionviewGoal()publicviewreturns(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);
functionchangeProjectState(bool change)publiconlyOwner{
isFundable = change;
emit changeState(msg.sender, change);
}
//Aqui inicia la funcion para fondear el proyectofunctionfundproject()publicpayable{
//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 metarequire(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 0require(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 tenemosrequire(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 maximofunctionviewRemaining()publicviewreturns(uint256){
uint256 remainingFunds = Goal - totalFunded;
return remainingFunds;
}
}
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?