Events
There is a special data-structure in Ethereum to provide the outside world with better access to return values. That is the logging facility of Ethereum.
Events are a way to access this logging facility. This logging facility gives outside applications a way to subscribe to these events through special RPC methods.
Before digging too much into the events, lets have a look at a simple example.
Contract Example:
Letās start with a simple Smart Contract that returns a value:
//SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
contract EventExample {
mapping(address => uint) public tokenBalance;
constructor() {
tokenBalance[msg.sender] = 100;
}
function sendToken(address _to, uint _amount) public returns(bool) {
require(tokenBalance[msg.sender] >= _amount, "Not enough tokens");
tokenBalance[msg.sender] -= _amount;
tokenBalance[_to] += _amount;
return true;
}
}
Deploy with JavaScript VM
Letās see what happens if you deploy the Smart Contract with the JavaScript VM.
- Select the JavaScript VM
- Deploy the Smart Contract
Send a Token
Now letās actually use the āsendTokenā function. Copy the address of Account#2 into the ā_toā field and enter ā1ā into the _amount field, then start a transaction:
Observe what happens in the Transaction window!
- Open the Transaction Details
- Have a look at the decoded output field!
Normally, there is no decoded output. Sending a transaction is a concurrent operation that usually doesnāt have a return value. There were some discussions to actually return something, but as of writing these lines, events are here to emit values from a writing transaction. Letās test this with a real blockchain!
Deploy with MetaMask
Letās use our Test-Ether we got earlier for Ropsten, Rinkeby or Gƶrli to test if that same behavior happens on a real blockchain!
Select āInjected Web3 Providerā from the Dropdown, autorize MetaMask with Remix and deploy to a test-network where you have some Eth.
Then MetaMask should pop up with a confirmation dialog.
Please double confirm if you are really on a test-network. Otherwise this experiment might become very expensive!
Send a Token
Now, again, send a Token to any address you want. It can also be the same address that deployed the smart contract. Weāre looking just for the return value, so, the actual logic is secondary for now.
Again, MetaMask will pop up. Again, confirm that you are on a test-network and then confirm the transaction.
If you have a look this time at the decoded output, youāll see nothing! šÆ But why?!
Because Events are there to return values from a transaction! Letās add an event!
Interested in seing my transaction from these screenshots? Checkout Etherscan hereā
Add A Solidity Event
Now that you know why we need Events, letās add one and observe the output again!
Modify the contract code as follows:
//SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
contract EventExample {
mapping(address => uint) public tokenBalance;
event TokensSent(address _from, address _to, uint _amount);
constructor() {
tokenBalance[msg.sender] = 100;
}
function sendToken(address _to, uint _amount) public returns(bool) {
require(tokenBalance[msg.sender] >= _amount, "Not enough tokens");
tokenBalance[msg.sender] -= _amount;
tokenBalance[_to] += _amount;
emit TokensSent(msg.sender, _to, _amount);
return true;
}
}
Re-Deploy with MetaMask
Letās re-deploy our contract with MetaMask and run the exact same Transaction. Hereās what we can observe in the Transaction Details:
Suddenly we have ālogsā. These are in-sequence emitted events from the Smart Contract execution!
Letās checkout how this works with web3js now!