Merge pull request #4952 from ethereum/docs-544-event-data

Clarifying docs on event storage
This commit is contained in:
chriseth 2018-10-05 14:44:39 +02:00 committed by GitHub
commit 44c1293aa7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 32 deletions

View File

@ -405,6 +405,8 @@ Offset ``f`` points to the start of the content of the array ``[[1, 2], [3]]`` w
Offset ``g`` points to the start of the content of the array ``["one", "two", "three"]`` which is line 10 (320 bytes); thus ``g = 0x0000000000000000000000000000000000000000000000000000000000000140``. Offset ``g`` points to the start of the content of the array ``["one", "two", "three"]`` which is line 10 (320 bytes); thus ``g = 0x0000000000000000000000000000000000000000000000000000000000000140``.
.. _abi_events:
Events Events
====== ======

View File

@ -756,40 +756,61 @@ converted to ``uint8``.
Events Events
****** ******
Events allow the convenient usage of the EVM logging facilities, Solidity events give an abstraction on top of the EVM's logging functionality.
which in turn can be used to "call" JavaScript callbacks in the user interface Applications can subscribe and listen to these events through the RPC interface of an Ethereum client.
of a dapp, which listen for these events.
Events are Events are inheritable members of contracts. When you call them, they cause the
inheritable members of contracts. When they are called, they cause the
arguments to be stored in the transaction's log - a special data structure arguments to be stored in the transaction's log - a special data structure
in the blockchain. These logs are associated with the address of in the blockchain. These logs are associated with the address of the contract,
the contract and will be incorporated into the blockchain are incorporated into the blockchain, and stay there as long as a block is
and stay there as long as a block is accessible (forever as of accessible (forever as of the Frontier and Homestead releases, but this might
Frontier and Homestead, but this might change with Serenity). Log and change with Serenity). The Log and its event data is not accessible from within
event data is not accessible from within contracts (not even from contracts (not even from the contract that created them).
the contract that created them).
"Simple payment verification" (SPV) proofs for logs are possible, so if an external entity supplies It is possible to request a simple payment verification (SPV) for logs, so if
a contract with such a proof, it can check that the log actually an external entity supplies a contract with such a verification, it can check
exists inside the blockchain. Be aware that block headers have to be supplied because that the log actually exists inside the blockchain. You have to supply block headers
the contract can only see the last 256 block hashes. because the contract can only see the last 256 block hashes.
Up to three parameters can You can add the attribute ``indexed`` to up to three parameters which adds them
receive the attribute ``indexed`` which will cause the respective arguments to a special data structure known as :ref:`"topics" <abi_events>` instead of
to be stored in a special data structure as so-called "topics", which allows them to be searched for, the data part of the log. If you use arrays (including ``string`` and ``bytes``)
for example when filtering a sequence of blocks for certain events. Events can always as indexed arguments, its Keccak-256 hash is stored as a topic instead, this is
be filtered by the address of the contract that emitted the event. Also, because a topic can only hold a single word (32 bytes).
the hash of the signature of the event is one of the topics except if you
declared the event with ``anonymous`` specifier. This means that it is All parameters without the ``indexed`` attribute are :ref:`ABI-encoded <ABI>`
into the data part of the log.
Topics allow you to search for events, for example when filtering a sequence of
blocks for certain events. You can also filter events by the address of the
contract that emitted the event.
For example, the code below uses the web3.js ``subscribe(“logs”)``
`method <https://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html#subscribe-logs>`_ to filter
logs that match a topic with a certain address value:
.. code-block:: javascript
var options = {
fromBlock: 0,
address: web3.eth.defaultAccount,
topics: ["0x0000000000000000000000000000000000000000000000000000000000000000", null, null]
};
web3.eth.subscribe('logs', options, function (error, result) {
if (!error)
console.log(result);
})
.on("data", function (log) {
console.log(log);
})
.on("changed", function (log) {
});
The hash of the signature of the event is one of the topics, except if you
declared the event with the ``anonymous`` specifier. This means that it is
not possible to filter for specific anonymous events by name. not possible to filter for specific anonymous events by name.
If arrays (including ``string`` and ``bytes``) are used as indexed arguments, the
Keccak-256 hash of it is stored as topic instead. This is because a topic
can only hold a single word (32 bytes).
All non-indexed arguments will be :ref:`ABI-encoded <ABI>` into the data part of the log.
:: ::
pragma solidity >=0.4.21 <0.6.0; pragma solidity >=0.4.21 <0.6.0;
@ -811,7 +832,7 @@ All non-indexed arguments will be :ref:`ABI-encoded <ABI>` into the data part of
} }
} }
The use in the JavaScript API would be as follows: The use in the JavaScript API is as follows:
:: ::
@ -823,19 +844,35 @@ The use in the JavaScript API would be as follows:
// watch for changes // watch for changes
event.watch(function(error, result){ event.watch(function(error, result){
// result will contain various information // result contains non-indexed arguments and topics
// including the arguments given to the `Deposit` // given to the `Deposit` call.
// call.
if (!error) if (!error)
console.log(result); console.log(result);
}); });
// Or pass a callback to start watching immediately // Or pass a callback to start watching immediately
var event = clientReceipt.Deposit(function(error, result) { var event = clientReceipt.Deposit(function(error, result) {
if (!error) if (!error)
console.log(result); console.log(result);
}); });
The output of the above looks like the following (trimmed):
.. code-block:: json
{
"returnValues": {
"_from": "0x1111…FFFFCCCC",
"_id": "0x50…sd5adb20",
"_value": "0x420042"
},
"raw": {
"data": "0x7f…91385",
"topics": ["0xfd4…b4ead7", "0x7f…1a91385"]
}
}
.. index:: ! log .. index:: ! log
Low-Level Interface to Logs Low-Level Interface to Logs