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

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

Ethereum transation event and log
以太坊交易事件的功能有三个:
1. 用于返回智能合约执行过程中的返回值到用户界面
2. 同步触发前端用户界面事件
3. 便宜的存储

例如某交易有如下日志:
https://etherscan.io/tx/0xb1c0abd217193ffe64f97caedad8fa6f0f9c0265967d2ab9fb782280c928fb47#eventlog

大家可以看到如下信息:

// 第一个日志: note
Address     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

你可能感兴趣的:(区块链)