美文网首页
从以太坊交易日志中监听智能合约事件event

从以太坊交易日志中监听智能合约事件event

作者: sky2016 | 来源:发表于2019-07-11 15:37 被阅读0次

    以太坊智能合约中,有一类特殊的回调函数,没有函数体,以大写字母开头,一般用来记录函数状态,这类回调函数称为事件event。事件event由合约函数调用,web3.js可以轻松监听此类event,并返回需要的数据。在网上搜索到的相关文章都是关于用web3.js来实现监听event的,今天我们就来从c++代码层面来看看怎么实现这个功能。
    我们先来看看一个简单的智能合约例子:

    contract Contract {
        event Incremented(bool indexed odd, uint x, uint y);
        function Contract() {
            x = 69;
            y = 20;
        }
        function inc() {
            ++x;
            ++y;
            Incremented(x % 2 == 0, x, y);
        }
        uint x;
        uint y;
    }
    

    这个合约只有两个变量x, y,一个函数inc()和一个事件Incremented,如果我们调用Contract中的inc()函数,则事件Incremented会被执行,我们的目的就是监听这个事件。

    首先我们在私有链上来部署这个合约,部署的过程就不赘述了,简单说就是执行一笔交易,交易的data为合约的二进制代码。

    同样调用智能合约的函数也是向智能合约发送一笔交易,将函数以及相关参数放到交易的data中,也就是调用Client::submitTransaction()这个函数,返回值是h256类型,为交易的hash值,也就是交易的id。如果此笔交易在区块链上得到确认,则智能合约中的函数会被执行,函数中的事件会被触发,事件触发的结果记录在交易的日志中。那么我们去哪里找交易的日志呢?
    当一笔交易得到确认,我们可以根据交易id去区块链上找到该笔交易的收据(receipt),receipt中记录交易的执行情况。

    执行以下代码可以得到交易收据

    toJson(m_pClient->localisedTransactionReceipt(h)).toStyledString();
    

    其中m_pClientdev::eth::Client类实例,h是交易id。
    我们执行inc()后,得到的收据内容为

    {
       "blockHash" : "0x862b329c8f5e8310ed5cc6decc18ccc61a96c984aeb3003627abdd9789bd73d9",
       "blockNumber" : 798,
       "contractAddress" : "0x46f74069282ce80249112a50c5fdea621436c2e7",
       "cumulativeGasUsed" : "0x85ba",
       "from" : "0x8fc41de977db1d49cff206ad8b25605e2b63e56e",
       "gasUsed" : "0x85ba",
       "logs" : [
          {
             "address" : "0x59a1181c37245f8b4d7c7a5cec19d22dd5da4331",
             "blockHash" : "0x862b329c8f5e8310ed5cc6decc18ccc61a96c984aeb3003627abdd9789bd73d9",
             "blockNumber" : 798,
             "data" : "0x00000000000000000000000000000000000000000000000000000000000000460000000000000000000000000000000000000000000000000000000000000015",
             "logIndex" : 0,
             "polarity" : false,
             "topics" : [
                "0x9b44895fef8929cca514f54bb4c52d35b5f403b960a39478ed7f4408e46eb69e",
                "0x0000000000000000000000000000000000000000000000000000000000000001"
             ],
             "transactionHash" : "0xc5659816ee1239f48cba7d99ea7defeb7b927dff8a9d074f618aa308fb1e9eb4",
             "transactionIndex" : 0,
             "type" : "mined"
          }
       ],
       "logsBloom" : "0x00000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000010000000040000000000000800000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000008000000000000000000000000000000000000000000000000000040000020000000000000000000000000000000000000000000000000000000000000",
       "stateRoot" : "0x2ff5b94c86fb021d6c354f827278ec48bd037a9b3981253f383717fe8f022eda",
       "to" : "0x59a1181c37245f8b4d7c7a5cec19d22dd5da4331",
       "transactionHash" : "0xc5659816ee1239f48cba7d99ea7defeb7b927dff8a9d074f618aa308fb1e9eb4",
       "transactionIndex" : 0
    }
    

    我们要从日志从寻找需要的东西,因此我们关注logs这部分内容。再看topics,这是一个数组,第一行的内容应该为事件名称的hash值,我们来计算一下:

    auto sh = dev::sha3("Incremented(bool,uint256,uint256)");
    std::cout << "0x" << sh.hex() << std::endl;
    

    结果正是0x9b44895fef8929cca514f54bb4c52d35b5f403b960a39478ed7f4408e46eb69e,因此我们就知道这个事件得到了触发。
    再来看这个事件的参数,第一个参数是x % 2 == 0的值,应该true, 也就是1,正是topics中第二行的值,注意到合约代码中Incremented第一个参数是indexed的,也就是这个标志的参数都会记录在topics的第2-n行中。那么没有这个标志的参数在哪呢?注意到上面还有个data,内容为0x00000000000000000000000000000000000000000000000000000000000000460000000000000000000000000000000000000000000000000000000000000015,这个可以分为两部分:
    0x00000000000000000000000000000000000000000000000000000000000000460x0000000000000000000000000000000000000000000000000000000000000015,正是后面两个参数x和y的值,因此通过解析交易收据receipt,我们就能够得到事件触发的完整信息,也就是能够监听这个事件了。

    更多文章请欢迎光临个人博客

    相关文章

      网友评论

          本文标题:从以太坊交易日志中监听智能合约事件event

          本文链接:https://www.haomeiwen.com/subject/qbddkctx.html