diff options
-rw-r--r-- | docs/contracts.rst | 162 | ||||
-rw-r--r-- | docs/contracts/events.rst | 161 |
2 files changed, 162 insertions, 161 deletions
diff --git a/docs/contracts.rst b/docs/contracts.rst index ee93f7b6..c2270479 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -529,167 +529,7 @@ Calling ``f(50)`` would create a type error since ``50`` can be implicitly conve and ``uint256`` types. On another hand ``f(256)`` would resolve to ``f(uint256)`` overload as ``256`` cannot be implicitly converted to ``uint8``. -.. index:: ! event - -.. _events: - -****** -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 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, -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) { - }); - - -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. - -:: - - pragma solidity >=0.4.21 <0.6.0; - - contract ClientReceipt { - event Deposit( - address indexed _from, - bytes32 indexed _id, - uint _value - ); - - function deposit(bytes32 _id) public payable { - // Events are emitted using `emit`, followed by - // the name of the event and the arguments - // (if any) in parentheses. Any such invocation - // (even deeply nested) can be detected from - // the JavaScript API by filtering for `Deposit`. - emit Deposit(msg.sender, _id, msg.value); - } - } - -The use in the JavaScript API is as follows: - -:: - - var abi = /* abi as generated by the compiler */; - var ClientReceipt = web3.eth.contract(abi); - var clientReceipt = ClientReceipt.at("0x1234...ab67" /* address */); - - var event = clientReceipt.Deposit(); - - // watch for changes - event.watch(function(error, result){ - // 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 -=========================== - -It is also possible to access the low-level interface to the logging -mechanism via the functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4``. -``logi`` takes ``i + 1`` parameter of type ``bytes32``, where the first -argument will be used for the data part of the log and the others -as topics. The event call above can be performed in the same way as - -:: - - pragma solidity >=0.4.10 <0.6.0; - - contract C { - function f() public payable { - uint256 _id = 0x420042; - log3( - bytes32(msg.value), - bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20), - bytes32(uint256(msg.sender)), - bytes32(_id) - ); - } - } - -where the long hexadecimal number is equal to -``keccak256("Deposit(address,bytes32,uint256)")``, the signature of the event. - -Additional Resources for Understanding Events -============================================== - -- `Javascript documentation <https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-events>`_ -- `Example usage of events <https://github.com/debris/smart-exchange/blob/master/lib/contracts/SmartExchange.sol>`_ -- `How to access them in js <https://github.com/debris/smart-exchange/blob/master/lib/exchange_transactions.js>`_ +.. include:: contracts/events.rst .. include:: contracts/inheritance.rst diff --git a/docs/contracts/events.rst b/docs/contracts/events.rst new file mode 100644 index 00000000..ecb0a87f --- /dev/null +++ b/docs/contracts/events.rst @@ -0,0 +1,161 @@ +.. index:: ! event + +.. _events: + +****** +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 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, +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) { + }); + + +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. + +:: + + pragma solidity >=0.4.21 <0.6.0; + + contract ClientReceipt { + event Deposit( + address indexed _from, + bytes32 indexed _id, + uint _value + ); + + function deposit(bytes32 _id) public payable { + // Events are emitted using `emit`, followed by + // the name of the event and the arguments + // (if any) in parentheses. Any such invocation + // (even deeply nested) can be detected from + // the JavaScript API by filtering for `Deposit`. + emit Deposit(msg.sender, _id, msg.value); + } + } + +The use in the JavaScript API is as follows: + +:: + + var abi = /* abi as generated by the compiler */; + var ClientReceipt = web3.eth.contract(abi); + var clientReceipt = ClientReceipt.at("0x1234...ab67" /* address */); + + var event = clientReceipt.Deposit(); + + // watch for changes + event.watch(function(error, result){ + // 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 +=========================== + +It is also possible to access the low-level interface to the logging +mechanism via the functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4``. +``logi`` takes ``i + 1`` parameter of type ``bytes32``, where the first +argument will be used for the data part of the log and the others +as topics. The event call above can be performed in the same way as + +:: + + pragma solidity >=0.4.10 <0.6.0; + + contract C { + function f() public payable { + uint256 _id = 0x420042; + log3( + bytes32(msg.value), + bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20), + bytes32(uint256(msg.sender)), + bytes32(_id) + ); + } + } + +where the long hexadecimal number is equal to +``keccak256("Deposit(address,bytes32,uint256)")``, the signature of the event. + +Additional Resources for Understanding Events +============================================== + +- `Javascript documentation <https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-events>`_ +- `Example usage of events <https://github.com/debris/smart-exchange/blob/master/lib/contracts/SmartExchange.sol>`_ +- `How to access them in js <https://github.com/debris/smart-exchange/blob/master/lib/exchange_transactions.js>`_ |