查询或解析solidity智能合约事件event或logs日志

写在前面

我们经常会遇到查询或访问某个合约的历史log日志,并解析合约地址相关日志,当然也可以是某个用户的地址。

下面根据案例,讲实际需求和解决方案

这是一个token合约,我们将获取此token合约的所有转账事件的历史记录

https://kovan.etherscan.io/address/0x29abca1f656a18d765971b4bad0ce112669e866e#code
以上链接是源码链接地址;

我们的需求这样的

通过web3js获取此token合约的转账事件,并解析此token合约对应的日志

这是event事件代码

  /**
   * @dev Emitted when `value` tokens are moved from one account (`from`) to
   * another (`to`).
   *
   * Note that `value` may be zero.
   */
  event Transfer(address indexed from, address indexed to, uint256 value);

 这是要解析的日志log,下面emit 后面的代码


  /**
   * @dev Moves tokens `amount` from `sender` to `recipient`.
   *
   * This is internal function is equivalent to {transfer}, and can be used to
   * e.g. implement automatic token fees, slashing mechanisms, etc.
   *
   * Emits a {Transfer} event.
   *
   * Requirements:
   *
   * - `sender` cannot be the zero address.
   * - `recipient` cannot be the zero address.
   * - `sender` must have a balance of at least `amount`.
   */
  function _transfer(address sender, address recipient, uint256 amount) internal {
    require(sender != address(0), "BEP20: transfer from the zero address");
    require(recipient != address(0), "BEP20: transfer to the zero address");

    _balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");
    _balances[recipient] = _balances[recipient].add(amount);
   

 //要解析的日志logs   
 emit Transfer(sender, recipient, amount);



  }

 

解决方案

首先打开web3js官方文档:web3.eth.Contract — web3.js 1.0.0 documentation

这里提供了三种直接访问的方案(其它方案这里不阐述)

分别是:1:once
               2:events
               3:getPastEvents

这里我们以getPastEvents为例详细阐述

getPastEvents - 读取合约历史事件

读取合约的历史事件。

调用:

myContract.getPastEvents(event[, options][, callback])

参数:

  • event - String: 事件名,或者使用 "allEvents" 来读取所有的事件
  • options - Object: 用于部署的选项,包含以下字段:
    • filter - Object : 可选,按索引参数过滤事件,例如 {filter: {myNumber: [12,13]}} 表示所有“myNumber” 为12 或 13的事件
    • fromBlock - Number : 可选,仅读取从该编号开始的块中的历史事件。
    • toBlock - Number : 可选,仅读取截止到该编号的块中的历史事件,默认值为"latest"
    • topics - Array : 可选,用来手动设置事件过滤器的主题。如果设置了filter属性和事件签名,那么(topic[0])将不会自动设置
  • callback - Function : 可选的回调参数,触发时其第一个参数为错误对象,第二个参数为历史事件数组

返回值:

一个Promise对象,其解析值为历史事件对象数组

示例代码:

myContract.getPastEvents('MyEvent', {
    filter: {myIndexedParam: [20,23], myOtherIndexedParam: '0x123456789...'}, // Using an array means OR: e.g. 20 or 23
    fromBlock: 0,
    toBlock: 'latest'
}, function(error, events){ console.log(events); })
.then(function(events){
    console.log(events) // same results as the optional callback above
});

> [{
    returnValues: {
        myIndexedParam: 20,
        myOtherIndexedParam: '0x123456789...',
        myNonIndexParam: 'My String'
    },
    raw: {
        data: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
        topics: ['0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7', '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385']
    },
    event: 'MyEvent',
    signature: '0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7',
    logIndex: 0,
    transactionIndex: 0,
    transactionHash: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
    blockHash: '0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7',
    blockNumber: 1234,
    address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
},{
    ...
}]

我们的代码;

var Web3 = require('web3');
var web3;
var topic=["0x29abca1F656A18D765971B4Bad0cE112669E866e"];
var abi = [{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[],"name":"_decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}];

async function createWeb3(){
    try {
        web3 = new Web3(new Web3.providers.HttpProvider('https://kovan.infura.io/v3/097a55226aad462e913bbf6c60ca039e'));
    } catch (error) {
      console.log(error);
      return false;
    }
}


// main();
async function  main(){
    if (await createWeb3() == false) {
        console.log('Web3 Create Error'.yellow);
        process.exit();
    }
    var fomo =new web3.eth.Contract(abi,
    topic);


    fomo.getPastEvents("Transfer",{fromBlock: 0,
        toBlock: 'latest'
    }, function(error, events){ console.log(events); })
    .then(function(events){
        console.log(events) // same results as the optional callback above
    });
}
main();


返回结果:
 

[{
    address: '0x29abca1F656A18D765971B4Bad0cE112669E866e',
    blockHash: '0xfcfc3a30ddd6e7cf792f8f5b0ae34ecce279ef53d8d1fa2803b5e97c40ec7a6e',
    blockNumber: 33488693,
    logIndex: 0,
    removed: false,
    transactionHash: '0xba0694b985d51d845ed028062bd272b3b0261f59f93068663fa3e06b45bfbbfc',
    transactionIndex: 0,
    transactionLogIndex: '0x0',
    type: 'mined',
    id: 'log_f5d16985',
    returnValues: Result {
      '0': '0x65518F078Ea391fdFFa3ebe916778b70440116D7',
      '1': '0xe980414De23cb6fD52958B4E9b7720823cb18F41',
      '2': '100000000000000000000',
      from: '0x65518F078Ea391fdFFa3ebe916778b70440116D7',
      to: '0xe980414De23cb6fD52958B4E9b7720823cb18F41',
      value: '100000000000000000000'
    },
    event: 'Transfer',
    signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
    raw: {
      data: '0x0000000000000000000000000000000000000000000000056bc75e2d63100000',
      topics: [Array]
    }
  }
]

其中一下便是我们解析事件和日志的结果

    returnValues: Result {
      '0': '0x65518F078Ea391fdFFa3ebe916778b70440116D7',
      '1': '0xe980414De23cb6fD52958B4E9b7720823cb18F41',
      '2': '100000000000000000000',
      from: '0x65518F078Ea391fdFFa3ebe916778b70440116D7',
      to: '0xe980414De23cb6fD52958B4E9b7720823cb18F41',
      value: '100000000000000000000'
    },


关于topics怎么来的怎么计算的请看这篇文章:Web3Js订阅Log示例_北纬32.6的博客-CSDN博客

以及参考链接:web3.eth.abi — web3.js 1.0.0 documentation

你可能感兴趣的:(智能合约,以太坊事件event,以太坊日志logs,解析日志logs,解析事件event)