以太坊中的事件(Events)和日志(Logs)是个特别让人困惑的概念,本文帮大家梳理。
This is a particularly confusing concept: #xff08; Events) and Log & #xff08; Logs& #xff09; #xff09; #xff0c; this paper helps you sort it out.
首先,以太坊中的Events和Logs基本上算是同一个概念。Solidity和web3.js中称为Events,以太坊黄皮书中称为Logs。你可以理解为:以太坊通过Logs实现Events(事件)功能。智能合约代码通过LOG opcode将日志写入区块链中。
First of all, xff0c; Events and Logs are basically the same concept in the Tails. Events and Web3.js are called Events, Logs are called in the Taiku Yellow Book. You can understand it as xff1a; Events( Events) Functions. Smart contract codes write logs into block chains through Log opcode.
日志内容位于区块链的什么地方?
Where the contents of the log are located in the block chain
日志内容是交易收据(Transaction Receipts)的一部分,整个日志内容,包括Receipts的其它内容会生成一个ReceiptsRoot存储在区块的头部。而完整数据则是链下存储。
The log contents are transaction receipts & #xff08; Transaction Receipts) part & #xff0c; whole log content & #xff0c; including other elements of Receipts will generate a ReceiptsRoot stored at the head of the block. The complete data is stored below the chain.
事件和日志的主要用途有三种:
- 帮助用户客户端(web3.js)读取智能合约的返回值;
- 智能合约异步通知用户客户端(web3.js);
- 用于智能合约的存储(比Storage便宜得多); 下面我们逐个解释:
1.帮助用户客户端(web3.js)读取智能合约的返回值:
1. Help client & #xff08; web3.js) read the return value of the smart contract xff1a;
假设下面的智能合约:
Assuming a smart contract below #xff1a;
contract ExampleContract {
// some state variables ...
function foo(int256 _value) returns (int256) {
// manipulate state ...
return _value;
}
}
我们可以通过web3.js的message call功能模拟调用智能合约:
/ some state certificates...
fun action foo(int256 _value) returns(int256)
return _ value;
we can simulate smart contracts by using web3.j's message call function #xff1a;
var returnValue = exampleContract.foo.call(2);
console.log(returnValue) // 2
但是在真实的环境中我们需要发送交易(Transaction)来调用某个智能合约。这时我们将无法获得智能合约的返回值。因为该交易当前只是被发送,离被打包、执行还有一段时间。此时调用的返回值只是该交易的txid或称为tx hash值。
var return Value & #61; exampleContract.foo.call (2);
consolole.log (returnValue) / / 2
, but in a real environment we need to send a transaction xff08; Transport & #xff09; to call a smart contract. We will not be able to get the return value of the smart contract. This is because the transaction is currently sent xff0c; there is still time before it is packed or executed. At this point, the return value is merely the txid or txhash value of the transaction.
var returnValue = exampleContract.foo.sendTransaction(2, {from: web3.eth.coinbase});
console.log(returnValue) // transaction hash
这时事件(Events)就登场了:
var return Value & #61; exampleContract.foo.sendTransation (2 {from: web3.eth.coinbase});
console.log(return Value)//transaction hash
#xff08; Events) xff1a;
//以下是solidity智能合约代码
contract ExampleContract {
event ReturnValue(address indexed _from, int256 _value);
function foo(int256 _value) returns (int256) {
ReturnValue(msg.sender, _value);
return _value;
}
}
/The following are the smart contract codes of solidity
contract ExampleContract {br/> event ReturnValue (address indexed _from, int256 _value);
funning foo (int256 _value) returns (int256) {br > ReturnValue (msg.sender, _value);
return _value;
return _value;
> br > br
//以下是web3.js用户客户端代码
var exampleEvent = exampleContract.ReturnValue({_from: web3.eth.coinbase});
exampleEvent.watch(function(err, result) {
if (err) {
console.log(err)
return;
}
console.log(result.args._value)
// check that result.args._from is web3.eth.coinbase then
// display result.args._value in the UI and call
// exampleEvent.stopWatching()
})
exampleContract.foo.sendTransaction(2, {from: web3.eth.coinbase})
当交易被打包时,web3.js中的callback就会被调用,这时web3.js就可以得到交易中的智能合约调用的返回值了。
/The following are web3.js user client codes
exempleEvent & #61; exampleContract.ReturnValue ({from: web3.eth.coinbase});
exampleEvent.watch (function (err, result)
if (errr) exempleevent
consolelog(errr)
return;
> consolelog (result.arg._value)
至于为什么交易打包,web3中的callback就被调用那是另一个问题了,简单解释如下。web3会和以太坊某个节点相连,当该节点得知某个交易进block后,会通知相连的web3相关信息。
As to why the transaction is packaged & #xff0c; the callback in web3 is called that is another question & #xff0c; the following is a simple explanation. Web3 will be connected to a node in Taipan & #xff0c; when that node becomes aware of a transaction & #xff0c; it will notify the connected web3 information.
2.智能合约异步通知用户客户端(web3.js):
2. Smart contract astride informs user client & #xff08; web3.js) & #xff1a;
上面例子是智能合约通知用户客户端的典型例子,但还有更多的异步调用可以通过类似的方式实现,从而实现了智能合约异步调用用户客户端的能力。
The above example is a typical example of an intelligent contract notifying user client & #xff0c; however, there are many more agglomerations that can be achieved in a similar way & #xff0c; thus the ability of an intelligent contract to use a user client is realized.
注:智能合约通常用solidity编写,运行在以太坊节点上(EVM)。
注:用户客户端通常用web3.js编写,运行在web服务器上,web3.js跟某个以太坊节点相连。
Note & #xff1a; Smart contracts are usually written in solidity & #xff0c; running at ( EVM)
NOTE & #xff1a; user clients usually write & #xff0c in web3.js; running on web servers & #xff0c; web3.js is connected to a typhus node.
3.用于智能合约的存储(比Storage便宜得多):
3. Storage for smart contracts xff08; much cheaper than Storage xff09;xff1a;
相比智能合约账户的Storage,用日志的方式存储一些信息会便宜很多。Storage中大致的价格是:每32字节(256位)存储需要消耗20,000气(Gas)。而日志大致是每字节8气(Gas)。
The approximate price in Storage is & #xff1a; every 32 bits & #xff08; 256 bits #xff09; storage requires 20,000 gas & #xff08; Gas& #xff09; logs are roughly 8 gas & #xff08; Gas #xff09;
下面看一个例子:
Here's an example of #xff1a;
//solidity智能合约代码,模拟用户存款功能
contract CryptoExchange {
event Deposit(uint256 indexed?market, address indexed _sender, uint256 _amount, uint256 _time);
function deposit(uint256 _amount, uint256 _market) returns (int256) {
// perform deposit, update user’s balance, etc
Deposit(market, msg.sender, _amount, now);
}
/ /solidity smart contract code & #xff0c; simulation user deposit function
compt CryptoExchange {br / > event Deposit (uint256 indexed? mark, address indexed _ Sender, uint256 _amount, uint256 _time);
function deposit (uint256 _amount, uint256 _mark) returns (int256)
Deposit ( market, msg.sender, _mount, now);
> > > ;
//当某户调用智能合约存了某笔款后, 智能合约需要主动通知用户客户端更新相应信息。
//以下是web3.js代码:
var depositEvent = cryptoExContract.Deposit({_sender: userAddress});
depositEvent.watch(function(err, result) {
if (err) {
console.log(err)
return;
}
// append details of result.args to UI
})
//通过增加fromBlock参数指定关注的区块范围
var depositEventAll = cryptoExContract.Deposit({_sender: userAddress}, {fromBlock: 0, toBlock: 'latest'});
depositEventAll.watch(function(err, result) {
if (err) {
console.log(err)
return;
}
// append details of result.args to UI
//如果不想再被通知可以调用:
//depositEventAll.stopWatching();
})
//注:indexed关键字表示按该字段索引日志,以提高查询效率。
/ When a smart contract is deposited, xff0c;
Smart contract needs to proactively notify the user client to update the corresponding information. /
deposit.Deposit(deposit_sent: userAddress} );
< < {rrrrrr. > > > ;
注册有任何问题请添加 微信:MVIP619 拉你进入群
打开微信扫一扫
添加客服
进入交流群
发表评论