智能合约Solidity教程-事件和日志(二)

  上节我们介绍了事件的定义、作用,以及在和前端交互时的示例。那么就会有一个疑问:事件保存的日志如何查看,这就是本文需要讲的内容

承接上篇文章,事件定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
contract MetaCoin {

// 定义事件
event Transfer(address indexed _from, address indexed _to, uint256 _value);

function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver] += amount;
// 触发事件
emit Transfer(msg.sender, receiver, amount);
return true;
}

}

由于日志不可被任何合约访问,那么我们应该如何查找日志了。尽管solidity没有提供查询日志的api,但是监听日志时,提供了filter功能,通过filter我们就可以完成查询日志的需求。
在监听事件时,有三个参数可以指定。上一篇文章中,我们只指定了一个call function参数,另外两个参数分别是:需要过滤的参数值和额外的filter参数,如下所示:

1
2
3
4
5
6
// 写法一
var event = myContract.Transfer(object1, object2);
event.watch(callfunction)

// 写法二
var event = myContract.Transfer(object1, object2, callfunction);

参数解释:
1、object1:json对象,添加indexed属性的参数值,这里需要填具体的值,例如上面的例子,我们可以过滤由指定地址发出的交易{'_from': '0x84d939AD8034c3ce2A7D4D100b939d4523b9E46E'}
2、object2:json对象,额外的filter参数,由solidit提供,可以指定的参数有:
  fromBlock:数字或字符串,默认为latest,指定过滤的起始位置,值为块的编号
  toBlock:数字或字符串,默认为latest,指定过滤的结束位置,值为块的编号
  address:字符串,接收指定账户地址发出的event
  topics:字符串数组,接收指定topic的event。如果是非匿名事件,其中一个topic就是事件签名:Transfer(address,address,uint),匿名事件是无法通过topic来过滤
3、callfunction:回调函数function(error, result){...}

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
MetaCoin.deployed().then(function (instance) {
var obj1 =
var event = instance.Transfer({}function (error, result) {
// 只监听向0x84d939AD8034c3ce2A7D4D100b939d4523b9E46E地址转账的事件
var obj1 = {
'_to': '0x84d939AD8034c3ce2A7D4D100b939d4523b9E46E',
}

// block过滤范围0-latest
var obj2 = {
'fromBlock': 0,
'toBlock': 'latest'
}

var event = instance.Transfer(obj1, obj2)
event.watch(function (error, result) {
console.log('transfer log begin')
console.log(JSON.stringify(result))
console.log('transfer log end')
})
}).then(function (value) {
console.log(value)
}).catch(function (e) {
console.log(e)
})

JouyPub wechat
欢迎订阅「K叔区块链」 - 专注于区块链技术学习