以太坊交易事件,日志的理解

想知道更多关于区块链技术知识,请百度【链客区块链技术问答社区】
链客,有问必答!

在这里插入图片描述

Ethereum transation event and log
以太坊交易事件的功能有三个:

  1. 用于返回智能合约执行过程中的返回值到用户界面
  2. 同步触发前端用户界面事件
  3. 便宜的存储
    例如某交易有如下日志:
    https://etherscan.io/tx/0xb1c0abd217193ffe64f97caedad8fa6f0f9c0265967d2ab9fb782280c928fb47#eventlog
    大家可以看到如下信息:
    // 第一个日志: noteAddress 0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0
    Topics [0] 0xa9059cbb00000000000000000000000000000000000000000000000000000000
    [1] 0x0000000000000000000000005af33b044fc0b24758552a2b3efb8b27bb06b038
    [2] 0x00000000000000000000000000c097f24ae4dd09359f87d85bc883a72a5a46c7
    [3] 0x0000000000000000000000000000000000000000000000000de0b6b3a7640000
    Data
    0000000000000000000000000000000000000000000000000000000000000000
    0000000000000000000000000000000000000000000000000000000000000040
    0000000000000000000000000000000000000000000000000000000000000044
    a9059cbb00000000000000000000000000c097f24ae4dd09359f87d85bc883a7
    2a5a46c70000000000000000000000000000000000000000000000000de0b6b3
    a7640000// 第二个日志:Transfer
    Topics [0] 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
    [1] 0x0000000000000000000000005af33b044fc0b24758552a2b3efb8b27bb06b038
    [2] 0x00000000000000000000000000c097f24ae4dd09359f87d85bc883a72a5a46c7
    Data
    0000000000000000000000000000000000000000000000000de0b6b3a7640000

通过
web3.eth.getTransaction(‘0xb1c0abd217193ffe64f97caedad8fa6f0f9c0265967d2ab9fb782280c928fb47’);
也可以获得交易的信息,通过获得消息回执,可以获得事件信息:
web3.eth.getTransactionReceipt(‘0xb1c0abd217193ffe64f97caedad8fa6f0f9c0265967d2ab9fb782280c928fb47’);
这是一条事件日志, 执行的合约是:EOSTokenContract
调用的函数是transfer函数。
通过查看合约的代码,我们知道合约会产生两条日志,为了方便理解,我贴出源码:
contract DSNote {
event LogNote(
bytes4 indexed sig,
address indexed guy,
bytes32 indexed foo,
bytes32 indexed bar,
uint wad,
bytes fax
) anonymous;
modifier note {
bytes32 foo;
bytes32 bar;

    assembly {
        foo := calldataload(4)   // 获取执行合约交易时的调用数据,同第4个字节开始的32个字节[4~36)
        bar := calldataload(36)  // 获取执行合约交易时的调用数据,同第36个字节开始的32个字符[36, 68)
    }

    // 产生一条日志消息
    LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data);

    _;
}

}
contract ERC20{
//…
event Transfer( address indexed from, address indexed to, uint value);
}
contract DSTokenBase{
//…function transfer(address dst, uint wad) returns (bool) {
assert(_balances[msg.sender] >= wad);

_balances[msg.sender] = sub(_balances[msg.sender], wad);
_balances[dst] = add(_balances[dst], wad);

Transfer(msg.sender, dst, wad);

return true;

}
//…
}

contract DSToken is DSTokenBase{
//…function transfer(address dst, uint wad) stoppable note returns (bool) {
return super.transfer(dst, wad);
}
//…
}

从合约DSToken的transfer接口可以看到使用stoppable和note修饰符,修饰符在代码中有定义。
note的修饰符生成了日志:
LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data);
同时transfer也调用了Transfer事件,这样产生了两个事件。
Transfer日志分析如下:
event Transfer( address indexed from, address indexed to, uint value);
该事件名称为Transfer, 参数from和to使用了indexed修饰符,表示这两个参数需要作为topic记录。
Transfer函数的Keccak-256 SHA3结果生成方法如下:
转换事件函数:
Transfer(address,address,uint256)
执行sha3函数获得hash:
web3.sha3(‘Transfer(address,address,uint256)’);
“0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef”
得到第二条日志(Transfer)的第一个topic, 第2,3个Topic为from, to的值:
0x5af33b044fc0b24758552a2b3efb8b27bb06b038,
0x00c097f24ae4dd09359f87d85bc883a72a5a46c7
后面的data数据为代币转移的数值:
0000000000000000000000000000000000000000000000000de0b6b3a7640000
和交易的数据是一致的。
note日志负责些许,而且,无法用我目前知道的知识分解完整,方法和上面类似。
由于note事件有4个indexed参数,且LogNote有anonymous修饰符,所以函数名称不会作为topic.
Topic的值都为日志参数值,可是数据中多出了两个32字节的数据:
“0x0000000000000000000000000000000000000000000000000000000000000000 // msg.vlue
0000000000000000000000000000000000000000000000000000000000000040 // ??不知道是什么数据
0000000000000000000000000000000000000000000000000000000000000044 // ??
a9059cbb00000000000000000000000000c097f24ae4dd09359f87d85bc883a72a5a46c70000000000000000000000000000000000000000000000000de0b6b3a7640000”, // msg.data

猜你喜欢

转载自blog.csdn.net/weixin_44172023/article/details/89137850
今日推荐