1. 程式人生 > >解析solidity的event log

解析solidity的event log

參考文件

例子程式碼如下:

pragma solidity ^0.4.25;

contract Assert{
    
}
contract TestReturn {
    
    Assert ast;
    event CreateAssertAll(Assert indexed _sig,uint256 indexed  id);
    event CreateAssertOne(Assert indexed _sig,uint256  id);
    event Create(Assert _sig,uint256 id);

    
    function check() public returns(uint256) {
        ast = new Assert();
        emit CreateAssertAll(ast,uint256(6));
        emit CreateAssertOne(ast,uint256(6));
        emit Create(ast,uint256(6));
    }
    
}

上面的程式碼中,有3個event。他們的index不同。生成的log資料結構不一樣。

使用web3檢視日誌。

const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/XXX"));

const SolidityCoder = require("web3/lib/solidity/coder.js");
web3.eth.getTransactionReceipt("0x12e3384bdba97c631bbaa5df27e94e6baeb9ee894ee80c7d9ce0e1b9944b70d7",function(error, result){
    if(!error){
        // console.log("receipt ==== ",result);
        let logs = result.logs;
        console.log("logs ==== ",logs);
        let data = SolidityCoder.decodeParams(["address", "uint256"], logs[2].data.replace("0x", ""));
        console.log("data ==== ",data);
    }
    else
        console.error(error);
});

可以看到列印日下:

logs ====  [ { address: '0x92e22427412dc8705b69c2db1b702d51586018f5',
    blockHash: '0x06cf0bd459caa91c9fd13a7b65875d300942648a975bf282813c4e1596258192',
    blockNumber: 4381899,
    data: '0x',
    logIndex: 3,
    removed: false,
    topics: 
     [ '0xd39437daf43d90c2fc7f92c178818776f8ae6c1e6bde3215fa60b27756797d17',
       '0x00000000000000000000000029f65c9a6f016ad76f5a26896343d3731267cc36',
       '0x0000000000000000000000000000000000000000000000000000000000000006' ],
    transactionHash: '0x12e3384bdba97c631bbaa5df27e94e6baeb9ee894ee80c7d9ce0e1b9944b70d7',
    transactionIndex: 20 },
  { address: '0x92e22427412dc8705b69c2db1b702d51586018f5',
    blockHash: '0x06cf0bd459caa91c9fd13a7b65875d300942648a975bf282813c4e1596258192',
    blockNumber: 4381899,
    data: '0x0000000000000000000000000000000000000000000000000000000000000006',
    logIndex: 4,
    removed: false,
    topics: 
     [ '0xef0d7493287e1bf143771073deb917ba8ae1b8503a98a3d6d490d058e81d67ea',
       '0x00000000000000000000000029f65c9a6f016ad76f5a26896343d3731267cc36' ],
    transactionHash: '0x12e3384bdba97c631bbaa5df27e94e6baeb9ee894ee80c7d9ce0e1b9944b70d7',
    transactionIndex: 20 },
  { address: '0x92e22427412dc8705b69c2db1b702d51586018f5',
    blockHash: '0x06cf0bd459caa91c9fd13a7b65875d300942648a975bf282813c4e1596258192',
    blockNumber: 4381899,
    data: '0x00000000000000000000000029f65c9a6f016ad76f5a26896343d3731267cc360000000000000000000000000000000000000000000000000000000000000006',
    logIndex: 5,
    removed: false,
    topics: 
     [ '0xcc9018de05b5f497ee7618d8830568d8ac2d45d0671b73d8f71c67e824122ec7' ],
    transactionHash: '0x12e3384bdba97c631bbaa5df27e94e6baeb9ee894ee80c7d9ce0e1b9944b70d7',
    transactionIndex: 20 } ]
data ====  [ '0x29f65c9a6f016ad76f5a26896343d3731267cc36',
  BigNumber { s: 1, e: 0, c: [ 6 ] } ]

分析日誌可以知道。

  • 一共生成了3個日誌。
  • topics的第一個值topics[0]是sha3(event名字(引數1型別,引數2型別))
  • 引數內容:如果event的引數是index,那就會在topics的值中。如果不是index,那就會在data中。

比較方便的解析方式:

let abi = "";
let SolidityEvent = require("web3/lib/web3/event.js");
let logParser =  (logs, abi) => {

    // pattern similar to lib/web3/contract.js:  addEventsToContract()
    let decoders = abi.filter(function (json) {
        return json.type === 'event';
    }).map(function(json) {
        // note first and third params required only by enocde and execute;
        // so don't call those!
        return new SolidityEvent(null, json, null);
    });

    return logs.map(function (log) {
        return decoders.find(function(decoder) {
            return (decoder.signature() == log.topics[0].replace("0x",""));
        }).decode(log);
    })
};
web3.eth.getTransactionReceipt("0x12e3384bdba97c631bbaa5df27e94e6baeb9ee894ee80c7d9ce0e1b9944b70d7",function(error, result){
    if(!error){
        // console.log("receipt ==== ",result);
        let logs = result.logs;
        let events = logParser(logs,JSON.parse(abi));
        console.log("logParser === ",events)
    }
    else
        console.error(error);
});