Events
Introduction
The log mechanism is one of the most important features of a virtual machine, which is used to output specific binary data and record it in transaction-receipt while the virtual machine is running a contract. Based on the Log mechanism, the Event feature is implemented to help developers confirm, check, and quickly retrieve specific states of a smart contract. This article introduces the basics of the Event mechanism and how to decode the Event Log.
Solidity Event
Events in Solidity are defined by the event
keyword. Triggering and logging an Event is implemented through the emit
keyword. An Event is not just a specific event name, but can contain several parameters.
Solidity Event Example:
contract EventExampleContract {
event Transfer(address indexed toAddress, uint256 amount);
constructor() payable public{}
function contractTransfer(address toAddress, uint256 amount){
toAddress.transfer(amount);
emit Transfer(toAddress, amount);
}
}
event Transfer
defines aTransfer
event containing two parameters, the first beingtoAddress
which represents the destination address of the transfer, and the second beingamount
which represents the amount of the transfer.emit Transfer(toAddress, amount)
triggers the corresponding Event when the contract completes the transfer function.
Tips
The specification generally requires that the Event name be capitalized to distinguish it from the corresponding function. For example, the event
Transfer
andtransfer
functions.
Event Structure
Solidity uses LOG instruction to record event information in a transaction. The structure in protobuf is as follows:
message Log {
bytes address = 1;
repeated bytes topics = 2;
bytes data = 3;
}
message TransactionInfo {
// ...
// A list of LOG represent list of events in a transaction
repeated Log log = 8;
// ...
}
Where the topics
field indicates the topic of the event, e.g. the topic Transfer(...)
. Also, all parameters marked as indexed
are listed in the topics
field in that order.
The data
field represents other non-indexed
parameters of the event, such as amount
.
Decoding Events Example
The ABI for the above Transfer
event is defined as:
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "toAddress",
"type": "address"
},
{
"indexed": false,
"name": "amount",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
}
Use gettransactioninfobyid
API to get the transaction result:
log:
address:
289C4D540B32C7BC56953E55631F8B141EB86434 # contract address in 20-byte format
data:
0000000000000000000000000000000000000000000000000000000000000001
topics:
69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de2 # topics[0]
000000000000000000000000E552F6487585C2B58BC2C9BB4492BC1F17132CD0 # topics[1]
Check along with ABI:
-
topics[0] is 69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de2. It is the result of keccak("event(address,uint256)").
-
topics[1] is 000000000000000000000000E552F6487585C2B58BC2C9BB4492BC1F17132CD0. It is the first indexed param (toAddress) with type address.
-
data is 0000000000000000000000000000000000000000000000000000000000000001. It is the param without being indexed (amount) with type uint256.
Event Subscription Support
Refer to:
Updated over 3 years ago