mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
commit
c084f6462d
@ -13,7 +13,8 @@ The Contract Application Binary Interface (ABI) is the standard way to interact
|
|||||||
from outside the blockchain and for contract-to-contract interaction. Data is encoded according to its type,
|
from outside the blockchain and for contract-to-contract interaction. Data is encoded according to its type,
|
||||||
as described in this specification. The encoding is not self describing and thus requires a schema in order to decode.
|
as described in this specification. The encoding is not self describing and thus requires a schema in order to decode.
|
||||||
|
|
||||||
We assume the interface functions of a contract are strongly typed, known at compilation time and static. We assume that all contracts will have the interface definitions of any contracts they call available at compile-time.
|
We assume the interface functions of a contract are strongly typed, known at compilation time and static.
|
||||||
|
We assume that all contracts will have the interface definitions of any contracts they call available at compile-time.
|
||||||
|
|
||||||
This specification does not address contracts whose interface is dynamic or otherwise known only at run-time.
|
This specification does not address contracts whose interface is dynamic or otherwise known only at run-time.
|
||||||
|
|
||||||
@ -23,17 +24,24 @@ Function Selector
|
|||||||
=================
|
=================
|
||||||
|
|
||||||
The first four bytes of the call data for a function call specifies the function to be called. It is the
|
The first four bytes of the call data for a function call specifies the function to be called. It is the
|
||||||
first (left, high-order in big-endian) four bytes of the Keccak-256 (SHA-3) hash of the signature of the function. The signature is defined as the canonical expression of the basic prototype without data location specifier, i.e.
|
first (left, high-order in big-endian) four bytes of the Keccak-256 (SHA-3) hash of the signature of
|
||||||
the function name with the parenthesised list of parameter types. Parameter types are split by a single comma - no spaces are used.
|
the function. The signature is defined as the canonical expression of the basic prototype without data
|
||||||
|
location specifier, i.e.
|
||||||
|
the function name with the parenthesised list of parameter types. Parameter types are split by a single
|
||||||
|
comma - no spaces are used.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
The return type of a function is not part of this signature. In :ref:`Solidity's function overloading <overload-function>` return types are not considered. The reason is to keep function call resolution context-independent.
|
The return type of a function is not part of this signature. In
|
||||||
|
:ref:`Solidity's function overloading <overload-function>` return types are not considered.
|
||||||
|
The reason is to keep function call resolution context-independent.
|
||||||
The :ref:`JSON description of the ABI<abi_json>` however contains both inputs and outputs.
|
The :ref:`JSON description of the ABI<abi_json>` however contains both inputs and outputs.
|
||||||
|
|
||||||
Argument Encoding
|
Argument Encoding
|
||||||
=================
|
=================
|
||||||
|
|
||||||
Starting from the fifth byte, the encoded arguments follow. This encoding is also used in other places, e.g. the return values and also event arguments are encoded in the same way, without the four bytes specifying the function.
|
Starting from the fifth byte, the encoded arguments follow. This encoding is also used in
|
||||||
|
other places, e.g. the return values and also event arguments are encoded in the same way,
|
||||||
|
without the four bytes specifying the function.
|
||||||
|
|
||||||
Types
|
Types
|
||||||
=====
|
=====
|
||||||
@ -44,17 +52,21 @@ The following elementary types exist:
|
|||||||
|
|
||||||
- ``int<M>``: two's complement signed integer type of ``M`` bits, ``0 < M <= 256``, ``M % 8 == 0``.
|
- ``int<M>``: two's complement signed integer type of ``M`` bits, ``0 < M <= 256``, ``M % 8 == 0``.
|
||||||
|
|
||||||
- ``address``: equivalent to ``uint160``, except for the assumed interpretation and language typing. For computing the function selector, ``address`` is used.
|
- ``address``: equivalent to ``uint160``, except for the assumed interpretation and language typing.
|
||||||
|
For computing the function selector, ``address`` is used.
|
||||||
|
|
||||||
- ``uint``, ``int``: synonyms for ``uint256``, ``int256`` respectively. For computing the function selector, ``uint256`` and ``int256`` have to be used.
|
- ``uint``, ``int``: synonyms for ``uint256``, ``int256`` respectively. For computing the function
|
||||||
|
selector, ``uint256`` and ``int256`` have to be used.
|
||||||
|
|
||||||
- ``bool``: equivalent to ``uint8`` restricted to the values 0 and 1. For computing the function selector, ``bool`` is used.
|
- ``bool``: equivalent to ``uint8`` restricted to the values 0 and 1. For computing the function selector, ``bool`` is used.
|
||||||
|
|
||||||
- ``fixed<M>x<N>``: signed fixed-point decimal number of ``M`` bits, ``8 <= M <= 256``, ``M % 8 ==0``, and ``0 < N <= 80``, which denotes the value ``v`` as ``v / (10 ** N)``.
|
- ``fixed<M>x<N>``: signed fixed-point decimal number of ``M`` bits, ``8 <= M <= 256``,
|
||||||
|
``M % 8 ==0``, and ``0 < N <= 80``, which denotes the value ``v`` as ``v / (10 ** N)``.
|
||||||
|
|
||||||
- ``ufixed<M>x<N>``: unsigned variant of ``fixed<M>x<N>``.
|
- ``ufixed<M>x<N>``: unsigned variant of ``fixed<M>x<N>``.
|
||||||
|
|
||||||
- ``fixed``, ``ufixed``: synonyms for ``fixed128x18``, ``ufixed128x18`` respectively. For computing the function selector, ``fixed128x18`` and ``ufixed128x18`` have to be used.
|
- ``fixed``, ``ufixed``: synonyms for ``fixed128x18``, ``ufixed128x18`` respectively. For
|
||||||
|
computing the function selector, ``fixed128x18`` and ``ufixed128x18`` have to be used.
|
||||||
|
|
||||||
- ``bytes<M>``: binary type of ``M`` bytes, ``0 < M <= 32``.
|
- ``bytes<M>``: binary type of ``M`` bytes, ``0 < M <= 32``.
|
||||||
|
|
||||||
@ -107,15 +119,20 @@ Design Criteria for the Encoding
|
|||||||
|
|
||||||
The encoding is designed to have the following properties, which are especially useful if some arguments are nested arrays:
|
The encoding is designed to have the following properties, which are especially useful if some arguments are nested arrays:
|
||||||
|
|
||||||
1. The number of reads necessary to access a value is at most the depth of the value inside the argument array structure, i.e. four reads are needed to retrieve ``a_i[k][l][r]``. In a previous version of the ABI, the number of reads scaled linearly with the total number of dynamic parameters in the worst case.
|
1. The number of reads necessary to access a value is at most the depth of the value
|
||||||
|
inside the argument array structure, i.e. four reads are needed to retrieve ``a_i[k][l][r]``. In a
|
||||||
|
previous version of the ABI, the number of reads scaled linearly with the total number of dynamic
|
||||||
|
parameters in the worst case.
|
||||||
|
|
||||||
2. The data of a variable or array element is not interleaved with other data and it is relocatable, i.e. it only uses relative "addresses".
|
2. The data of a variable or array element is not interleaved with other data and it is
|
||||||
|
relocatable, i.e. it only uses relative "addresses".
|
||||||
|
|
||||||
|
|
||||||
Formal Specification of the Encoding
|
Formal Specification of the Encoding
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
We distinguish static and dynamic types. Static types are encoded in-place and dynamic types are encoded at a separately allocated location after the current block.
|
We distinguish static and dynamic types. Static types are encoded in-place and dynamic types are
|
||||||
|
encoded at a separately allocated location after the current block.
|
||||||
|
|
||||||
**Definition:** The following types are called "dynamic":
|
**Definition:** The following types are called "dynamic":
|
||||||
|
|
||||||
@ -178,9 +195,12 @@ on the type of ``X`` being
|
|||||||
|
|
||||||
- ``string``:
|
- ``string``:
|
||||||
|
|
||||||
``enc(X) = enc(enc_utf8(X))``, i.e. ``X`` is utf-8 encoded and this value is interpreted as of ``bytes`` type and encoded further. Note that the length used in this subsequent encoding is the number of bytes of the utf-8 encoded string, not its number of characters.
|
``enc(X) = enc(enc_utf8(X))``, i.e. ``X`` is utf-8 encoded and this value is interpreted
|
||||||
|
as of ``bytes`` type and encoded further. Note that the length used in this subsequent
|
||||||
|
encoding is the number of bytes of the utf-8 encoded string, not its number of characters.
|
||||||
|
|
||||||
- ``uint<M>``: ``enc(X)`` is the big-endian encoding of ``X``, padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.
|
- ``uint<M>``: ``enc(X)`` is the big-endian encoding of ``X``, padded on the higher-order
|
||||||
|
(left) side with zero-bytes such that the length is 32 bytes.
|
||||||
- ``address``: as in the ``uint160`` case
|
- ``address``: as in the ``uint160`` case
|
||||||
- ``int<M>``: ``enc(X)`` is the big-endian two's complement encoding of ``X``, padded on the higher-order (left) side with ``0xff`` for negative ``X`` and with zero bytes for positive ``X`` such that the length is 32 bytes.
|
- ``int<M>``: ``enc(X)`` is the big-endian two's complement encoding of ``X``, padded on the higher-order (left) side with ``0xff`` for negative ``X`` and with zero bytes for positive ``X`` such that the length is 32 bytes.
|
||||||
- ``bool``: as in the ``uint8`` case, where ``1`` is used for ``true`` and ``0`` for ``false``
|
- ``bool``: as in the ``uint8`` case, where ``1`` is used for ``true`` and ``0`` for ``false``
|
||||||
@ -222,11 +242,15 @@ Given the contract:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Thus for our ``Foo`` example if we wanted to call ``baz`` with the parameters ``69`` and ``true``, we would pass 68 bytes total, which can be broken down into:
|
Thus for our ``Foo`` example if we wanted to call ``baz`` with the parameters ``69`` and
|
||||||
|
``true``, we would pass 68 bytes total, which can be broken down into:
|
||||||
|
|
||||||
- ``0xcdcd77c0``: the Method ID. This is derived as the first 4 bytes of the Keccak hash of the ASCII form of the signature ``baz(uint32,bool)``.
|
- ``0xcdcd77c0``: the Method ID. This is derived as the first 4 bytes of the Keccak hash of
|
||||||
- ``0x0000000000000000000000000000000000000000000000000000000000000045``: the first parameter, a uint32 value ``69`` padded to 32 bytes
|
the ASCII form of the signature ``baz(uint32,bool)``.
|
||||||
- ``0x0000000000000000000000000000000000000000000000000000000000000001``: the second parameter - boolean ``true``, padded to 32 bytes
|
- ``0x0000000000000000000000000000000000000000000000000000000000000045``: the first parameter,
|
||||||
|
a uint32 value ``69`` padded to 32 bytes
|
||||||
|
- ``0x0000000000000000000000000000000000000000000000000000000000000001``: the second parameter - boolean
|
||||||
|
``true``, padded to 32 bytes
|
||||||
|
|
||||||
In total:
|
In total:
|
||||||
|
|
||||||
@ -234,13 +258,16 @@ In total:
|
|||||||
|
|
||||||
0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001
|
0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001
|
||||||
|
|
||||||
It returns a single ``bool``. If, for example, it were to return ``false``, its output would be the single byte array ``0x0000000000000000000000000000000000000000000000000000000000000000``, a single bool.
|
It returns a single ``bool``. If, for example, it were to return ``false``, its output would be
|
||||||
|
the single byte array ``0x0000000000000000000000000000000000000000000000000000000000000000``, a single bool.
|
||||||
|
|
||||||
If we wanted to call ``bar`` with the argument ``["abc", "def"]``, we would pass 68 bytes total, broken down into:
|
If we wanted to call ``bar`` with the argument ``["abc", "def"]``, we would pass 68 bytes total, broken down into:
|
||||||
|
|
||||||
- ``0xfce353f6``: the Method ID. This is derived from the signature ``bar(bytes3[2])``.
|
- ``0xfce353f6``: the Method ID. This is derived from the signature ``bar(bytes3[2])``.
|
||||||
- ``0x6162630000000000000000000000000000000000000000000000000000000000``: the first part of the first parameter, a ``bytes3`` value ``"abc"`` (left-aligned).
|
- ``0x6162630000000000000000000000000000000000000000000000000000000000``: the first part of the first
|
||||||
- ``0x6465660000000000000000000000000000000000000000000000000000000000``: the second part of the first parameter, a ``bytes3`` value ``"def"`` (left-aligned).
|
parameter, a ``bytes3`` value ``"abc"`` (left-aligned).
|
||||||
|
- ``0x6465660000000000000000000000000000000000000000000000000000000000``: the second part of the first
|
||||||
|
parameter, a ``bytes3`` value ``"def"`` (left-aligned).
|
||||||
|
|
||||||
In total:
|
In total:
|
||||||
|
|
||||||
@ -248,7 +275,8 @@ In total:
|
|||||||
|
|
||||||
0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000
|
0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000
|
||||||
|
|
||||||
If we wanted to call ``sam`` with the arguments ``"dave"``, ``true`` and ``[1,2,3]``, we would pass 292 bytes total, broken down into:
|
If we wanted to call ``sam`` with the arguments ``"dave"``, ``true`` and ``[1,2,3]``, we would
|
||||||
|
pass 292 bytes total, broken down into:
|
||||||
|
|
||||||
- ``0xa5643bf2``: the Method ID. This is derived from the signature ``sam(bytes,bool,uint256[])``. Note that ``uint`` is replaced with its canonical representation ``uint256``.
|
- ``0xa5643bf2``: the Method ID. This is derived from the signature ``sam(bytes,bool,uint256[])``. Note that ``uint`` is replaced with its canonical representation ``uint256``.
|
||||||
- ``0x0000000000000000000000000000000000000000000000000000000000000060``: the location of the data part of the first parameter (dynamic type), measured in bytes from the start of the arguments block. In this case, ``0x60``.
|
- ``0x0000000000000000000000000000000000000000000000000000000000000060``: the location of the data part of the first parameter (dynamic type), measured in bytes from the start of the arguments block. In this case, ``0x60``.
|
||||||
@ -270,10 +298,14 @@ In total:
|
|||||||
Use of Dynamic Types
|
Use of Dynamic Types
|
||||||
====================
|
====================
|
||||||
|
|
||||||
A call to a function with the signature ``f(uint,uint32[],bytes10,bytes)`` with values ``(0x123, [0x456, 0x789], "1234567890", "Hello, world!")`` is encoded in the following way:
|
A call to a function with the signature ``f(uint,uint32[],bytes10,bytes)`` with values
|
||||||
|
``(0x123, [0x456, 0x789], "1234567890", "Hello, world!")`` is encoded in the following way:
|
||||||
|
|
||||||
We take the first four bytes of ``sha3("f(uint256,uint32[],bytes10,bytes)")``, i.e. ``0x8be65246``.
|
We take the first four bytes of ``sha3("f(uint256,uint32[],bytes10,bytes)")``, i.e. ``0x8be65246``.
|
||||||
Then we encode the head parts of all four arguments. For the static types ``uint256`` and ``bytes10``, these are directly the values we want to pass, whereas for the dynamic types ``uint32[]`` and ``bytes``, we use the offset in bytes to the start of their data area, measured from the start of the value encoding (i.e. not counting the first four bytes containing the hash of the function signature). These are:
|
Then we encode the head parts of all four arguments. For the static types ``uint256`` and ``bytes10``,
|
||||||
|
these are directly the values we want to pass, whereas for the dynamic types ``uint32[]`` and ``bytes``,
|
||||||
|
we use the offset in bytes to the start of their data area, measured from the start of the value
|
||||||
|
encoding (i.e. not counting the first four bytes containing the hash of the function signature). These are:
|
||||||
|
|
||||||
- ``0x0000000000000000000000000000000000000000000000000000000000000123`` (``0x123`` padded to 32 bytes)
|
- ``0x0000000000000000000000000000000000000000000000000000000000000123`` (``0x123`` padded to 32 bytes)
|
||||||
- ``0x0000000000000000000000000000000000000000000000000000000000000080`` (offset to start of data part of second parameter, 4*32 bytes, exactly the size of the head part)
|
- ``0x0000000000000000000000000000000000000000000000000000000000000080`` (offset to start of data part of second parameter, 4*32 bytes, exactly the size of the head part)
|
||||||
@ -306,7 +338,8 @@ All together, the encoding is (newline after function selector and each 32-bytes
|
|||||||
000000000000000000000000000000000000000000000000000000000000000d
|
000000000000000000000000000000000000000000000000000000000000000d
|
||||||
48656c6c6f2c20776f726c642100000000000000000000000000000000000000
|
48656c6c6f2c20776f726c642100000000000000000000000000000000000000
|
||||||
|
|
||||||
Let us apply the same principle to encode the data for a function with a signature ``g(uint[][],string[])`` with values ``([[1, 2], [3]], ["one", "two", "three"])`` but start from the most atomic parts of the encoding:
|
Let us apply the same principle to encode the data for a function with a signature ``g(uint[][],string[])``
|
||||||
|
with values ``([[1, 2], [3]], ["one", "two", "three"])`` but start from the most atomic parts of the encoding:
|
||||||
|
|
||||||
First we encode the length and data of the first embedded dynamic array ``[1, 2]`` of the first root array ``[[1, 2], [3]]``:
|
First we encode the length and data of the first embedded dynamic array ``[1, 2]`` of the first root array ``[[1, 2], [3]]``:
|
||||||
|
|
||||||
@ -319,7 +352,9 @@ Then we encode the length and data of the second embedded dynamic array ``[3]``
|
|||||||
- ``0x0000000000000000000000000000000000000000000000000000000000000001`` (number of elements in the second array, 1; the element is ``3``)
|
- ``0x0000000000000000000000000000000000000000000000000000000000000001`` (number of elements in the second array, 1; the element is ``3``)
|
||||||
- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (first element)
|
- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (first element)
|
||||||
|
|
||||||
Then we need to find the offsets ``a`` and ``b`` for their respective dynamic arrays ``[1, 2]`` and ``[3]``. To calculate the offsets we can take a look at the encoded data of the first root array ``[[1, 2], [3]]`` enumerating each line in the encoding:
|
Then we need to find the offsets ``a`` and ``b`` for their respective dynamic arrays ``[1, 2]`` and ``[3]``.
|
||||||
|
To calculate the offsets we can take a look at the encoded data of the first root array ``[[1, 2], [3]]``
|
||||||
|
enumerating each line in the encoding:
|
||||||
|
|
||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
|
|
||||||
@ -331,9 +366,11 @@ Then we need to find the offsets ``a`` and ``b`` for their respective dynamic ar
|
|||||||
5 - 0000000000000000000000000000000000000000000000000000000000000001 - count for [3]
|
5 - 0000000000000000000000000000000000000000000000000000000000000001 - count for [3]
|
||||||
6 - 0000000000000000000000000000000000000000000000000000000000000003 - encoding of 3
|
6 - 0000000000000000000000000000000000000000000000000000000000000003 - encoding of 3
|
||||||
|
|
||||||
Offset ``a`` points to the start of the content of the array ``[1, 2]`` which is line 2 (64 bytes); thus ``a = 0x0000000000000000000000000000000000000000000000000000000000000040``.
|
Offset ``a`` points to the start of the content of the array ``[1, 2]`` which is line
|
||||||
|
2 (64 bytes); thus ``a = 0x0000000000000000000000000000000000000000000000000000000000000040``.
|
||||||
|
|
||||||
Offset ``b`` points to the start of the content of the array ``[3]`` which is line 5 (160 bytes); thus ``b = 0x00000000000000000000000000000000000000000000000000000000000000a0``.
|
Offset ``b`` points to the start of the content of the array ``[3]`` which is line 5 (160 bytes);
|
||||||
|
thus ``b = 0x00000000000000000000000000000000000000000000000000000000000000a0``.
|
||||||
|
|
||||||
|
|
||||||
Then we encode the embedded strings of the second root array:
|
Then we encode the embedded strings of the second root array:
|
||||||
@ -359,14 +396,18 @@ In parallel to the first root array, since strings are dynamic elements we need
|
|||||||
7 - 0000000000000000000000000000000000000000000000000000000000000005 - count for "three"
|
7 - 0000000000000000000000000000000000000000000000000000000000000005 - count for "three"
|
||||||
8 - 7468726565000000000000000000000000000000000000000000000000000000 - encoding of "three"
|
8 - 7468726565000000000000000000000000000000000000000000000000000000 - encoding of "three"
|
||||||
|
|
||||||
Offset ``c`` points to the start of the content of the string ``"one"`` which is line 3 (96 bytes); thus ``c = 0x0000000000000000000000000000000000000000000000000000000000000060``.
|
Offset ``c`` points to the start of the content of the string ``"one"`` which is line 3 (96 bytes);
|
||||||
|
thus ``c = 0x0000000000000000000000000000000000000000000000000000000000000060``.
|
||||||
|
|
||||||
Offset ``d`` points to the start of the content of the string ``"two"`` which is line 5 (160 bytes); thus ``d = 0x00000000000000000000000000000000000000000000000000000000000000a0``.
|
Offset ``d`` points to the start of the content of the string ``"two"`` which is line 5 (160 bytes);
|
||||||
|
thus ``d = 0x00000000000000000000000000000000000000000000000000000000000000a0``.
|
||||||
|
|
||||||
Offset ``e`` points to the start of the content of the string ``"three"`` which is line 7 (224 bytes); thus ``e = 0x00000000000000000000000000000000000000000000000000000000000000e0``.
|
Offset ``e`` points to the start of the content of the string ``"three"`` which is line 7 (224 bytes);
|
||||||
|
thus ``e = 0x00000000000000000000000000000000000000000000000000000000000000e0``.
|
||||||
|
|
||||||
|
|
||||||
Note that the encodings of the embedded elements of the root arrays are not dependent on each other and have the same encodings for a function with a signature ``g(string[],uint[][])``.
|
Note that the encodings of the embedded elements of the root arrays are not dependent on each other
|
||||||
|
and have the same encodings for a function with a signature ``g(string[],uint[][])``.
|
||||||
|
|
||||||
Then we encode the length of the first root array:
|
Then we encode the length of the first root array:
|
||||||
|
|
||||||
@ -376,7 +417,8 @@ Then we encode the length of the second root array:
|
|||||||
|
|
||||||
- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of strings in the second root array, 3; the strings themselves are ``"one"``, ``"two"`` and ``"three"``)
|
- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of strings in the second root array, 3; the strings themselves are ``"one"``, ``"two"`` and ``"three"``)
|
||||||
|
|
||||||
Finally we find the offsets ``f`` and ``g`` for their respective root dynamic arrays ``[[1, 2], [3]]`` and ``["one", "two", "three"]``, and assemble parts in the correct order:
|
Finally we find the offsets ``f`` and ``g`` for their respective root dynamic arrays ``[[1, 2], [3]]`` and
|
||||||
|
``["one", "two", "three"]``, and assemble parts in the correct order:
|
||||||
|
|
||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
|
|
||||||
@ -402,25 +444,36 @@ Finally we find the offsets ``f`` and ``g`` for their respective root dynamic ar
|
|||||||
18 - 0000000000000000000000000000000000000000000000000000000000000005 - count for "three"
|
18 - 0000000000000000000000000000000000000000000000000000000000000005 - count for "three"
|
||||||
19 - 7468726565000000000000000000000000000000000000000000000000000000 - encoding of "three"
|
19 - 7468726565000000000000000000000000000000000000000000000000000000 - encoding of "three"
|
||||||
|
|
||||||
Offset ``f`` points to the start of the content of the array ``[[1, 2], [3]]`` which is line 2 (64 bytes); thus ``f = 0x0000000000000000000000000000000000000000000000000000000000000040``.
|
Offset ``f`` points to the start of the content of the array ``[[1, 2], [3]]`` which is line 2 (64 bytes);
|
||||||
|
thus ``f = 0x0000000000000000000000000000000000000000000000000000000000000040``.
|
||||||
|
|
||||||
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:
|
.. _abi_events:
|
||||||
|
|
||||||
Events
|
Events
|
||||||
======
|
======
|
||||||
|
|
||||||
Events are an abstraction of the Ethereum logging/event-watching protocol. Log entries provide the contract's address, a series of up to four topics and some arbitrary length binary data. Events leverage the existing function ABI in order to interpret this (together with an interface spec) as a properly typed structure.
|
Events are an abstraction of the Ethereum logging/event-watching protocol. Log entries provide the contract's
|
||||||
|
address, a series of up to four topics and some arbitrary length binary data. Events leverage the existing function
|
||||||
|
ABI in order to interpret this (together with an interface spec) as a properly typed structure.
|
||||||
|
|
||||||
Given an event name and series of event parameters, we split them into two sub-series: those which are indexed and those which are not. Those which are indexed, which may number up to 3, are used alongside the Keccak hash of the event signature to form the topics of the log entry. Those which are not indexed form the byte array of the event.
|
Given an event name and series of event parameters, we split them into two sub-series: those which are indexed and
|
||||||
|
those which are not. Those which are indexed, which may number up to 3, are used alongside the Keccak hash of the
|
||||||
|
event signature to form the topics of the log entry. Those which are not indexed form the byte array of the event.
|
||||||
|
|
||||||
In effect, a log entry using this ABI is described as:
|
In effect, a log entry using this ABI is described as:
|
||||||
|
|
||||||
- ``address``: the address of the contract (intrinsically provided by Ethereum);
|
- ``address``: the address of the contract (intrinsically provided by Ethereum);
|
||||||
- ``topics[0]``: ``keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")")`` (``canonical_type_of`` is a function that simply returns the canonical type of a given argument, e.g. for ``uint indexed foo``, it would return ``uint256``). If the event is declared as ``anonymous`` the ``topics[0]`` is not generated;
|
- ``topics[0]``: ``keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")")`` (``canonical_type_of``
|
||||||
- ``topics[n]``: ``abi_encode(EVENT_INDEXED_ARGS[n - 1])`` (``EVENT_INDEXED_ARGS`` is the series of ``EVENT_ARGS`` that are indexed);
|
is a function that simply returns the canonical type of a given argument, e.g. for ``uint indexed foo``, it would
|
||||||
- ``data``: ABI encoding of ``EVENT_NON_INDEXED_ARGS`` (``EVENT_NON_INDEXED_ARGS`` is the series of ``EVENT_ARGS`` that are not indexed, ``abi_encode`` is the ABI encoding function used for returning a series of typed values from a function, as described above).
|
return ``uint256``). If the event is declared as ``anonymous`` the ``topics[0]`` is not generated;
|
||||||
|
- ``topics[n]``: ``abi_encode(EVENT_INDEXED_ARGS[n - 1])`` (``EVENT_INDEXED_ARGS`` is the series of ``EVENT_ARGS``
|
||||||
|
that are indexed);
|
||||||
|
- ``data``: ABI encoding of ``EVENT_NON_INDEXED_ARGS`` (``EVENT_NON_INDEXED_ARGS`` is the series of ``EVENT_ARGS``
|
||||||
|
that are not indexed, ``abi_encode`` is the ABI encoding function used for returning a series of typed values
|
||||||
|
from a function, as described above).
|
||||||
|
|
||||||
For all types of length at most 32 bytes, the ``EVENT_INDEXED_ARGS`` array contains
|
For all types of length at most 32 bytes, the ``EVENT_INDEXED_ARGS`` array contains
|
||||||
the value directly, padded or sign-extended (for signed integers) to 32 bytes, just as for regular ABI encoding.
|
the value directly, padded or sign-extended (for signed integers) to 32 bytes, just as for regular ABI encoding.
|
||||||
@ -453,7 +506,9 @@ A function description is a JSON object with the fields:
|
|||||||
* ``components``: used for tuple types (more below).
|
* ``components``: used for tuple types (more below).
|
||||||
|
|
||||||
- ``outputs``: an array of objects similar to ``inputs``.
|
- ``outputs``: an array of objects similar to ``inputs``.
|
||||||
- ``stateMutability``: a string with one of the following values: ``pure`` (:ref:`specified to not read blockchain state <pure-functions>`), ``view`` (:ref:`specified to not modify the blockchain state <view-functions>`), ``nonpayable`` (function does not accept Ether) and ``payable`` (function accepts Ether).
|
- ``stateMutability``: a string with one of the following values: ``pure`` (:ref:`specified to not read
|
||||||
|
blockchain state <pure-functions>`), ``view`` (:ref:`specified to not modify the blockchain
|
||||||
|
state <view-functions>`), ``nonpayable`` (function does not accept Ether) and ``payable`` (function accepts Ether).
|
||||||
|
|
||||||
Constructor and fallback function never have ``name`` or ``outputs``. Fallback function doesn't have ``inputs`` either.
|
Constructor and fallback function never have ``name`` or ``outputs``. Fallback function doesn't have ``inputs`` either.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user