Event Log
The Event Log is one of the most important features of the TRON Virtual Machine (TVM), used to output specific binary data and record it in TransactionInfo when TVM is running a contract. The Event Log can help developers confirm, check, and quickly retrieve specific states of a smart contract. This article introduces basics of the Event mechanism and how to decode the Event Log.
How to Define and Trigger Events in Contracts
In a Solidity contract, you can define an Event via the event
keyword, and trigger an Event via the emit
keyword. When defining an Event, you can specify not only the Event name, but also several parameters to output specific data. Take the Transfer Event of the TRC20 contract as an example:
contract ExampleContractWithEvent {
event Transfer(address indexed from,address indexed to, uint256 value);
constructor() payable public{}
function contractTransfer(address toAddress, uint256 amount){
toAddress.transfer(amount);
emit Transfer(msg.sender,toAddress, amount);
}
}
event Transfer(address indexed from,address indexed to, uint256 value)
defines aTransfer
Event containing three parameters: The first parameter isfrom
, indicating the sender address, the second one isto
, indicating the recipient address, and the third one isvalue
, indicating the transfer amount.emit Transfer(msg.sender,toAddress, amount)
specifies to trigger the corresponding Event after the transfer is completed. The Event contains the sender address, the recipient address, and the amount.
Note:The Solidity specification generally requires that the Event name be capitalized to distinguish it from the corresponding function. For example, distinguish the Event "Transfer" and the function "transfer".
LOG
Solidity uses the LOG instruction to record Event information in TransactionInfo. The Event information is in the log field of TransactionInfo. The following section uses a TransactionInfo snippet obtained through the gettransactioninfobyid
API to illustrate the structure of an Event:
{
"id": "88c66d08f15b983183c7f7d23e3fafec0320bcc837d67957a8bda58d04ca53e1",
......
"log": [
{
"address": "a614f803b6fd780986a42c78ec9c7f77e6ded13c",
"topics": [
"ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"00000000000000000000000079309abcff2cf531070ca9222a1f72c4a5136874",
"00000000000000000000000081b64b1c09d448d25c9eeb3ee3b8f3348a694c96"
],
"data": "00000000000000000000000000000000000000000000000000000000b2d05e00"
}
]
}
log
: The list of Events triggered in the transaction. For each Event, it contains the following three parts:
address
: Contract address. In order to be compatible with the EVM, the address in the TVM is a hex format address without the prefix0x41
. So if you want to parse the address in the log, you need to add41
to the beginning of the log address , and then convert it to the Base58 format .topics
: The topic of the Event, including the Event itself and parameters marked asindexed
. The reason for usingtopics
to save theindexed
parameters is that blockchain always uses key-value storage engines such as LevelDB or RockDB. These engines generally support theprefix-scan
operation. So putting theindexed
parameters intotopics
enables quickly retrieving theTransfer
Event or retrieving a specificTransfer
Event with a targettoAddress
.data
: Non-indexed parameters of Events, such asamount
.
LOG Decoding
For Events in the above LOG section, if you want to decode them, you must first know the ABI of the Event. The following is the ABI of the above Transfer Event:
{
"anonymous":false,
"inputs":
[
{"indexed":true,"name":"from","type":"address"},
{"indexed":true,"name":"to","type":"address"},
{"indexed":false,"name":"value","type":"uint256"}
],
"name":"Transfer",
"type":"event"
}
Check the Event log along the ABI to decode the data:
topics[0]
:ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef is the Event itself. This value is the calculation result ofkeccak256('Transfer(address,address,uint256)')
, so the Event is a Transfer Event. The keccak256 hash value of the Event can be calculated via tronweb.sha3(). Note: The parameter of keccak256 must be a string without any spaces; otherwise, the calculated hash value will be different.topics[1]
:00000000000000000000000079309abcff2cf531070ca9222a1f72c4a5136874 is the first indexed parameter,from
. The address here is the 20-byte address with the prefix 0x41 removed. Therefore, for this parameter, get the last 40 bits of data, and add41
in the front to get the TRON hex address.topics[2]
:00000000000000000000000081b64b1c09d448d25c9eeb3ee3b8f3348a694c96 is the second indexed parameter,to
, indicating the recipient account address. The parsing logic is the same as above.data
: 00000000000000000000000000000000000000000000000000000000b2d05e00 is the value of a non-indexed parameter. If there are multiple non-indexed parameters, they are listed in the order according to the ABI coding rules. For details, please refer to ABI coding rules. For this example, there is only one non-indexed parameter, namelyvalue
, the transfer amount. The hexadecimal data can be directly converted to decimal.
Updated 3 days ago