web3.js 智能合约事件
以太坊智能合约能够发出事件,表示在智能合约代码执行中发生的事情。智能合约的前端UI,例如,DApps、web3.js,都可以侦听这些事件。
事件在区块链中的存储
区块链是一个由区块组成的列表,这些块的内容基本上是交易记录。每个交易都有一个附加的交易日志,事件结果存放在交易日志里。合约发出的事件,可以使用合约地址访问。
web3.js中,可以通过智能合约对象中的getPastEvents函数访问事件。
本章示例,我们将实际连接到Ethereum主网来获取OmiseGo ERC-20通证的传输事件。ERC-20标准规定,实现该标准的智能合约必须在传输通证时发出传输事件。
使用web3.js获取OmiseGo智能合约事件的步骤如下:
创建智能合约对象。
使用getPastEvents函数获取事件
注意,此次连接到以太坊主网(mainnet)
创建智能合约对象
创建智能合约对象,要设置智能合约的ABI代码及地址,这些信息都可以在etherscan查询到。
const Web3 = require('web3') const web3 = new Web3('https://mainnet.infura.io/YOUR_INFURA_API_KEY') // 连接到主网// OMG Token Contract ABI code const abi = [{"constant":true,"inputs":[],"name":"mintingFinished","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"finishMinting","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_releaseTime","type":"uint256"}],"name":"mintTimelocked","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[],"name":"MintFinished","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]// 智能合约地址 const address = '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07'// 创建智能合约对象 const contract = new web3.eth.Contract(abi, address)
使用getPastEvent`函数获取事件
查看智能合约的事件,可以使用contract对象上的getPastEvents()函数。
contract.getPastEvents( 'AllEvents', // 过滤事件参数,这里获取全部事件 { fromBlock: 0, // 起始块 toBlock: 'latest' // 终止块 }, (err, events) => { console.log(events) } // 回调函数 )
fromBlock与toBlock指定了查询事件的起始区块与终止区块,如果区块中的事件太多,getPastEvents函数调用会失败。
可以限制一下要查询区块的范围,以免函数执行失败。我们的示例中会查询最新几个区块中的事件,关于最新区块的序号,可以通过etherscan查询。
contract.getPastEvents( 'AllEvents', { fromBlock: 8717848, toBlock: 'latest' }, (err, events) => { console.log(events) } )