Solidity事件在DApp中的应用和使用方法

Solidity事件InDApp中的应用和使用方法

电报联系方式

当谈到Solidity时,通常涉及到以太坊智能合约编程语言。如果你对以太坊和智能合约不太熟悉,那么简单来说,以太坊是一种基于区块链技术的去中心化平台,而智能合约是在以太坊上运行的自动化合同代码。Solidity是一种用于编写智能合约的编程语言,类似于其他编程语言,但专门设计用于创建区块链上的去中心化应用程序和合同。

What is事件Evnet

当在以太坊虚拟机(EVM)上执行智能合约时,这些合约可以通过发送事件来记录重要信息。事件是一种特殊的操作,它可以将合约执行中的特定数据存储到交易的日志中。然后,这些日志与合约的地址相关联,并保存到区块链中。

区块链由一系列交易构成,这些交易被打包成块,并按顺序连接在一起,形成一个不断增长的链条。每个交易都包含了一种称为”收据”的结构,这个收据可以包含零个或多个日志记录。这些日志记录代表着智能合约执行期间发生的事件,它们可以包含有关合约操作的重要信息。这些事件日志被永久记录在区块链上,任何人都可以查看它们,以了解合约的状态变化和活动。这种方式有助于实现透明性和可审计性,因为合约操作的历史不可篡改,并且可以被验证。

在DAPP的应用中,如果监听了某事件,当事件发生时,会进行回调。

日志和事件在合约内是无法被访问的,即使是创建日志的合约。

在Solidity 代码中,使用event 关键字来定义一个事件,如:

event EventName(address bidder, uint amount);

这个用法和定义函数式一样的,并且事件在合约中同样可以被继承。触发一个事件使用emit

emit EventName(msg.sender, msg.value);

触发事件可以在任何函数中调用,如:

function testEvent() public {

// 触发一个事件
emit EventName(msg.sender, msg.value);
}

监听事件

如果在点击了”Updata Info”按钮后,虽然成功调用了智能合约,但是界面上没有立刻反映出来更新的情况,你可以通过使用事件监听来解决这个问题。事件监听允许你在智能合约触发了特定事件时,实时捕捉到这些事件,并在界面上进行相应的更新,从而提供更及时的用户反馈和状态显示。这样,用户就可以立刻看到操作的结果,而不必等待交易被确认。

修改合约,定义事件及触发事件

回顾一下合约代码:

pragma solidity ^0.4.21;

contract InfoContract {

string fName;
uint age;

function setInfo(string _fName, uint _age) public {
fName = _fName;
age = _age;
}

function getInfo() public constant returns (string, uint) {
return (fName, age);
}
}

首先,需要定义一个事件:

event Instructor(
string name,
uint age
);

这个事件中,会接受两个参数:name 和 age , 也就是需要跟踪的两个信息。

然后,需要在setInfo函数中,触发Instructor事件,如:

function setInfo(string _fName, uint _age) public {
fName = _fName;
age = _age;
emit Instructor(_fName, _age);
}

在Web3与智能合约交互实战, 点击”Updata Info”按钮之后,会调用setInfo函数,函数时触发Instructor事件。

UsingWeb3监听事件,刷新UI

现在需要使用Web3监听事件,刷新UI。
先回顾下之前的使用Web3和智能合约交互的代码:

<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();

然后使用**.watch()**方法来添加一个回调函数:

instructorEvent.watch(function(error, result) {
if (!error)
{
$(“#info”).html(result.args.name + ‘ (‘ + result.args.age + ‘ years old)’);
} else {
console.log(error);
}
});

代码更新之后,可以在浏览器查看效果

事件高级用法-过滤器

有时我们会有这样的需求:获取当前所有姓名及年龄记录,应该如何做呢?
实际上事件支持过滤器,可以从所有的区块中过滤出符合要求的事件,如:

var instructorEvent = info.Instructor({}, {fromBlock: 0, toBlock: ‘latest’});

或者是,要过滤出年龄28岁的记录,可以这样:

var instructorEvent = info.Instructor({ ‘age’: 28});

比如,我们要获取到代币合约中,所有的转账记录, 就可以使用:

var transferEvent = token.Transfer({}, {fromBlock: 0, toBlock: ‘latest’})
var transferEvent.watch(function(error, result){
// handle result.args.from result.args.to
});

开发联系:DEXDAO

 

© 版权声明

Related posts

No comments

No comments...