Solidity:那些你就可能错误的调用
1.solidity 中对于事件的监听
1.1 solidity的event事件
事件是以太坊EVM提供的一种日志基础设施。事件可以用来做操作记录,存储为日志。也可以用来实现一些交互功能,比如通知UI,返回函数调用结果等1。通过监控事件的执行,可以实现对事件状态的有效查看,并实现本地的数据处理等操作。
1.1.1事件
当定义的事件触发时,我们可以将事件存储到EVM的交易日志中,日志是区块链中的一种特殊数据结构。日志与合约关联,与合约的存储合并存入区块链中。只要某个区块可以访问,其相关的日志就可以访问。但在合约中,我们不能直接访问日志和事件数据(即便是创建日志的合约)。
solidity 中对于世家的定义如下:
pragma solidity >=0.4.22 <0.7.0;
contract User {
event data(string name, int256 age);
function updateData(string memory _name, int256 _age) public
{
emit data(_name, _age);
}
}
1.1.2在javascript 可以使用web3对上述事件进行监视:
(1)方法一
var event = myContract.transfer();
// 监听
event.watch(function(error, result){
console.log("Event are as following:-------");
for(let key in result){
console.log(key + " : " + result[key]);
}
console.log("Event ending-------");
});
上述这种方式:会显示没有watch函数,应该是版本变化,也可能是web3的问题,所有我推荐大家使用如下的监听方式:
(2)方法二
另外一种简便写法是直接加入事件回调,这样就不用再写watch的部分:
var event = myContract.transfer(function(error, result){
console.log("Event are as following:-------");
for(let key in result){
console.log(key + " : " + result[key]);
}
console.log("Event ending-------");
});
其实查看已有的web3.js文件,我们可以发现,官方已经给出了一个对于事件监听函数的声明形式:
http://cw.hubwiz.com/card/c/web3.js-1.0/1/4/13/
const { data } = this.meta.events;
//监听事件
data((err, event) => {
// console.log(event)
}).on('data', (event) => {
console.log(event.returnValues)
})
其中,第一行是获取其中的事件,名称。下面的就是对于监听事件的声明,其中:
myContract.events.MyEvent([options][, callback])
参数:
options - Object: 可选,用于部署的选项,包含以下字段:
filter - Object : 可选,按索引参数过滤事件。例如 {filter: {myNumber: [12,13]}} 表示 “myNumber” 为12或13的所有事件
fromBlock - Number: 可选,仅监听该选项指定编号的块中发生的事件
topics - Array : 可选,用来手动为事件过滤器设定主题。如果设置过filter属性和事件签名,那么(topic[0])将不会自动设置
callback - Function: 可选,该回调函数触发时,其第二给参数为事件对象,第一个参数为错误对象
EventEmitter: 事件发生器,声明有以下事件:
"data" 返回 Object: 接收到新的事件时触发,参数为事件对象
"changed" 返回 Object: 当事件从区块链上移除时触发,该事件对象将被添加额外的属性"removed: true"
"error" 返回 Object: 当发生错误时触发
上述的例子中就是使用呢的发生器中的data事件。