diff options
author | Chris Ward <chriswhward@gmail.com> | 2018-09-12 20:49:48 +0800 |
---|---|---|
committer | Chris Ward <chriswhward@gmail.com> | 2018-10-05 17:25:48 +0800 |
commit | 973d91ec894a5438597855ffb9e53f0a20c18696 (patch) | |
tree | a6d0e8826301e680a4549509fc37f8dd85c5b2d6 /docs/contracts.rst | |
parent | c07e5f0b163418bcb1e851a4d9f343e956095aef (diff) | |
download | dexon-solidity-973d91ec894a5438597855ffb9e53f0a20c18696.tar.gz dexon-solidity-973d91ec894a5438597855ffb9e53f0a20c18696.tar.zst dexon-solidity-973d91ec894a5438597855ffb9e53f0a20c18696.zip |
Update docs on event data and logs
Updates from comments
Clarify code comments and add an event output example
Clarification from review
Updated with information from @gumb0
Add clarifier
Updates from review
Remove link
Update example code
Diffstat (limited to 'docs/contracts.rst')
-rw-r--r-- | docs/contracts.rst | 103 |
1 files changed, 70 insertions, 33 deletions
diff --git a/docs/contracts.rst b/docs/contracts.rst index be89727d..95967975 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -756,39 +756,60 @@ converted to ``uint8``. Events ****** -Events allow the convenient usage of the EVM logging facilities, -which in turn can be used to "call" JavaScript callbacks in the user interface -of a dapp, which listen for these events. +Solidity events give an abstraction on top of the EVM's logging functionality. +Applications can subscribe and listen to these events through the RPC interface of an Ethereum client. -Events are -inheritable members of contracts. When they are called, they cause the +Events are inheritable members of contracts. When you call them, they cause the arguments to be stored in the transaction's log - a special data structure -in the blockchain. These logs are associated with the address of -the contract and will be incorporated into the blockchain -and stay there as long as a block is accessible (forever as of -Frontier and Homestead, but this might change with Serenity). Log and -event data is not accessible from within contracts (not even from -the contract that created them). - -"Simple payment verification" (SPV) proofs for logs are possible, so if an external entity supplies -a contract with such a proof, it can check that the log actually -exists inside the blockchain. Be aware that block headers have to be supplied because -the contract can only see the last 256 block hashes. - -Up to three parameters can -receive the attribute ``indexed`` which will cause the respective arguments -to be stored in a special data structure as so-called "topics", which allows them to be searched for, -for example when filtering a sequence of blocks for certain events. Events can always -be filtered by the address of the contract that emitted the event. Also, -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 -not possible to filter for specific anonymous events by name. +in the blockchain. These logs are associated with the address of the contract, +are incorporated into the blockchain, and stay there as long as a block is +accessible (forever as of the Frontier and Homestead releases, but this might +change with Serenity). The Log and its event data is not accessible from within +contracts (not even from the contract that created them). + +It is possible to request a simple payment verification (SPV) for logs, so if +an external entity supplies a contract with such a verification, it can check +that the log actually exists inside the blockchain. You have to supply block headers +because the contract can only see the last 256 block hashes. + +You can add the attribute ``indexed`` to up to three parameters which adds them +to a special data structure known as :ref:`"topics" <abi_events>` instead of +the data part of the log. If you use arrays (including ``string`` and ``bytes``) +as indexed arguments, its Keccak-256 hash is stored as a topic instead, this is +because a topic can only hold a single word (32 bytes). + +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) { + }); -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. +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. :: @@ -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 event.watch(function(error, result){ - // result will contain various information - // including the arguments given to the `Deposit` - // call. + // result contains non-indexed arguments and topics + // given to the `Deposit` call. if (!error) console.log(result); }); + // Or pass a callback to start watching immediately var event = clientReceipt.Deposit(function(error, result) { if (!error) 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 Low-Level Interface to Logs |