什么是Evnet事件
事件是以太坊虚拟机(EVM)日志基础设施提供的一个接口,事件可以用来做操作记录,存储为日志。如果监听了某事件,当事件发生时,会进行回调。当定义的事件触发时,我们可以将事件存储到EVM的交易的日志中(日志是区块链上的一种特殊数据结构)。日志是与合约地址关联的,并存储在区块链中。
注意:
区块链上的交易往往会有日志记录,日志代表着智能合约所触发的事件。
不能直接访问日志和事件数据,即使是创建日志的合约。
在Solidity中,使用event
关键字来定义一个事件。
event EventName(address bidder, uint amount);
事件在合约中可以被继承。触发一个事件使用emit
(之前的版本里并不需要使用emit)
emit EventName(msg.sender, msg.value);
触发事件的调用
function testEvent() public {
// 触发一个事件
emit EventName(msg.sender, msg.value);
}
监听事件
在Web3.js与智能合约交互中,可以通过Event
来实现一些交互功能。
接下来一起来看看在之前web3的代码中,加入Event
,并触发事件
在之前的合约中添加了一个Event事件
pragma solidity ^0.4.21;
contract InfoContract {
string fName;
uint age;
event Instructor(
string name,
uint age
);
function setInfo(string _fName, uint _age) public {
fName = _fName;
age = _age;
}
function getInfo() public constant returns (string, uint) {
return (fName, age);
}
}
然后修改setInfo函数,触发Instructor事件
function setInfo(string _fName, uint _age) public {
fName = _fName;
age = _age;
emit Instructor(_fName, _age);
}
当调用setInfo函数,函数时触发Instructor事件。
现在通过Web3.js监听事件,刷新UI。
<script>
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));
}
web3.eth.defaultAccount = web3.eth.accounts[0];
var infoContract = web3.eth.contract(ABI INFO);
var info = infoContract.at('CONTRACT ADDRESS');
info.getInfo(function(error, result){
if(!error)
{
$("#info").html(result[0]+' ('+result[1]+' years old)');
console.log(result);
}
else
console.error(error);
});
$("#button").click(function() {
info.setInfo($("#name").val(), $("#age").val());
});
</script>
现在,我们改一下代码,通过监听事件获取信息,所以不需要info.getInfo()
来获取信息了
var instructorEvent = info.Instructor();
instructorEvent.watch(function(error, result) {
if (!error)
{
$("#info").html(result.args.name + ' (' + result.args.age + ' years old)');
} else {
console.log(error);
}
});
这样修改以后,就可以刷新UI了。
https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-events