events and Logs (Logs) in the etheric square are a particularly confusing concept, and this article helps you to comb through them.
Because of the previous article, we discussed the Ethernet square go-ethereum client query transaction list of some methods, this article, we specifically implement a filter of the discussion. Let's see how this approach is used in particular. Focus on the last part. Hope to play a certain role in helping to develop. We begin with the basic concepts and understand the process as a whole.
First of all, events and logs in the etheric square are basically the same concept. Solidity and Web3.js called events, the ether square Yellow book called the logs. As you can see, the etheric Square realizes events (event) functions through logs. The smart Contract code writes logs to the block chain via log.
(The same is true if the truffle framework is developed, because the truffle framework itself is packaged web3.js)
the contents of the log are located somewhere in the block chain.
The log content is part of the transaction receipt (Transaction receipts), and the entire log content, including receipts's other content, generates a receiptsroot stored in the block's head. And the full data is stored under the chain.
There are four main uses for events and logs:
1. Help the User Client (web3.js) read the return value of the intelligent contract;
2. The intelligent contract notifies the user Client asynchronously (web3.js);
3. Storage for intelligent contracts (much cheaper than storage);
4. I think there is a fourth, can help us filter out the historical transaction data through filter, the concrete implementation of the following article analysis.
Here we explain
1. Help User Client (web3.js) read the return value of the smart contract:
Suppose the following intelligent contract:
Contract Examplecontract {
//Some state variables ...
function foo (int256 _value) returns (int256) {
//manipulate state ...
return _value
}
}
We can simulate the invocation of a smart contract via the Web3.js message call function:
var returnvalue = ExampleContract.foo.call (2);
Console.log (returnvalue)//2
But in the real world we need to send a transaction (Transaction) to invoke an intelligent contract. At this point we will not be able to get the return value of the smart contract. Because the transaction is currently only being sent, packaged, and executed for some time (the miners ' workload proof is needed). The return value of the call at this time is only the txid of the transaction or the TX hash value.
var returnvalue = exampleContract.foo.sendTransaction (2, {from:web3.eth.coinbase});
Console.log (returnvalue)//Transaction Hash
This is where events go: We tend to write a method on the chain, or a method that lets the data in the chain change. We do this by adding an event to the front of the method.
The following is the solidity intelligent contract Code
contract Examplecontract {
Event returnvalue (address indexed _from, int256 _value);
unction foo (int256 _value) returns (int256) {
returnvalue (Msg.sender, _value);
return _value
}
}
The following is the Web3.js User client code
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})
When the transaction is packaged, the callback in the Web3.js is invoked, and web3.js can then get the return value of the intelligent contract call in the transaction.
As for why the transaction is packaged, the callback in the web3.js is called another question, as explained briefly below. The web3.js will be connected to a node in the ether square, and when the node learns that a transaction is written into block, it notifies the connected node of the information.
2. Intelligent Contract Notification User Client asynchronously (web3.js):
The example above is a typical example of a smart contract notification User Client, but there are more asynchronous calls that can be implemented in a similar way, enabling the intelligent contract to invoke user clients asynchronously.
Note: Intelligent contracts are usually written in solidity and run on the etheric square node (EVM).
Note: User clients are usually written with Web3.js, running on a Web server, Web3.js connected to an Ethernet square node.
3. Storage for smart contracts (much cheaper than storage):
It is much cheaper to store some information in a journal than the storage of an intelligent contract account. The approximate price in the storage is that 20,000 gas is consumed per 32 byte (256-bit) storage. And the log is roughly 8 gas per byte.
Let's look at an example:
Solidity intelligent Contract Code, analog user deposit function
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);
}
When a user invokes a smart contract to save a sum, the smart contract needs to actively notify the client to update the corresponding information.
4. Help us filter out historical transaction data through filter.
The following method concretely implements the way we begin to pick out historical transaction data from the chain through the filter method.
Here's the Web3.js code:
var depositevent = Cryptoexcontract.deposit ({_sender:useraddress});
Depositevent.watch (function (err, result) {
if [err] {
console.log (err) return
;
}
else{
//Append the details
of the Result.args to UI//writes this transaction to the client repository to facilitate later querying of historical transaction data.
}
})
Query all transaction data by increasing the Fromblock parameter to specify the block range of interest. (Get the historical transaction data stored on the chain, we use the method of scraping chain to obtain, because ETH currently does not provide the API that obtains historical data.)
var depositeventall = cryptoexcontract.deposit ({_sender:useraddress}, {fromblock:0, Toblock: ' latest '});
Depositeventall.watch (function (err, result) {
if [err] {
console.log (err) return
;
}
else{
//append details of Result.args to UI
///If you do not want to be notified again can call:
//depositeventall.stopwatching ();
}
})
Note: The indexed keyword indicates that the log is indexed by the field to improve query efficiency.
December 24, 2017 organized in Shenzhen