mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Changed inline code syntax
Changed from :code:`<inline>` to ``<inline>``
This commit is contained in:
parent
652bb0e8c1
commit
49f5bc7ce9
@ -17,7 +17,7 @@ to read the data, so will everyone else.
|
|||||||
|
|
||||||
You can restrict read access to your contract's state
|
You can restrict read access to your contract's state
|
||||||
by **other contracts**. That is actually the default
|
by **other contracts**. That is actually the default
|
||||||
unless you declare make your state variables :code:`public`.
|
unless you declare make your state variables ``public``.
|
||||||
|
|
||||||
Furthermore, you can restrict who can make modifications
|
Furthermore, you can restrict who can make modifications
|
||||||
to your contract's state or call your contract's
|
to your contract's state or call your contract's
|
||||||
@ -140,11 +140,11 @@ Example
|
|||||||
=======
|
=======
|
||||||
|
|
||||||
In the following example,
|
In the following example,
|
||||||
the modifier :code:`atStage` ensures that the function can
|
the modifier ``atStage`` ensures that the function can
|
||||||
only be called at a certain stage.
|
only be called at a certain stage.
|
||||||
|
|
||||||
Automatic timed transitions
|
Automatic timed transitions
|
||||||
are handled by the modifier :code:`timeTransitions`, which
|
are handled by the modifier ``timeTransitions``, which
|
||||||
should be used for all functions.
|
should be used for all functions.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@ -154,7 +154,7 @@ should be used for all functions.
|
|||||||
it after the latter, so that the new stage is
|
it after the latter, so that the new stage is
|
||||||
taken into account.
|
taken into account.
|
||||||
|
|
||||||
Finally, the modifier :code:`transitionNext` can be used
|
Finally, the modifier ``transitionNext`` can be used
|
||||||
to automatically go to the next stage when the
|
to automatically go to the next stage when the
|
||||||
function finishes.
|
function finishes.
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ Contracts can be created "from outside" or from Solidity contracts.
|
|||||||
When a contract is created, its constructor (a function with the same
|
When a contract is created, its constructor (a function with the same
|
||||||
name as the contract) is executed once.
|
name as the contract) is executed once.
|
||||||
|
|
||||||
From :code:`web3.js`, i.e. the JavaScript
|
From ``web3.js``, i.e. the JavaScript
|
||||||
API, this is done as follows::
|
API, this is done as follows::
|
||||||
|
|
||||||
// The json abi array generated by the compiler
|
// The json abi array generated by the compiler
|
||||||
@ -53,7 +53,7 @@ API, this is done as follows::
|
|||||||
|
|
||||||
Internally, constructor arguments are passed after the code of
|
Internally, constructor arguments are passed after the code of
|
||||||
the contract itself, but you do not have to care about this
|
the contract itself, but you do not have to care about this
|
||||||
if you use :code:`web3.js`.
|
if you use ``web3.js``.
|
||||||
|
|
||||||
If a contract wants to create another contract, the source code
|
If a contract wants to create another contract, the source code
|
||||||
(and the binary) of the created contract has to be known to the creator.
|
(and the binary) of the created contract has to be known to the creator.
|
||||||
@ -143,38 +143,38 @@ a "message call") and external
|
|||||||
ones that do), there are four types of visibilities for
|
ones that do), there are four types of visibilities for
|
||||||
functions and state variables.
|
functions and state variables.
|
||||||
|
|
||||||
Functions can be specified as being :code:`external`,
|
Functions can be specified as being ``external``,
|
||||||
:code:`public`, :code:`internal` or :code:`private`, where the default is
|
``public``, ``internal`` or ``private``, where the default is
|
||||||
:code:`public`. For state variables, :code:`external` is not possible
|
``public``. For state variables, ``external`` is not possible
|
||||||
and the default is :code:`internal`.
|
and the default is ``internal``.
|
||||||
|
|
||||||
:code:`external`:
|
``external``:
|
||||||
External functions are part of the contract
|
External functions are part of the contract
|
||||||
interface, which means they can be called from other contracts and
|
interface, which means they can be called from other contracts and
|
||||||
via transactions. An external function :code:`f` cannot be called
|
via transactions. An external function ``f`` cannot be called
|
||||||
internally (i.e. :code:`f()` does not work, but :code:`this.f()` works).
|
internally (i.e. ``f()`` does not work, but ``this.f()`` works).
|
||||||
External functions are sometimes more efficient when
|
External functions are sometimes more efficient when
|
||||||
they receive large arrays of data.
|
they receive large arrays of data.
|
||||||
|
|
||||||
:code:`public`:
|
``public``:
|
||||||
Public functions are part of the contract
|
Public functions are part of the contract
|
||||||
interface and can be either called internally or via
|
interface and can be either called internally or via
|
||||||
messages. For public state variables, an automatic accessor
|
messages. For public state variables, an automatic accessor
|
||||||
function (see below) is generated.
|
function (see below) is generated.
|
||||||
|
|
||||||
:code:`internal`:
|
``internal``:
|
||||||
Those functions and state variables can only be
|
Those functions and state variables can only be
|
||||||
accessed internally (i.e. from within the current contract
|
accessed internally (i.e. from within the current contract
|
||||||
or contracts deriving from it), without using :code:`this`.
|
or contracts deriving from it), without using ``this``.
|
||||||
|
|
||||||
:code:`private`:
|
``private``:
|
||||||
Private functions and state variables are only
|
Private functions and state variables are only
|
||||||
visible for the contract they are defined in and not in
|
visible for the contract they are defined in and not in
|
||||||
derived contracts.
|
derived contracts.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Everything that is inside a contract is visible to
|
Everything that is inside a contract is visible to
|
||||||
all external observers. Making something :code:`private`
|
all external observers. Making something ``private``
|
||||||
only prevents other contract from accessing and modifying
|
only prevents other contract from accessing and modifying
|
||||||
the information, but it will still be visible to the
|
the information, but it will still be visible to the
|
||||||
whole world outside of the blockchain.
|
whole world outside of the blockchain.
|
||||||
@ -191,9 +191,9 @@ return parameter list for functions.
|
|||||||
uint public data;
|
uint public data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Other contracts can call :code:`c.data()` to retrieve the value of data in state
|
Other contracts can call ``c.data()`` to retrieve the value of data in state
|
||||||
storage, but are not able to call :code:`f`. Contracts derived from :code:`c` can call
|
storage, but are not able to call ``f``. Contracts derived from ``c`` can call
|
||||||
:code:`setData` to alter the value of :code:`data` (but only in their own state).
|
``setData`` to alter the value of ``data`` (but only in their own state).
|
||||||
|
|
||||||
.. index:: ! accessor;function, ! function;accessor
|
.. index:: ! accessor;function, ! function;accessor
|
||||||
|
|
||||||
@ -202,15 +202,15 @@ Accessor Functions
|
|||||||
|
|
||||||
The compiler automatically creates accessor functions for
|
The compiler automatically creates accessor functions for
|
||||||
all public state variables. The contract given below will
|
all public state variables. The contract given below will
|
||||||
have a function called :code:`data` that does not take any
|
have a function called ``data`` that does not take any
|
||||||
arguments and returns a uint, the value of the state
|
arguments and returns a uint, the value of the state
|
||||||
variable :code:`data`. The initialization of state variables can
|
variable ``data``. The initialization of state variables can
|
||||||
be done at declaration.
|
be done at declaration.
|
||||||
|
|
||||||
The accessor functions have external visibility. If the
|
The accessor functions have external visibility. If the
|
||||||
symbol is accessed internally (i.e. without :code:`this.`),
|
symbol is accessed internally (i.e. without ``this.``),
|
||||||
it is a state variable and if it is accessed externally
|
it is a state variable and if it is accessed externally
|
||||||
(i.e. with :code:`this.`), it is a function.
|
(i.e. with ``this.``), it is a function.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -414,15 +414,15 @@ ultimately, also the block headers have to be supplied because
|
|||||||
the contract can only see the last 256 block hashes).
|
the contract can only see the last 256 block hashes).
|
||||||
|
|
||||||
Up to three parameters can
|
Up to three parameters can
|
||||||
receive the attribute :code:`indexed` which will cause the respective arguments
|
receive the attribute ``indexed`` which will cause the respective arguments
|
||||||
to be searched for: It is possible to filter for specific values of
|
to be searched for: It is possible to filter for specific values of
|
||||||
indexed arguments in the user interface.
|
indexed arguments in the user interface.
|
||||||
|
|
||||||
If arrays (including :code:`string` and :code:`bytes`) are used as indexed arguments, the
|
If arrays (including ``string`` and ``bytes``) are used as indexed arguments, the
|
||||||
sha3-hash of it is stored as topic instead.
|
sha3-hash of it is stored as topic instead.
|
||||||
|
|
||||||
The hash of the signature of the event is one of the topics except if you
|
The hash of the signature of the event is one of the topics except if you
|
||||||
declared the event with :code:`anonymous` specifier. This means that it is
|
declared the event with ``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.
|
||||||
|
|
||||||
All non-indexed arguments will be stored in the data part of the log.
|
All non-indexed arguments will be stored in the data part of the log.
|
||||||
@ -475,8 +475,8 @@ Low-Level Interface to Logs
|
|||||||
===========================
|
===========================
|
||||||
|
|
||||||
It is also possible to access the low-level interface to the logging
|
It is also possible to access the low-level interface to the logging
|
||||||
mechanism via the functions :code:`log0`, :code:`log1`, :code:`log2`, :code:`log3` and :code:`log4`.
|
mechanism via the functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4``.
|
||||||
:code:`logi` takes :code:`i + 1` parameter of type :code:`bytes32`, where the first
|
``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
|
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
|
as topics. The event call above can be performed in the same way as
|
||||||
|
|
||||||
@ -490,7 +490,7 @@ as topics. The event call above can be performed in the same way as
|
|||||||
);
|
);
|
||||||
|
|
||||||
where the long hexadecimal number is equal to
|
where the long hexadecimal number is equal to
|
||||||
:code:`sha3("Deposit(address,hash256,uint256)")`, the signature of the event.
|
``sha3("Deposit(address,hash256,uint256)")``, the signature of the event.
|
||||||
|
|
||||||
Additional Resources for Understanding Events
|
Additional Resources for Understanding Events
|
||||||
==============================================
|
==============================================
|
||||||
@ -591,7 +591,7 @@ Details are given in the following example.
|
|||||||
uint info;
|
uint info;
|
||||||
}
|
}
|
||||||
|
|
||||||
Note that above, we call :code:`mortal.kill()` to "forward" the
|
Note that above, we call ``mortal.kill()`` to "forward" the
|
||||||
destruction request. The way this is done is problematic, as
|
destruction request. The way this is done is problematic, as
|
||||||
seen in the following example::
|
seen in the following example::
|
||||||
|
|
||||||
@ -615,10 +615,10 @@ seen in the following example::
|
|||||||
contract Final is Base1, Base2 {
|
contract Final is Base1, Base2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
A call to :code:`Final.kill()` will call :code:`Base2.kill` as the most
|
A call to ``Final.kill()`` will call ``Base2.kill`` as the most
|
||||||
derived override, but this function will bypass
|
derived override, but this function will bypass
|
||||||
:code:`Base1.kill`, basically because it does not even know about
|
``Base1.kill``, basically because it does not even know about
|
||||||
:code:`Base1`. The way around this is to use :code:`super`::
|
``Base1``. The way around this is to use ``super``::
|
||||||
|
|
||||||
contract mortal is owned {
|
contract mortal is owned {
|
||||||
function kill() {
|
function kill() {
|
||||||
@ -640,10 +640,10 @@ derived override, but this function will bypass
|
|||||||
contract Final is Base2, Base1 {
|
contract Final is Base2, Base1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
If :code:`Base1` calls a function of :code:`super`, it does not simply
|
If ``Base1`` calls a function of ``super``, it does not simply
|
||||||
call this function on one of its base contracts, it rather
|
call this function on one of its base contracts, it rather
|
||||||
calls this function on the next base contract in the final
|
calls this function on the next base contract in the final
|
||||||
inheritance graph, so it will call :code:`Base2.kill()` (note that
|
inheritance graph, so it will call ``Base2.kill()`` (note that
|
||||||
the final inheritance sequence is -- starting with the most
|
the final inheritance sequence is -- starting with the most
|
||||||
derived contract: Final, Base1, Base2, mortal, owned).
|
derived contract: Final, Base1, Base2, mortal, owned).
|
||||||
The actual function that is called when using super is
|
The actual function that is called when using super is
|
||||||
@ -670,9 +670,9 @@ the base constructors. This can be done at two places::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Either directly in the inheritance list (:code:`is Base(7)`) or in
|
Either directly in the inheritance list (``is Base(7)``) or in
|
||||||
the way a modifier would be invoked as part of the header of
|
the way a modifier would be invoked as part of the header of
|
||||||
the derived constructor (:code:`Base(_y * _y)`). The first way to
|
the derived constructor (``Base(_y * _y)``). The first way to
|
||||||
do it is more convenient if the constructor argument is a
|
do it is more convenient if the constructor argument is a
|
||||||
constant and defines the behaviour of the contract or
|
constant and defines the behaviour of the contract or
|
||||||
describes it. The second way has to be used if the
|
describes it. The second way has to be used if the
|
||||||
@ -691,7 +691,7 @@ Solidity follows the path of Python and uses "`C3 Linearization <https://en.wiki
|
|||||||
to force a specific order in the DAG of base classes. This
|
to force a specific order in the DAG of base classes. This
|
||||||
results in the desirable property of monotonicity but
|
results in the desirable property of monotonicity but
|
||||||
disallows some inheritance graphs. Especially, the order in
|
disallows some inheritance graphs. Especially, the order in
|
||||||
which the base classes are given in the :code:`is` directive is
|
which the base classes are given in the ``is`` directive is
|
||||||
important. In the following code, Solidity will give the
|
important. In the following code, Solidity will give the
|
||||||
error "Linearization of inheritance graph impossible".
|
error "Linearization of inheritance graph impossible".
|
||||||
|
|
||||||
@ -701,9 +701,9 @@ error "Linearization of inheritance graph impossible".
|
|||||||
contract A is X {}
|
contract A is X {}
|
||||||
contract C is A, X {}
|
contract C is A, X {}
|
||||||
|
|
||||||
The reason for this is that :code:`C` requests :code:`X` to override :code:`A`
|
The reason for this is that ``C`` requests ``X`` to override ``A``
|
||||||
(by specifying :code:`A, X` in this order), but :code:`A` itself
|
(by specifying ``A, X`` in this order), but ``A`` itself
|
||||||
requests to override :code:`X`, which is a contradiction that
|
requests to override ``X``, which is a contradiction that
|
||||||
cannot be resolved.
|
cannot be resolved.
|
||||||
|
|
||||||
A simple rule to remember is to specify the base classes in
|
A simple rule to remember is to specify the base classes in
|
||||||
@ -715,7 +715,7 @@ the order from "most base-like" to "most derived".
|
|||||||
Abstract Contracts
|
Abstract Contracts
|
||||||
******************
|
******************
|
||||||
|
|
||||||
Contract functions can lack an implementation as in the following example (note that the function declaration header is terminated by :code:`;`)::
|
Contract functions can lack an implementation as in the following example (note that the function declaration header is terminated by ``;``)::
|
||||||
|
|
||||||
contract Feline {
|
contract Feline {
|
||||||
function utterance() returns (bytes32);
|
function utterance() returns (bytes32);
|
||||||
@ -738,10 +738,10 @@ Libraries
|
|||||||
************
|
************
|
||||||
|
|
||||||
Libraries are similar to contracts, but their purpose is that they are deployed
|
Libraries are similar to contracts, but their purpose is that they are deployed
|
||||||
only once at a specific address and their code is reused using the :code:`DELEGATECALL`
|
only once at a specific address and their code is reused using the ``DELEGATECALL``
|
||||||
(:code:`CALLCODE` until Homestead)
|
(``CALLCODE`` until Homestead)
|
||||||
feature of the EVM. This means that if library functions are called, their code
|
feature of the EVM. This means that if library functions are called, their code
|
||||||
is executed in the context of the calling contract, i.e. :code:`this` points to the
|
is executed in the context of the calling contract, i.e. ``this`` points to the
|
||||||
calling contract and especially the storage from the calling contract can be
|
calling contract and especially the storage from the calling contract can be
|
||||||
accessed. As a library is an isolated piece of source code, it can only access
|
accessed. As a library is an isolated piece of source code, it can only access
|
||||||
state variables of the calling contract if they are explicitly supplied (it
|
state variables of the calling contract if they are explicitly supplied (it
|
||||||
@ -750,14 +750,14 @@ would have to way to name them, otherwise).
|
|||||||
Libraries can be seen as implicit base contracts of the contracts that use them.
|
Libraries can be seen as implicit base contracts of the contracts that use them.
|
||||||
They will not be explicitly visible in the inheritance hierarchy, but calls
|
They will not be explicitly visible in the inheritance hierarchy, but calls
|
||||||
to library functions look just like calls to functions of explicit base
|
to library functions look just like calls to functions of explicit base
|
||||||
contracts (:code:`L.f()` if :code:`L` is the name of the library). Furthermore,
|
contracts (``L.f()`` if ``L`` is the name of the library). Furthermore,
|
||||||
:code:`internal` functions of libraries are visible in all contracts, just as
|
``internal`` functions of libraries are visible in all contracts, just as
|
||||||
if the library were a base contract. Of course, calls to internal functions
|
if the library were a base contract. Of course, calls to internal functions
|
||||||
use the internal calling convention, which means that all internal types
|
use the internal calling convention, which means that all internal types
|
||||||
can be passed and memory types will be passed by reference and not copied.
|
can be passed and memory types will be passed by reference and not copied.
|
||||||
In order to realise this in the EVM, code of internal library functions
|
In order to realise this in the EVM, code of internal library functions
|
||||||
(and all functions called from therein) will be pulled into the calling
|
(and all functions called from therein) will be pulled into the calling
|
||||||
contract and a regular :code:`JUMP` call will be used instead of a :code:`DELEGATECALL`.
|
contract and a regular ``JUMP`` call will be used instead of a ``DELEGATECALL``.
|
||||||
|
|
||||||
.. index:: using for, set
|
.. index:: using for, set
|
||||||
|
|
||||||
@ -823,13 +823,13 @@ data types, functions also work without any storage
|
|||||||
reference parameters, can have multiple storage reference
|
reference parameters, can have multiple storage reference
|
||||||
parameters and in any position.
|
parameters and in any position.
|
||||||
|
|
||||||
The calls to :code:`Set.contains`, :code:`Set.insert` and :code:`Set.remove`
|
The calls to ``Set.contains``, ``Set.insert`` and ``Set.remove``
|
||||||
are all compiled as calls (:code:`DELEGATECALL`) to an external
|
are all compiled as calls (``DELEGATECALL``) to an external
|
||||||
contract/library. If you use libraries, take care that an
|
contract/library. If you use libraries, take care that an
|
||||||
actual external function call is performed.
|
actual external function call is performed.
|
||||||
:code:`msg.sender`, :code:`msg.value` and :code:`this` will retain their values
|
``msg.sender``, ``msg.value`` and ``this`` will retain their values
|
||||||
in this call, though (prior to Homestead, :code:`msg.sender` and
|
in this call, though (prior to Homestead, ``msg.sender`` and
|
||||||
:code:`msg.value` changed, though).
|
``msg.value`` changed, though).
|
||||||
|
|
||||||
The following example shows how to use memory types and
|
The following example shows how to use memory types and
|
||||||
internal functions in libraries in order to implement
|
internal functions in libraries in order to implement
|
||||||
@ -895,8 +895,8 @@ final bytecode by a linker
|
|||||||
(see :ref:`commandline-compiler`) on how to use the
|
(see :ref:`commandline-compiler`) on how to use the
|
||||||
commandline compiler for linking). If the addresses are not
|
commandline compiler for linking). If the addresses are not
|
||||||
given as arguments to the compiler, the compiled hex code
|
given as arguments to the compiler, the compiled hex code
|
||||||
will contain placeholders of the form :code:`__Set______` (where
|
will contain placeholders of the form ``__Set______`` (where
|
||||||
:code:`Set` is the name of the library). The address can be filled
|
``Set`` is the name of the library). The address can be filled
|
||||||
manually by replacing all those 40 symbols by the hex
|
manually by replacing all those 40 symbols by the hex
|
||||||
encoding of the address of the library contract.
|
encoding of the address of the library contract.
|
||||||
|
|
||||||
@ -915,14 +915,14 @@ Restrictions for libraries in comparison to contracts:
|
|||||||
Using For
|
Using For
|
||||||
*********
|
*********
|
||||||
|
|
||||||
The directive :code:`using A for B;` can be used to attach library
|
The directive ``using A for B;`` can be used to attach library
|
||||||
functions (from the library :code:`A`) to any type (:code:`B`).
|
functions (from the library ``A``) to any type (``B``).
|
||||||
These functions will receive the object they are called on
|
These functions will receive the object they are called on
|
||||||
as their first parameter (like the :code:`self` variable in
|
as their first parameter (like the ``self`` variable in
|
||||||
Python).
|
Python).
|
||||||
|
|
||||||
The effect of :code:`using A for *;` is that the functions from
|
The effect of ``using A for *;`` is that the functions from
|
||||||
the library :code:`A` are attached to any type.
|
the library ``A`` are attached to any type.
|
||||||
|
|
||||||
In both situations, all functions, even those where the
|
In both situations, all functions, even those where the
|
||||||
type of the first parameter does not match the type of
|
type of the first parameter does not match the type of
|
||||||
@ -930,7 +930,7 @@ the object, are attached. The type is checked at the
|
|||||||
point the function is called and function overload
|
point the function is called and function overload
|
||||||
resolution is performed.
|
resolution is performed.
|
||||||
|
|
||||||
The :code:`using A for B;` directive is active for the current
|
The ``using A for B;`` directive is active for the current
|
||||||
scope, which is limited to a contract for now but will
|
scope, which is limited to a contract for now but will
|
||||||
be lifted to the global scope later, so that by including
|
be lifted to the global scope later, so that by including
|
||||||
a module, its data types including library functions are
|
a module, its data types including library functions are
|
||||||
@ -1014,5 +1014,5 @@ It is also possible to extend elementary types in that way::
|
|||||||
|
|
||||||
Note that all library calls are actual EVM function calls. This means that
|
Note that all library calls are actual EVM function calls. This means that
|
||||||
if you pass memory or value types, a copy will be performed, even of the
|
if you pass memory or value types, a copy will be performed, even of the
|
||||||
:code:`self` variable. The only situation where no copy will be performed
|
``self`` variable. The only situation where no copy will be performed
|
||||||
is when storage reference variables are used.
|
is when storage reference variables are used.
|
||||||
|
@ -8,15 +8,15 @@ Control Structures
|
|||||||
===================
|
===================
|
||||||
|
|
||||||
Most of the control structures from C/JavaScript are available in Solidity
|
Most of the control structures from C/JavaScript are available in Solidity
|
||||||
except for :code:`switch` and :code:`goto`. So
|
except for ``switch`` and ``goto``. So
|
||||||
there is: :code:`if`, :code:`else`, :code:`while`, :code:`for`, :code:`break`, :code:`continue`, :code:`return`, :code:`? :`, with
|
there is: ``if``, ``else``, ``while``, ``for``, ``break``, ``continue``, ``return``, ``? :``, with
|
||||||
the usual semantics known from C / JavaScript.
|
the usual semantics known from C / JavaScript.
|
||||||
|
|
||||||
Parentheses can *not* be omitted for conditionals, but curly brances can be omitted
|
Parentheses can *not* be omitted for conditionals, but curly brances can be omitted
|
||||||
around single-statement bodies.
|
around single-statement bodies.
|
||||||
|
|
||||||
Note that there is no type conversion from non-boolean to boolean types as
|
Note that there is no type conversion from non-boolean to boolean types as
|
||||||
there is in C and JavaScript, so :code:`if (1) { ... }` is *not* valid Solidity.
|
there is in C and JavaScript, so ``if (1) { ... }`` is *not* valid Solidity.
|
||||||
|
|
||||||
.. index:: ! function;call, function;internal, function;external
|
.. index:: ! function;call, function;internal, function;external
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ contract can be called internally.
|
|||||||
External Function Calls
|
External Function Calls
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
The expression :code:`this.g(8);` is also a valid function call, but this time, the function
|
The expression ``this.g(8);`` is also a valid function call, but this time, the function
|
||||||
will be called "externally", via a message call and not directly via jumps.
|
will be called "externally", via a message call and not directly via jumps.
|
||||||
Functions of other contracts have to be called externally. For an external call,
|
Functions of other contracts have to be called externally. For an external call,
|
||||||
all function arguments have to be copied to memory.
|
all function arguments have to be copied to memory.
|
||||||
@ -63,9 +63,9 @@ of other contracts, the amount of Wei sent with the call and the gas can be spec
|
|||||||
function callFeed() { feed.info.value(10).gas(800)(); }
|
function callFeed() { feed.info.value(10).gas(800)(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
Note that the expression :code:`InfoFeed(addr)` performs an explicit type conversion stating
|
Note that the expression ``InfoFeed(addr)`` performs an explicit type conversion stating
|
||||||
that "we know that the type of the contract at the given address is :code:`InfoFeed`" and
|
that "we know that the type of the contract at the given address is ``InfoFeed``" and
|
||||||
this does not execute a constructor. We could also have used :code:`function setFeed(InfoFeed _feed) { feed = _feed; }` directly. Be careful about the fact that :code:`feed.info.value(10).gas(800)`
|
this does not execute a constructor. We could also have used ``function setFeed(InfoFeed _feed) { feed = _feed; }`` directly. Be careful about the fact that ``feed.info.value(10).gas(800)``
|
||||||
only (locally) sets the value and amount of gas sent with the function call and only the
|
only (locally) sets the value and amount of gas sent with the function call and only the
|
||||||
parentheses at the end perform the actual call.
|
parentheses at the end perform the actual call.
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ Complications for Arrays and Structs
|
|||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
The semantics of assignment are a bit more complicated for non-value types like arrays and structs.
|
The semantics of assignment are a bit more complicated for non-value types like arrays and structs.
|
||||||
Assigning *to* a state variable always creates an independent copy. On the other hand, assigning to a local variable creates an independent copy only for elementary types, i.e. static types that fit into 32 bytes. If structs or arrays (including :code:`bytes` and :code:`string`) are assigned from a state variable to a local variable, the local variable holds a reference to the original state variable. A second assignment to the local variable does not modify the state but only changes the reference. Assignments to members (or elements) of the local variable *do* change the state.
|
Assigning *to* a state variable always creates an independent copy. On the other hand, assigning to a local variable creates an independent copy only for elementary types, i.e. static types that fit into 32 bytes. If structs or arrays (including ``bytes`` and ``string``) are assigned from a state variable to a local variable, the local variable holds a reference to the original state variable. A second assignment to the local variable does not modify the state but only changes the reference. Assignments to members (or elements) of the local variable *do* change the state.
|
||||||
|
|
||||||
.. index:: ! exception, ! throw
|
.. index:: ! exception, ! throw
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ Scoping and Declarations
|
|||||||
In Solidity, a variable declared anywhere within a function will be in scope for the *entire function*, regardless of where it is declared.
|
In Solidity, a variable declared anywhere within a function will be in scope for the *entire function*, regardless of where it is declared.
|
||||||
This happens because Solidity inherits its scoping rules from JavaScript.
|
This happens because Solidity inherits its scoping rules from JavaScript.
|
||||||
This is in contrast to many languages where variables are only scoped where they are declared until the end of the semantic block.
|
This is in contrast to many languages where variables are only scoped where they are declared until the end of the semantic block.
|
||||||
As a result, the following code is illegal and cause the compiler to throw an error, :code:`Identifier already declared`::
|
As a result, the following code is illegal and cause the compiler to throw an error, ``Identifier already declared``::
|
||||||
|
|
||||||
contract ScopingErrors {
|
contract ScopingErrors {
|
||||||
function scoping() {
|
function scoping() {
|
||||||
@ -208,11 +208,11 @@ As a result, the following code is legal, despite being poorly written::
|
|||||||
Exceptions
|
Exceptions
|
||||||
==========
|
==========
|
||||||
|
|
||||||
There are some cases where exceptions are thrown automatically (see below). You can use the :code:`throw` instruction to throw an exception manually. The effect of an exception is that the currently executing call is stopped and reverted (i.e. all changes to the state and balances are undone) and the exception is also "bubbled up" through Solidity function calls (exceptions are :code:`send` and the low-level functions :code:`call`, :code:`delegatecall` and :code:`callcode`, those return :code:`false` in case of an exception).
|
There are some cases where exceptions are thrown automatically (see below). You can use the ``throw`` instruction to throw an exception manually. The effect of an exception is that the currently executing call is stopped and reverted (i.e. all changes to the state and balances are undone) and the exception is also "bubbled up" through Solidity function calls (exceptions are ``send`` and the low-level functions ``call``, ``delegatecall`` and ``callcode``, those return ``false`` in case of an exception).
|
||||||
|
|
||||||
Catching exceptions is not yet possible.
|
Catching exceptions is not yet possible.
|
||||||
|
|
||||||
In the following example, we show how :code:`throw` can be used to easily revert an Ether transfer and also how to check the return value of :code:`send`::
|
In the following example, we show how ``throw`` can be used to easily revert an Ether transfer and also how to check the return value of ``send``::
|
||||||
|
|
||||||
contract Sharer {
|
contract Sharer {
|
||||||
function sendHalf(address addr) returns (uint balance) {
|
function sendHalf(address addr) returns (uint balance) {
|
||||||
@ -224,7 +224,7 @@ In the following example, we show how :code:`throw` can be used to easily revert
|
|||||||
|
|
||||||
Currently, there are three situations, where exceptions happen automatically in Solidity:
|
Currently, there are three situations, where exceptions happen automatically in Solidity:
|
||||||
|
|
||||||
1. If you access an array beyond its length (i.e. :code:`x[i]` where :code:`i >= x.length`)
|
1. If you access an array beyond its length (i.e. ``x[i]`` where ``i >= x.length``)
|
||||||
2. If a function called via a message call does not finish properly (i.e. it runs out of gas or throws an exception itself).
|
2. If a function called via a message call does not finish properly (i.e. it runs out of gas or throws an exception itself).
|
||||||
3. If a non-existent function on a library is called or Ether is sent to a library.
|
3. If a non-existent function on a library is called or Ether is sent to a library.
|
||||||
|
|
||||||
@ -242,10 +242,10 @@ often hard to address the correct stack slot and provide arguments to opcodes at
|
|||||||
point on the stack. Solidity's inline assembly tries to facilitate that and other issues
|
point on the stack. Solidity's inline assembly tries to facilitate that and other issues
|
||||||
arising when writing manual assembly by the following features:
|
arising when writing manual assembly by the following features:
|
||||||
|
|
||||||
* functional-style opcodes: :code:`mul(1, add(2, 3))` instead of :code:`push1 3 push1 2 add push1 1 mul`
|
* functional-style opcodes: ``mul(1, add(2, 3))`` instead of ``push1 3 push1 2 add push1 1 mul``
|
||||||
* assembly-local variables: :code:`let x := add(2, 3) let y := mload(0x40) x := add(x, y)`
|
* assembly-local variables: ``let x := add(2, 3) let y := mload(0x40) x := add(x, y)``
|
||||||
* access to external variables: :code:`function f(uint x) { assembly { x := sub(x, 1) } }`
|
* access to external variables: ``function f(uint x) { assembly { x := sub(x, 1) } }``
|
||||||
* labels: :code:`let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0))`
|
* labels: ``let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0))``
|
||||||
|
|
||||||
We now want to describe the inline assembly language in detail.
|
We now want to describe the inline assembly language in detail.
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ Example
|
|||||||
-------
|
-------
|
||||||
|
|
||||||
The following example provides library code to access the code of another contract and
|
The following example provides library code to access the code of another contract and
|
||||||
load it into a :code:`bytes` variable. This is not possible at all with "plain Solidity" and the
|
load it into a ``bytes`` variable. This is not possible at all with "plain Solidity" and the
|
||||||
idea is that assembly libraries will be used to enhance the language in such ways.
|
idea is that assembly libraries will be used to enhance the language in such ways.
|
||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
@ -311,18 +311,18 @@ Syntax
|
|||||||
------
|
------
|
||||||
|
|
||||||
Inline assembly parses comments, literals and identifiers exactly as Solidity, so you can use the
|
Inline assembly parses comments, literals and identifiers exactly as Solidity, so you can use the
|
||||||
usual :code:`//` and :code:`/* */` comments. Inline assembly is initiated by :code:`assembly { ... }` and inside
|
usual ``//`` and ``/* */`` comments. Inline assembly is initiated by ``assembly { ... }`` and inside
|
||||||
these curly braces, the following can be used (see the later sections for more details)
|
these curly braces, the following can be used (see the later sections for more details)
|
||||||
|
|
||||||
- literals, i.e. :code:`0x123`, :code:`42` or :code:`"abc"` (strings up to 32 characters)
|
- literals, i.e. ``0x123``, ``42`` or ``"abc"`` (strings up to 32 characters)
|
||||||
- opcodes (in "instruction style"), e.g. :code:`mload sload dup1 sstore`, for a list see below
|
- opcodes (in "instruction style"), e.g. ``mload sload dup1 sstore``, for a list see below
|
||||||
- opcode in functional style, e.g. :code:`add(1, mlod(0))`
|
- opcode in functional style, e.g. ``add(1, mlod(0))``
|
||||||
- labels, e.g. :code:`name:`
|
- labels, e.g. ``name:``
|
||||||
- variable declarations, e.g. :code:`let x := 7` or :code:`let x := add(y, 3)`
|
- variable declarations, e.g. ``let x := 7`` or ``let x := add(y, 3)``
|
||||||
- identifiers (externals, labels or assembly-local variables), e.g. :code:`jump(name)`, :code:`3 x add`
|
- identifiers (externals, labels or assembly-local variables), e.g. ``jump(name)``, ``3 x add``
|
||||||
- assignments (in "instruction style"), e.g. :code:`3 =: x`
|
- assignments (in "instruction style"), e.g. ``3 =: x``
|
||||||
- assignments in functional style, e.g. :code:`x := add(y, 3)`
|
- assignments in functional style, e.g. ``x := add(y, 3)``
|
||||||
- blocks where local variables are scoped inside, e.g. :code:`{ let x := 3 { let y := add(x, 1) } }`
|
- blocks where local variables are scoped inside, e.g. ``{ let x := 3 { let y := add(x, 1) } }``
|
||||||
|
|
||||||
Opcodes
|
Opcodes
|
||||||
-------
|
-------
|
||||||
@ -332,13 +332,13 @@ following list can be used as a reference of its opcodes.
|
|||||||
|
|
||||||
If an opcode takes arguments (always from the top of the stack), they are given in parentheses.
|
If an opcode takes arguments (always from the top of the stack), they are given in parentheses.
|
||||||
Note that the order of arguments can be seed to be reversed in non-functional style (explained below).
|
Note that the order of arguments can be seed to be reversed in non-functional style (explained below).
|
||||||
Opcodes marked with :code:`-` do not push an item onto the stack, those marked with :code:`*` are
|
Opcodes marked with ``-`` do not push an item onto the stack, those marked with ``*`` are
|
||||||
special and all others push exactly one item onte the stack.
|
special and all others push exactly one item onte the stack.
|
||||||
|
|
||||||
In the following, :code:`mem[a...b)` signifies the bytes of memory starting at position :code:`a` up to
|
In the following, ``mem[a...b)`` signifies the bytes of memory starting at position ``a`` up to
|
||||||
(excluding) position :code:`b` and :code:`storage[p]` signifies the storage contents at position :code:`p`.
|
(excluding) position ``b`` and ``storage[p]`` signifies the storage contents at position ``p``.
|
||||||
|
|
||||||
The opcodes :code:`pushi` and :code:`jumpdest` cannot be used directly.
|
The opcodes ``pushi`` and ``jumpdest`` cannot be used directly.
|
||||||
|
|
||||||
+-------------------------+------+-----------------------------------------------------------------+
|
+-------------------------+------+-----------------------------------------------------------------+
|
||||||
| stop + `-` | stop execution, identical to return(0,0) |
|
| stop + `-` | stop execution, identical to return(0,0) |
|
||||||
@ -447,8 +447,8 @@ The opcodes :code:`pushi` and :code:`jumpdest` cannot be used directly.
|
|||||||
| callcode(g, a, v, in, | | identical to call but only use the code from a and stay |
|
| callcode(g, a, v, in, | | identical to call but only use the code from a and stay |
|
||||||
| insize, out, outsize) | | in the context of the current contract otherwise |
|
| insize, out, outsize) | | in the context of the current contract otherwise |
|
||||||
+-------------------------+------+-----------------------------------------------------------------+
|
+-------------------------+------+-----------------------------------------------------------------+
|
||||||
| delegatecall(g, a, in, | | identical to callcode but also keep :code:`caller` |
|
| delegatecall(g, a, in, | | identical to callcode but also keep ``caller`` |
|
||||||
| insize, out, outsize) | | and :code:`callvalue` |
|
| insize, out, outsize) | | and ``callvalue`` |
|
||||||
+-------------------------+------+-----------------------------------------------------------------+
|
+-------------------------+------+-----------------------------------------------------------------+
|
||||||
| return(p, s) | `*` | end execution, return data mem[p..(p+s)) |
|
| return(p, s) | `*` | end execution, return data mem[p..(p+s)) |
|
||||||
+-------------------------+------+-----------------------------------------------------------------+
|
+-------------------------+------+-----------------------------------------------------------------+
|
||||||
@ -486,7 +486,7 @@ Literals
|
|||||||
--------
|
--------
|
||||||
|
|
||||||
You can use integer constants by typing them in decimal or hexadecimal notation and an
|
You can use integer constants by typing them in decimal or hexadecimal notation and an
|
||||||
appropriate :code:`PUSHi` instruction will automatically be generated. The following creates code
|
appropriate ``PUSHi`` instruction will automatically be generated. The following creates code
|
||||||
to add 2 and 3 resulting in 5 and then computes the bitwise and with the string "abc".
|
to add 2 and 3 resulting in 5 and then computes the bitwise and with the string "abc".
|
||||||
Strings are stored left-aligned and cannot be longer than 32 bytes.
|
Strings are stored left-aligned and cannot be longer than 32 bytes.
|
||||||
|
|
||||||
@ -498,7 +498,7 @@ Functional Style
|
|||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
You can type opcode after opcode in the same way they will end up in bytecode. For example
|
You can type opcode after opcode in the same way they will end up in bytecode. For example
|
||||||
adding :code:`3` to the contents in memory at position :code:`0x80` would be
|
adding ``3`` to the contents in memory at position ``0x80`` would be
|
||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
|
|
||||||
@ -557,7 +557,7 @@ It is planned that the stack height changes can be specified in inline assembly.
|
|||||||
Labels
|
Labels
|
||||||
------
|
------
|
||||||
|
|
||||||
Another problem in EVM assembly is that :code:`jump` and :code:`jumpi` use absolute addresses
|
Another problem in EVM assembly is that ``jump`` and ``jumpi`` use absolute addresses
|
||||||
which can change easily. Solidity inline assembly provides labels to make the use of
|
which can change easily. Solidity inline assembly provides labels to make the use of
|
||||||
jumps easier. The following code computes an element in the Fibonacci series.
|
jumps easier. The following code computes an element in the Fibonacci series.
|
||||||
|
|
||||||
@ -584,7 +584,7 @@ you should just not access any stack variables (even assembly variables) in that
|
|||||||
|
|
||||||
Furthermore, the stack height analyser goes through the code opcode by opcode
|
Furthermore, the stack height analyser goes through the code opcode by opcode
|
||||||
(and not according to control flow), so in the following case, the assembler
|
(and not according to control flow), so in the following case, the assembler
|
||||||
will have a wrong impression about the stack height at label :code:`two`:
|
will have a wrong impression about the stack height at label ``two``:
|
||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
|
|
||||||
@ -606,12 +606,12 @@ will have a wrong impression about the stack height at label :code:`two`:
|
|||||||
Declaring Assembly-Local Variables
|
Declaring Assembly-Local Variables
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
You can use the :code:`let` keyword to declare variables that are only visible in
|
You can use the ``let`` keyword to declare variables that are only visible in
|
||||||
inline assembly and actually only in the current :code:`{...}`-block. What happens
|
inline assembly and actually only in the current ``{...}``-block. What happens
|
||||||
is that the :code:`let` instruction will create a new stack slot that is reserved
|
is that the ``let`` instruction will create a new stack slot that is reserved
|
||||||
for the variable and automatically removed again when the end of the block
|
for the variable and automatically removed again when the end of the block
|
||||||
is reached. You need to provide an initial value for the variable which can
|
is reached. You need to provide an initial value for the variable which can
|
||||||
be just :code:`0`, but it can also be a complex functional-style expression.
|
be just ``0``, but it can also be a complex functional-style expression.
|
||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
|
|
||||||
@ -638,9 +638,9 @@ variables. Take care that when you assign to variables that point to
|
|||||||
memory or storage, you will only change the pointer and not the data.
|
memory or storage, you will only change the pointer and not the data.
|
||||||
|
|
||||||
There are two kinds of assignments: Functional-style and instruction-style.
|
There are two kinds of assignments: Functional-style and instruction-style.
|
||||||
For functionaly-style assignments (:code:`variable := value`), you need to provide a value in a
|
For functionaly-style assignments (``variable := value``), you need to provide a value in a
|
||||||
functional-style expression that results in exactly one stack value
|
functional-style expression that results in exactly one stack value
|
||||||
and for instruction-style (:code:`=: variable`), the value is just taken from the stack top.
|
and for instruction-style (``=: variable``), the value is just taken from the stack top.
|
||||||
For both ways, the colon points to the name of the variable.
|
For both ways, the colon points to the name of the variable.
|
||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
@ -669,7 +669,7 @@ Conventions in Solidity
|
|||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
In contrast to EVM assembly, Solidity knows types which are narrower than 256 bits,
|
In contrast to EVM assembly, Solidity knows types which are narrower than 256 bits,
|
||||||
e.g. :code:`uint24`. In order to make them more efficient, most arithmetic operations just
|
e.g. ``uint24``. In order to make them more efficient, most arithmetic operations just
|
||||||
treat them as 256 bit numbers and the higher-order bits are only cleaned at the
|
treat them as 256 bit numbers and the higher-order bits are only cleaned at the
|
||||||
point where it is necessary, i.e. just shortly before they are written to memory
|
point where it is necessary, i.e. just shortly before they are written to memory
|
||||||
or before comparisons are performed. This means that if you access such a variable
|
or before comparisons are performed. This means that if you access such a variable
|
||||||
@ -677,11 +677,11 @@ from within inline assembly, you might have to manually clean the higher order b
|
|||||||
first.
|
first.
|
||||||
|
|
||||||
Solidity manages memory in a very simple way: There is a "free memory pointer"
|
Solidity manages memory in a very simple way: There is a "free memory pointer"
|
||||||
at position :code:`0x40` in memory. If you want to allocate memory, just use the memory
|
at position ``0x40`` in memory. If you want to allocate memory, just use the memory
|
||||||
from that point on and update the pointer accordingly.
|
from that point on and update the pointer accordingly.
|
||||||
|
|
||||||
Elements in memory arrays in Solidity always occupy multiples of 32 bytes (yes, this is
|
Elements in memory arrays in Solidity always occupy multiples of 32 bytes (yes, this is
|
||||||
even true for :code:`byte[]`, but not for :code:`bytes` and :code:`string`). Multi-dimensional memory
|
even true for ``byte[]``, but not for ``bytes`` and ``string``). Multi-dimensional memory
|
||||||
arrays are pointers to memory arrays. The length of a dynamic array is stored at the
|
arrays are pointers to memory arrays. The length of a dynamic array is stored at the
|
||||||
first slot of the array and then only the array elements follow.
|
first slot of the array and then only the array elements follow.
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ How do I compile contracts?
|
|||||||
|
|
||||||
Probably the fastest way is the `online compiler <https://ethereum.github.io/browser-solidity/>`_.
|
Probably the fastest way is the `online compiler <https://ethereum.github.io/browser-solidity/>`_.
|
||||||
|
|
||||||
You can also use the :code:`solc` binary which comes with cpp-ethereum to compile
|
You can also use the ``solc`` binary which comes with cpp-ethereum to compile
|
||||||
contracts or an emerging option is to use Mix, the IDE.
|
contracts or an emerging option is to use Mix, the IDE.
|
||||||
|
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ several blockchain explorers.
|
|||||||
Contracts on the blockchain should have their original source
|
Contracts on the blockchain should have their original source
|
||||||
code published if they are to be used by third parties.
|
code published if they are to be used by third parties.
|
||||||
|
|
||||||
Does :code:`selfdestruct()` free up space in the blockchain?
|
Does ``selfdestruct()`` free up space in the blockchain?
|
||||||
============================================================
|
============================================================
|
||||||
|
|
||||||
It removes the contract bytecode and storage from the current block
|
It removes the contract bytecode and storage from the current block
|
||||||
@ -89,26 +89,26 @@ If you want to deactivate your contracts, it is preferable to **disable** them b
|
|||||||
internal state which causes all functions to throw. This will make it impossible
|
internal state which causes all functions to throw. This will make it impossible
|
||||||
to use the contract and ether sent to the contract will be returned automatically.
|
to use the contract and ether sent to the contract will be returned automatically.
|
||||||
|
|
||||||
Now to answering the question: Inside a constructor, :code:`msg.sender` is the
|
Now to answering the question: Inside a constructor, ``msg.sender`` is the
|
||||||
creator. Save it. Then :code:`selfdestruct(creator);` to kill and return funds.
|
creator. Save it. Then ``selfdestruct(creator);`` to kill and return funds.
|
||||||
|
|
||||||
`example <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/05_greeter.sol>`_
|
`example <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/05_greeter.sol>`_
|
||||||
|
|
||||||
Note that if you :code:`import "mortal"` at the top of your contracts and declare
|
Note that if you ``import "mortal"`` at the top of your contracts and declare
|
||||||
:code:`contract SomeContract is mortal { ...` and compile with a compiler that already
|
``contract SomeContract is mortal { ...`` and compile with a compiler that already
|
||||||
has it (which includes `browser-solidity <https://ethereum.github.io/browser-solidity/>`_), then
|
has it (which includes `browser-solidity <https://ethereum.github.io/browser-solidity/>`_), then
|
||||||
:code:`kill()` is taken care of for you. Once a contract is "mortal", then you can
|
``kill()`` is taken care of for you. Once a contract is "mortal", then you can
|
||||||
:code:`contractname.kill.sendTransaction({from:eth.coinbase})`, just the same as my
|
``contractname.kill.sendTransaction({from:eth.coinbase})``, just the same as my
|
||||||
examples.
|
examples.
|
||||||
|
|
||||||
Store Ether in a contract
|
Store Ether in a contract
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
The trick is to create the contract with :code:`{from:someaddress, value: web3.toWei(3,"ether")...}`
|
The trick is to create the contract with ``{from:someaddress, value: web3.toWei(3,"ether")...}``
|
||||||
|
|
||||||
See `endowment_retriever.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/30_endowment_retriever.sol>`_.
|
See `endowment_retriever.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/30_endowment_retriever.sol>`_.
|
||||||
|
|
||||||
Use a non-constant function (req :code:`sendTransaction`) to increment a variable in a contract
|
Use a non-constant function (req ``sendTransaction``) to increment a variable in a contract
|
||||||
===============================================================================================
|
===============================================================================================
|
||||||
|
|
||||||
See `value_incrementer.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/20_value_incrementer.sol>`_.
|
See `value_incrementer.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/20_value_incrementer.sol>`_.
|
||||||
@ -116,44 +116,44 @@ See `value_incrementer.sol <https://github.com/fivedogit/solidity-baby-steps/blo
|
|||||||
Get contract address in Solidity
|
Get contract address in Solidity
|
||||||
================================
|
================================
|
||||||
|
|
||||||
Short answer: The global variable :code:`this` is the contract address.
|
Short answer: The global variable ``this`` is the contract address.
|
||||||
|
|
||||||
See `basic_info_getter <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/15_basic_info_getter.sol>`_.
|
See `basic_info_getter <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/15_basic_info_getter.sol>`_.
|
||||||
|
|
||||||
Long answer: :code:`this` is a variable representing the current contract.
|
Long answer: ``this`` is a variable representing the current contract.
|
||||||
Its type is the type of the contract. Since any contract type basically inherits from the
|
Its type is the type of the contract. Since any contract type basically inherits from the
|
||||||
:code:`address` type, :code:`this` is always convertible to :code:`address` and in this case contains
|
``address`` type, ``this`` is always convertible to ``address`` and in this case contains
|
||||||
its own address.
|
its own address.
|
||||||
|
|
||||||
What is the difference between a function marked :code:`constant` and one that is not?
|
What is the difference between a function marked ``constant`` and one that is not?
|
||||||
======================================================================================
|
======================================================================================
|
||||||
|
|
||||||
:code:`constant` functions can perform some action and return a value, but cannot
|
``constant`` functions can perform some action and return a value, but cannot
|
||||||
change state (this is not yet enforced by the compiler). In other words, a
|
change state (this is not yet enforced by the compiler). In other words, a
|
||||||
constant function cannot save or update any variables within the contract or wider
|
constant function cannot save or update any variables within the contract or wider
|
||||||
blockchain. These functions are called using :code:`c.someFunction(...)` from
|
blockchain. These functions are called using ``c.someFunction(...)`` from
|
||||||
geth or any other web3.js environment.
|
geth or any other web3.js environment.
|
||||||
|
|
||||||
"non-constant" functions (those lacking the :code:`constant` specifier) must be called
|
"non-constant" functions (those lacking the ``constant`` specifier) must be called
|
||||||
with :code:`c.someMethod.sendTransaction({from:eth.accounts[x], gas: 1000000});`
|
with ``c.someMethod.sendTransaction({from:eth.accounts[x], gas: 1000000});``
|
||||||
That is, because they can change state, they have to have a gas
|
That is, because they can change state, they have to have a gas
|
||||||
payment sent along to get the work done.
|
payment sent along to get the work done.
|
||||||
|
|
||||||
Get a contract to return its funds to you (not using :code:`selfdestruct(...)`).
|
Get a contract to return its funds to you (not using ``selfdestruct(...)``).
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
This example demonstrates how to send funds from a contract to an address.
|
This example demonstrates how to send funds from a contract to an address.
|
||||||
|
|
||||||
See `endowment_retriever <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/30_endowment_retriever.sol>`_.
|
See `endowment_retriever <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/30_endowment_retriever.sol>`_.
|
||||||
|
|
||||||
What is a :code:`mapping` and how do we use them?
|
What is a ``mapping`` and how do we use them?
|
||||||
=================================================
|
=================================================
|
||||||
|
|
||||||
A mapping is very similar to a K->V hashmap.
|
A mapping is very similar to a K->V hashmap.
|
||||||
If you have a state variable of type :code:`mapping (string -> uint) x;`, then you can
|
If you have a state variable of type ``mapping (string -> uint) x;``, then you can
|
||||||
access the value by :code:`x["somekeystring"]`.
|
access the value by ``x["somekeystring"]``.
|
||||||
|
|
||||||
How can I get the length of a :code:`mapping`?
|
How can I get the length of a ``mapping``?
|
||||||
==============================================
|
==============================================
|
||||||
|
|
||||||
Mappings are a rather low-level data structure. It does not store the keys
|
Mappings are a rather low-level data structure. It does not store the keys
|
||||||
@ -161,18 +161,18 @@ and it is not possible to know which or how many values are "set". Actually,
|
|||||||
all values to all possible keys are set by default, they are just
|
all values to all possible keys are set by default, they are just
|
||||||
initialised with the zero value.
|
initialised with the zero value.
|
||||||
|
|
||||||
In this sense, the attribute :code:`length` for a mapping does not really apply.
|
In this sense, the attribute ``length`` for a mapping does not really apply.
|
||||||
|
|
||||||
If you want to have a "sized mapping", you can use the iterable mapping
|
If you want to have a "sized mapping", you can use the iterable mapping
|
||||||
(see below) or just a dynamically-sized array of structs.
|
(see below) or just a dynamically-sized array of structs.
|
||||||
|
|
||||||
Are :code:`mapping`'s iterable?
|
Are ``mapping``'s iterable?
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
Mappings themselves are not iterable, but you can use a higher-level
|
Mappings themselves are not iterable, but you can use a higher-level
|
||||||
datastructure on top of it, for example the `iterable mapping <https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol>`_.
|
datastructure on top of it, for example the `iterable mapping <https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol>`_.
|
||||||
|
|
||||||
Can I put arrays inside of a :code:`mapping`? How do I make a :code:`mapping` of a :code:`mapping`?
|
Can I put arrays inside of a ``mapping``? How do I make a ``mapping`` of a ``mapping``?
|
||||||
===================================================================================================
|
===================================================================================================
|
||||||
|
|
||||||
Mappings are already syntactically similar to arrays as they are, therefore it doesn't make much sense to store an array in them. Rather what you should do is create a mapping of a mapping.
|
Mappings are already syntactically similar to arrays as they are, therefore it doesn't make much sense to store an array in them. Rather what you should do is create a mapping of a mapping.
|
||||||
@ -192,23 +192,23 @@ An example of this would be::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Can you return an array or a :code:`string` from a solidity function call?
|
Can you return an array or a ``string`` from a solidity function call?
|
||||||
==========================================================================
|
==========================================================================
|
||||||
|
|
||||||
Yes. See `array_receiver_and_returner.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/60_array_receiver_and_returner.sol>`_.
|
Yes. See `array_receiver_and_returner.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/60_array_receiver_and_returner.sol>`_.
|
||||||
|
|
||||||
What is problematic, though, is returning any variably-sized data (e.g. a
|
What is problematic, though, is returning any variably-sized data (e.g. a
|
||||||
variably-sized array like :code:`uint[]`) from a fuction **called from within Solidity**.
|
variably-sized array like ``uint[]``) from a fuction **called from within Solidity**.
|
||||||
This is a limitation of the EVM and will be solved with the next protocol update.
|
This is a limitation of the EVM and will be solved with the next protocol update.
|
||||||
|
|
||||||
Returning variably-sized data as part of an external transaction or call is fine.
|
Returning variably-sized data as part of an external transaction or call is fine.
|
||||||
|
|
||||||
How do you represent :code:`double`/:code:`float` in Solidity?
|
How do you represent ``double``/``float`` in Solidity?
|
||||||
==============================================================
|
==============================================================
|
||||||
|
|
||||||
This is not yet possible.
|
This is not yet possible.
|
||||||
|
|
||||||
Is it possible to in-line initialize an array like so: :code:`string[] myarray = ["a", "b"];`
|
Is it possible to in-line initialize an array like so: ``string[] myarray = ["a", "b"];``
|
||||||
=============================================================================================
|
=============================================================================================
|
||||||
|
|
||||||
Yes. However it should be noted that this currently only works with statically sized memory arrays. You can even create an inline memory
|
Yes. However it should be noted that this currently only works with statically sized memory arrays. You can even create an inline memory
|
||||||
@ -223,7 +223,7 @@ Example::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
What are :code:`event`'s and why do we need them?
|
What are ``event``'s and why do we need them?
|
||||||
=================================================
|
=================================================
|
||||||
|
|
||||||
Let us suppose that you need a contract to alert the outside world when
|
Let us suppose that you need a contract to alert the outside world when
|
||||||
@ -239,20 +239,20 @@ The visibility specifiers do not only change the visibility but also
|
|||||||
the way functions can be called. In general, functions in the
|
the way functions can be called. In general, functions in the
|
||||||
same contract can also be called internally (which is cheaper
|
same contract can also be called internally (which is cheaper
|
||||||
and allows for memory types to be passed by reference). This
|
and allows for memory types to be passed by reference). This
|
||||||
is done if you just use :code:`f(1,2)`. If you use :code:`this.f(1,2)`
|
is done if you just use ``f(1,2)``. If you use ``this.f(1,2)``
|
||||||
or :code:`otherContract.f(1,2)`, the function is called externally.
|
or ``otherContract.f(1,2)``, the function is called externally.
|
||||||
|
|
||||||
Internal function calls have the advantage that you can use
|
Internal function calls have the advantage that you can use
|
||||||
all Solidity types as parameters, but you have to stick to the
|
all Solidity types as parameters, but you have to stick to the
|
||||||
simpler ABI types for external calls.
|
simpler ABI types for external calls.
|
||||||
|
|
||||||
* :code:`external`: all, only externally
|
* ``external``: all, only externally
|
||||||
|
|
||||||
* :code:`public`: all (this is the default), externally and internally
|
* ``public``: all (this is the default), externally and internally
|
||||||
|
|
||||||
* :code:`internal`: only this contract and contracts deriving from it, only internally
|
* ``internal``: only this contract and contracts deriving from it, only internally
|
||||||
|
|
||||||
* :code:`private`: only this contract, only internally
|
* ``private``: only this contract, only internally
|
||||||
|
|
||||||
|
|
||||||
Do contract constructors have to be publicly visible?
|
Do contract constructors have to be publicly visible?
|
||||||
@ -278,7 +278,7 @@ Is a constructor required?
|
|||||||
|
|
||||||
No. If there is no constructor, a generic one without arguments and no actions will be used.
|
No. If there is no constructor, a generic one without arguments and no actions will be used.
|
||||||
|
|
||||||
Are timestamps (:code:`now,` :code:`block.timestamp`) reliable?
|
Are timestamps (``now,`` ``block.timestamp``) reliable?
|
||||||
===============================================================
|
===============================================================
|
||||||
|
|
||||||
This depends on what you mean by "reliable".
|
This depends on what you mean by "reliable".
|
||||||
@ -288,27 +288,27 @@ Unless someone really messes up the blockchain or the clock on
|
|||||||
your computer, you can make the following assumptions:
|
your computer, you can make the following assumptions:
|
||||||
|
|
||||||
You publish a transaction at a time X, this transaction contains same
|
You publish a transaction at a time X, this transaction contains same
|
||||||
code that calls :code:`now` and is included in a block whose timestamp is Y
|
code that calls ``now`` and is included in a block whose timestamp is Y
|
||||||
and this block is included into the canonical chain (published) at a time Z.
|
and this block is included into the canonical chain (published) at a time Z.
|
||||||
|
|
||||||
The value of :code:`now` will be identical to Y and X <= Y <= Z.
|
The value of ``now`` will be identical to Y and X <= Y <= Z.
|
||||||
|
|
||||||
Never use :code:`now` or :code:`block.hash` as a source of randomness, unless you know
|
Never use ``now`` or ``block.hash`` as a source of randomness, unless you know
|
||||||
what you are doing!
|
what you are doing!
|
||||||
|
|
||||||
Can a contract function return a :code:`struct`?
|
Can a contract function return a ``struct``?
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
Yes, but only in "internal" function calls.
|
Yes, but only in ``internal`` function calls.
|
||||||
|
|
||||||
If I return an :code:`enum`, I only get integer values in web3.js. How to get the named values?
|
If I return an ``enum``, I only get integer values in web3.js. How to get the named values?
|
||||||
===============================================================================================
|
===============================================================================================
|
||||||
|
|
||||||
Enums are not supported by the ABI, they are just supported by Solidity.
|
Enums are not supported by the ABI, they are just supported by Solidity.
|
||||||
You have to do the mapping yourself for now, we might provide some help
|
You have to do the mapping yourself for now, we might provide some help
|
||||||
later.
|
later.
|
||||||
|
|
||||||
What is the deal with :code:`function () { ... }` inside Solidity contracts? How can a function not have a name?
|
What is the deal with ``function () { ... }`` inside Solidity contracts? How can a function not have a name?
|
||||||
================================================================================================================
|
================================================================================================================
|
||||||
|
|
||||||
This function is called "fallback function" and it
|
This function is called "fallback function" and it
|
||||||
@ -324,7 +324,7 @@ a way to pull out Ether from a contract.
|
|||||||
If the contract is not meant to receive Ether with simple transfers, you
|
If the contract is not meant to receive Ether with simple transfers, you
|
||||||
should implement the fallback function as
|
should implement the fallback function as
|
||||||
|
|
||||||
:code:`function() { throw; }`
|
``function() { throw; }``
|
||||||
|
|
||||||
this will cause all transactions to this contract that do not call an
|
this will cause all transactions to this contract that do not call an
|
||||||
existing function to be reverted, so that all Ether is sent back.
|
existing function to be reverted, so that all Ether is sent back.
|
||||||
@ -333,7 +333,7 @@ Another use of the fallback function is to e.g. register that your
|
|||||||
contract received ether by using an event.
|
contract received ether by using an event.
|
||||||
|
|
||||||
*Attention*: If you implement the fallback function take care that it uses as
|
*Attention*: If you implement the fallback function take care that it uses as
|
||||||
little gas as possible, because :code:`send()` will only supply a limited amount.
|
little gas as possible, because ``send()`` will only supply a limited amount.
|
||||||
|
|
||||||
Is it possible to pass arguments to the fallback function?
|
Is it possible to pass arguments to the fallback function?
|
||||||
==========================================================
|
==========================================================
|
||||||
@ -342,7 +342,7 @@ The fallback function cannot take parameters.
|
|||||||
|
|
||||||
Under special circumstances, you can send data. If you take care
|
Under special circumstances, you can send data. If you take care
|
||||||
that none of the other functions is invoked, you can access the data
|
that none of the other functions is invoked, you can access the data
|
||||||
by :code:`msg.data`.
|
by ``msg.data``.
|
||||||
|
|
||||||
Can state variables be initialized in-line?
|
Can state variables be initialized in-line?
|
||||||
===========================================
|
===========================================
|
||||||
@ -368,7 +368,7 @@ Examples::
|
|||||||
C c = new C();
|
C c = new C();
|
||||||
}
|
}
|
||||||
|
|
||||||
What is the :code:`modifier` keyword?
|
What is the ``modifier`` keyword?
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
Modifiers are a way to prepend or append code to a function in order
|
Modifiers are a way to prepend or append code to a function in order
|
||||||
@ -376,7 +376,7 @@ to add guards, initialisation or cleanup functionality in a concise way.
|
|||||||
|
|
||||||
For examples, see the `features.sol <https://github.com/ethereum/dapp-bin/blob/master/library/features.sol>`_.
|
For examples, see the `features.sol <https://github.com/ethereum/dapp-bin/blob/master/library/features.sol>`_.
|
||||||
|
|
||||||
How do :code:`struct`'s work?
|
How do ``struct``'s work?
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
See `struct_and_for_loop_tester.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/65_struct_and_for_loop_tester.sol>`_.
|
See `struct_and_for_loop_tester.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/65_struct_and_for_loop_tester.sol>`_.
|
||||||
@ -386,12 +386,12 @@ How do for loops work?
|
|||||||
|
|
||||||
Very similar to JavaScript. There is one point to watch out for, though:
|
Very similar to JavaScript. There is one point to watch out for, though:
|
||||||
|
|
||||||
If you use :code:`for (var i = 0; i < a.length; i ++) { a[i] = i; }`, then
|
If you use ``for (var i = 0; i < a.length; i ++) { a[i] = i; }``, then
|
||||||
the type of :code:`i` will be inferred only from :code:`0`, whose type is :code:`uint8`.
|
the type of ``i`` will be inferred only from ``0``, whose type is ``uint8``.
|
||||||
This means that if :code:`a` has more than :code:`255` elements, your loop will
|
This means that if ``a`` has more than ``255`` elements, your loop will
|
||||||
not terminate because :code:`i` can only hold values up to :code:`255`.
|
not terminate because ``i`` can only hold values up to ``255``.
|
||||||
|
|
||||||
Better use :code:`for (uint i = 0; i < a.length...`
|
Better use ``for (uint i = 0; i < a.length...``
|
||||||
|
|
||||||
See `struct_and_for_loop_tester.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/65_struct_and_for_loop_tester.sol>`_.
|
See `struct_and_for_loop_tester.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/65_struct_and_for_loop_tester.sol>`_.
|
||||||
|
|
||||||
@ -402,14 +402,14 @@ Solidity is character set agnostic concerning strings in the source code, althou
|
|||||||
utf-8 is recommended. Identifiers (variables, functions, ...) can only use
|
utf-8 is recommended. Identifiers (variables, functions, ...) can only use
|
||||||
ASCII.
|
ASCII.
|
||||||
|
|
||||||
What are some examples of basic string manipulation (:code:`substring`, :code:`indexOf`, :code:`charAt`, etc)?
|
What are some examples of basic string manipulation (``substring``, ``indexOf``, ``charAt``, etc)?
|
||||||
==============================================================================================================
|
==============================================================================================================
|
||||||
|
|
||||||
There are some string utility functions at `stringUtils.sol <https://github.com/ethereum/dapp-bin/blob/master/library/stringUtils.sol>`_
|
There are some string utility functions at `stringUtils.sol <https://github.com/ethereum/dapp-bin/blob/master/library/stringUtils.sol>`_
|
||||||
which will be extended in the future.
|
which will be extended in the future.
|
||||||
|
|
||||||
For now, if you want to modify a string (even when you only want to know its length),
|
For now, if you want to modify a string (even when you only want to know its length),
|
||||||
you should always convert it to a :code:`bytes` first::
|
you should always convert it to a ``bytes`` first::
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
string s;
|
string s;
|
||||||
@ -429,8 +429,8 @@ Can I concatenate two strings?
|
|||||||
|
|
||||||
You have to do it manually for now.
|
You have to do it manually for now.
|
||||||
|
|
||||||
Why is the low-level function :code:`.call()` less favorable than instantiating a contract with a variable (:code:`ContractB b;`) and executing its functions (:code:`b.doSomething();`)?
|
Why is the low-level function ``.call()`` less favorable than instantiating a contract with a variable (``ContractB b;``) and executing its functions (``b.doSomething();``)?
|
||||||
=========================================================================================================================================================================================
|
========================================================================================================================================================================================
|
||||||
|
|
||||||
If you use actual functions, the compiler will tell you if the types
|
If you use actual functions, the compiler will tell you if the types
|
||||||
or your arguments do not match, if the function does not exist
|
or your arguments do not match, if the function does not exist
|
||||||
@ -445,12 +445,12 @@ Is unused gas automatically refunded?
|
|||||||
|
|
||||||
Yes and it is immediate, i.e. done as part of the transaction.
|
Yes and it is immediate, i.e. done as part of the transaction.
|
||||||
|
|
||||||
When returning a value of say :code:`uint` type, is it possible to return an :code:`undefined` or "null"-like value?
|
When returning a value of say ``uint`` type, is it possible to return an ``undefined`` or "null"-like value?
|
||||||
====================================================================================================================
|
====================================================================================================================
|
||||||
|
|
||||||
This is not possible, because all types use up the full value range.
|
This is not possible, because all types use up the full value range.
|
||||||
|
|
||||||
You have the option to :code:`throw` on error, which will also revert the whole
|
You have the option to ``throw`` on error, which will also revert the whole
|
||||||
transaction, which might be a good idea if you ran into an unexpected
|
transaction, which might be a good idea if you ran into an unexpected
|
||||||
situation.
|
situation.
|
||||||
|
|
||||||
@ -495,7 +495,7 @@ No, a function call from one contract to another does not create its own transac
|
|||||||
you have to look in the overall transaction. This is also the reason why several
|
you have to look in the overall transaction. This is also the reason why several
|
||||||
block explorer do not show Ether sent between contracts correctly.
|
block explorer do not show Ether sent between contracts correctly.
|
||||||
|
|
||||||
What is the :code:`memory` keyword? What does it do?
|
What is the ``memory`` keyword? What does it do?
|
||||||
====================================================
|
====================================================
|
||||||
|
|
||||||
The Ethereum Virtual Machine has three areas where it can store items.
|
The Ethereum Virtual Machine has three areas where it can store items.
|
||||||
@ -545,14 +545,14 @@ Example::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The function :code:`append` can work both on :code:`data1` and :code:`data2` and its modifications will be
|
The function ``append`` can work both on ``data1`` and ``data2`` and its modifications will be
|
||||||
stored permanently. If you remove the :code:`storage` keyword, the default
|
stored permanently. If you remove the ``storage`` keyword, the default
|
||||||
is to use :code:`memory` for function arguments. This has the effect that
|
is to use ``memory`` for function arguments. This has the effect that
|
||||||
at the point where :code:`append(data1)` or :code:`append(data2)` is called, an
|
at the point where ``append(data1)`` or ``append(data2)`` is called, an
|
||||||
independent copy of the state variable is created in memory and
|
independent copy of the state variable is created in memory and
|
||||||
:code:`append` operates on this copy (which does not support :code:`.push` - but that
|
``append`` operates on this copy (which does not support ``.push`` - but that
|
||||||
is another issue). The modifications to this independent copy do not
|
is another issue). The modifications to this independent copy do not
|
||||||
carry back to :code:`data1` or :code:`data2`.
|
carry back to ``data1`` or ``data2``.
|
||||||
|
|
||||||
A common mistake is to declare a local variable and assume that it will
|
A common mistake is to declare a local variable and assume that it will
|
||||||
be created in memory, although it will be created in storage::
|
be created in memory, although it will be created in storage::
|
||||||
@ -569,16 +569,16 @@ be created in memory, although it will be created in storage::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The type of the local variable :code:`x` is :code:`uint[] storage`, but since
|
The type of the local variable ``x`` is ``uint[] storage``, but since
|
||||||
storage is not dynamically allocated, it has to be assigned from
|
storage is not dynamically allocated, it has to be assigned from
|
||||||
a state variable before it can be used. So no space in storage will be
|
a state variable before it can be used. So no space in storage will be
|
||||||
allocated for :code:`x`, but instead it functions only as an alias for
|
allocated for ``x``, but instead it functions only as an alias for
|
||||||
a pre-existing variable in storage.
|
a pre-existing variable in storage.
|
||||||
|
|
||||||
What will happen is that the compiler interprets :code:`x` as a storage
|
What will happen is that the compiler interprets ``x`` as a storage
|
||||||
pointer and will make it point to the storage slot :code:`0` by default.
|
pointer and will make it point to the storage slot ``0`` by default.
|
||||||
This has the effect that :code:`someVariable` (which resides at storage
|
This has the effect that ``someVariable`` (which resides at storage
|
||||||
slot :code:`0`) is modified by :code:`x.push(2)`.
|
slot ``0``) is modified by ``x.push(2)``.
|
||||||
|
|
||||||
The correct way to do this is the following::
|
The correct way to do this is the following::
|
||||||
|
|
||||||
@ -598,11 +598,11 @@ Can a regular (i.e. non-contract) ethereum account be closed permanently like a
|
|||||||
No. Non-contract accounts "exist" as long as the private key is known by
|
No. Non-contract accounts "exist" as long as the private key is known by
|
||||||
someone or can be generated in some way.
|
someone or can be generated in some way.
|
||||||
|
|
||||||
What is the difference between :code:`bytes` and :code:`byte[]`?
|
What is the difference between ``bytes`` and ``byte[]``?
|
||||||
================================================================
|
================================================================
|
||||||
|
|
||||||
:code:`bytes` is usually more efficient: When used as arguments to functions (i.e. in
|
``bytes`` is usually more efficient: When used as arguments to functions (i.e. in
|
||||||
CALLDATA) or in memory, every single element of a :code:`byte[]` is padded to 32
|
CALLDATA) or in memory, every single element of a ``byte[]`` is padded to 32
|
||||||
bytes which wastes 31 bytes per element.
|
bytes which wastes 31 bytes per element.
|
||||||
|
|
||||||
Is it possible to send a value while calling an overloaded function?
|
Is it possible to send a value while calling an overloaded function?
|
||||||
@ -658,19 +658,19 @@ How do you create 2-dimensional arrays?
|
|||||||
|
|
||||||
See `2D_array.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/55_2D_array.sol>`_.
|
See `2D_array.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/55_2D_array.sol>`_.
|
||||||
|
|
||||||
Note that filling a 10x10 square of :code:`uint8` + contract creation took more than :code:`800,000`
|
Note that filling a 10x10 square of ``uint8`` + contract creation took more than ``800,000``
|
||||||
gas at the time of this writing. 17x17 took :code:`2,000,000` gas. With the limit at
|
gas at the time of this writing. 17x17 took ``2,000,000`` gas. With the limit at
|
||||||
3.14 million... well, there’s a pretty low ceiling for what you can create right
|
3.14 million... well, there’s a pretty low ceiling for what you can create right
|
||||||
now.
|
now.
|
||||||
|
|
||||||
Note that merely "creating" the array is free, the costs are in filling it.
|
Note that merely "creating" the array is free, the costs are in filling it.
|
||||||
|
|
||||||
Note2: Optimizing storage access can pull the gas costs down considerably, because
|
Note2: Optimizing storage access can pull the gas costs down considerably, because
|
||||||
32 :code:`uint8` values can be stored in a single slot. The problem is that these optimizations
|
32 ``uint8`` values can be stored in a single slot. The problem is that these optimizations
|
||||||
currently do not work across loops and also have a problem with bounds checking.
|
currently do not work across loops and also have a problem with bounds checking.
|
||||||
You might get much better results in the future, though.
|
You might get much better results in the future, though.
|
||||||
|
|
||||||
What does :code:`p.recipient.call.value(p.amount)(p.data)` do?
|
What does ``p.recipient.call.value(p.amount)(p.data)`` do?
|
||||||
==============================================================
|
==============================================================
|
||||||
|
|
||||||
Every external function call in Solidity can be modified in two ways:
|
Every external function call in Solidity can be modified in two ways:
|
||||||
@ -680,14 +680,14 @@ Every external function call in Solidity can be modified in two ways:
|
|||||||
|
|
||||||
This is done by "calling a function on the function":
|
This is done by "calling a function on the function":
|
||||||
|
|
||||||
:code:`f.gas(2).value(20)()` calls the modified function :code:`f` and thereby sending 20
|
``f.gas(2).value(20)()`` calls the modified function ``f`` and thereby sending 20
|
||||||
Wei and limiting the gas to 2 (so this function call will most likely go out of
|
Wei and limiting the gas to 2 (so this function call will most likely go out of
|
||||||
gas and return your 20 Wei).
|
gas and return your 20 Wei).
|
||||||
|
|
||||||
In the above example, the low-level function :code:`call` is used to invoke another
|
In the above example, the low-level function ``call`` is used to invoke another
|
||||||
contract with :code:`p.data` as payload and :code:`p.amount` Wei is sent with that call.
|
contract with ``p.data`` as payload and ``p.amount`` Wei is sent with that call.
|
||||||
|
|
||||||
What happens to a :code:`struct`'s mapping when copying over a :code:`struct`?
|
What happens to a ``struct``'s mapping when copying over a ``struct``?
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
This is a very interesting question. Suppose that we have a contract field set up like such::
|
This is a very interesting question. Suppose that we have a contract field set up like such::
|
||||||
@ -709,8 +709,8 @@ How do I initialize a contract with only a specific amount of wei?
|
|||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
Currently the approach is a little ugly, but there is little that can be done to improve it.
|
Currently the approach is a little ugly, but there is little that can be done to improve it.
|
||||||
In the case of a :code:`contract A` calling a new instance of :code:`contract B`, parentheses have to be used around
|
In the case of a ``contract A`` calling a new instance of ``contract B``, parentheses have to be used around
|
||||||
:code:`new B` because :code:`B.value` would refer to a member of :code:`B` called :code:`value`.
|
``new B`` because ``B.value`` would refer to a member of ``B`` called ``value``.
|
||||||
You will need to make sure that you have both contracts aware of each other's presence.
|
You will need to make sure that you have both contracts aware of each other's presence.
|
||||||
In this example::
|
In this example::
|
||||||
|
|
||||||
@ -731,29 +731,29 @@ Can a contract function accept a two-dimensional array?
|
|||||||
This is not yet implemented for external calls and dynamic arrays -
|
This is not yet implemented for external calls and dynamic arrays -
|
||||||
you can only use one level of dynamic arrays.
|
you can only use one level of dynamic arrays.
|
||||||
|
|
||||||
What is the relationship between :code:`bytes32` and :code:`string`? Why is it that :code:`bytes32 somevar = "stringliteral";` works and what does the saved 32-byte hex value mean?
|
What is the relationship between ``bytes32`` and ``string``? Why is it that ``bytes32 somevar = "stringliteral";`` works and what does the saved 32-byte hex value mean?
|
||||||
====================================================================================================================================================================================
|
====================================================================================================================================================================================
|
||||||
|
|
||||||
The type :code:`bytes32` can hold 32 (raw) bytes. In the assignment :code:`bytes32 samevar = "stringliteral";`,
|
The type ``bytes32`` can hold 32 (raw) bytes. In the assignment ``bytes32 samevar = "stringliteral";``,
|
||||||
the string literal is interpreted in its raw byte form and if you inspect :code:`somevar` and
|
the string literal is interpreted in its raw byte form and if you inspect ``somevar`` and
|
||||||
see a 32-byte hex value, this is just :code:`"stringliteral"` in hex.
|
see a 32-byte hex value, this is just ``"stringliteral"`` in hex.
|
||||||
|
|
||||||
The type :code:`bytes` is similar, only that it can change its length.
|
The type ``bytes`` is similar, only that it can change its length.
|
||||||
|
|
||||||
Finally, :code:`string` is basically identical to :code:`bytes` only that it is assumed
|
Finally, ``string`` is basically identical to ``bytes`` only that it is assumed
|
||||||
to hold the utf-8 encoding of a real string. Since :code:`string` stores the
|
to hold the utf-8 encoding of a real string. Since ``string`` stores the
|
||||||
data in utf-8 encoding it is quite expensive to compute the number of
|
data in utf-8 encoding it is quite expensive to compute the number of
|
||||||
characters in the string (the encoding of some characters takes more
|
characters in the string (the encoding of some characters takes more
|
||||||
than a single byte). Because of that, :code:`string s; s.length` is not yet
|
than a single byte). Because of that, ``string s; s.length`` is not yet
|
||||||
supported and not even index access :code:`s[2]`. But if you want to access
|
supported and not even index access ``s[2]``. But if you want to access
|
||||||
the low-level byte encoding of the string, you can use
|
the low-level byte encoding of the string, you can use
|
||||||
:code:`bytes(s).length` and :code:`bytes(s)[2]` which will result in the number
|
``bytes(s).length`` and ``bytes(s)[2]`` which will result in the number
|
||||||
of bytes in the utf-8 encoding of the string (not the number of
|
of bytes in the utf-8 encoding of the string (not the number of
|
||||||
characters) and the second byte (not character) of the utf-8 encoded
|
characters) and the second byte (not character) of the utf-8 encoded
|
||||||
string, respectively.
|
string, respectively.
|
||||||
|
|
||||||
|
|
||||||
Can a contract pass an array (static size) or string or :code:`bytes` (dynamic size) to another contract?
|
Can a contract pass an array (static size) or string or ``bytes`` (dynamic size) to another contract?
|
||||||
=========================================================================================================
|
=========================================================================================================
|
||||||
|
|
||||||
Sure. Take care that if you cross the memory / storage boundary,
|
Sure. Take care that if you cross the memory / storage boundary,
|
||||||
@ -776,17 +776,17 @@ independent copies will be created::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The call to :code:`g(x)` will not have an effect on :code:`x` because it needs
|
The call to ``g(x)`` will not have an effect on ``x`` because it needs
|
||||||
to create an independent copy of the storage value in memory
|
to create an independent copy of the storage value in memory
|
||||||
(the default storage location is memory). On the other hand,
|
(the default storage location is memory). On the other hand,
|
||||||
:code:`h(x)` successfully modifies :code:`x` because only a reference
|
``h(x)`` successfully modifies ``x`` because only a reference
|
||||||
and not a copy is passed.
|
and not a copy is passed.
|
||||||
|
|
||||||
Sometimes, when I try to change the length of an array with ex: :code:`arrayname.length = 7;` I get a compiler error :code:`Value must be an lvalue`. Why?
|
Sometimes, when I try to change the length of an array with ex: ``arrayname.length = 7;`` I get a compiler error ``Value must be an lvalue``. Why?
|
||||||
==========================================================================================================================================================
|
==========================================================================================================================================================
|
||||||
|
|
||||||
You can resize a dynamic array in storage (i.e. an array declared at the
|
You can resize a dynamic array in storage (i.e. an array declared at the
|
||||||
contract level) with :code:`arrayname.length = <some new length>;`. If you get the
|
contract level) with ``arrayname.length = <some new length>;``. If you get the
|
||||||
"lvalue" error, you are probably doing one of two things wrong.
|
"lvalue" error, you are probably doing one of two things wrong.
|
||||||
|
|
||||||
1. You might be trying to resize an array in "memory", or
|
1. You might be trying to resize an array in "memory", or
|
||||||
@ -806,16 +806,16 @@ contract level) with :code:`arrayname.length = <some new length>;`. If you get t
|
|||||||
might be used to declaring them in C or Java, but they are access as in
|
might be used to declaring them in C or Java, but they are access as in
|
||||||
C or Java.
|
C or Java.
|
||||||
|
|
||||||
For example, :code:`int8[][5] somearray;` are 5 dynamic :code:`int8` arrays.
|
For example, ``int8[][5] somearray;`` are 5 dynamic ``int8`` arrays.
|
||||||
|
|
||||||
The reason for this is that :code:`T[5]` is always an array of 5 :code:`T`'s,
|
The reason for this is that ``T[5]`` is always an array of 5 ``T``'s,
|
||||||
no matter whether :code:`T` itself is an array or not (this is not the
|
no matter whether ``T`` itself is an array or not (this is not the
|
||||||
case in C or Java).
|
case in C or Java).
|
||||||
|
|
||||||
Is it possible to return an array of strings (:code:`string[]`) from a Solidity function?
|
Is it possible to return an array of strings (``string[]``) from a Solidity function?
|
||||||
===========================================================================================
|
===========================================================================================
|
||||||
|
|
||||||
Not yet, as this requires two levels of dynamic arrays (:code:`string` is a dynamic array itself).
|
Not yet, as this requires two levels of dynamic arrays (``string`` is a dynamic array itself).
|
||||||
|
|
||||||
If you issue a call for an array, it is possible to retrieve the whole array? Or must you write a helper function for that?
|
If you issue a call for an array, it is possible to retrieve the whole array? Or must you write a helper function for that?
|
||||||
===========================================================================================================================
|
===========================================================================================================================
|
||||||
@ -839,12 +839,12 @@ https://github.com/ethereum/wiki/wiki/Subtleties
|
|||||||
After a successful CREATE operation's sub-execution, if the operation returns x, 5 * len(x) gas is subtracted from the remaining gas before the contract is created. If the remaining gas is less than 5 * len(x), then no gas is subtracted, the code of the created contract becomes the empty string, but this is not treated as an exceptional condition - no reverts happen.
|
After a successful CREATE operation's sub-execution, if the operation returns x, 5 * len(x) gas is subtracted from the remaining gas before the contract is created. If the remaining gas is less than 5 * len(x), then no gas is subtracted, the code of the created contract becomes the empty string, but this is not treated as an exceptional condition - no reverts happen.
|
||||||
|
|
||||||
|
|
||||||
How do I use :code:`.send()`?
|
How do I use ``.send()``?
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
If you want to send 20 Ether from a contract to the address :code:`x`, you use :code:`x.send(20 ether);`.
|
If you want to send 20 Ether from a contract to the address ``x``, you use ``x.send(20 ether);``.
|
||||||
Here, :code:`x` can be a plain address or a contract. If the contract already explicitly defines
|
Here, ``x`` can be a plain address or a contract. If the contract already explicitly defines
|
||||||
a function :code:`send` (and thus overwrites the special function), you can use :code:`address(x).send(20 ether);`.
|
a function ``send`` (and thus overwrites the special function), you can use ``address(x).send(20 ether);``.
|
||||||
|
|
||||||
What does the following strange check do in the Custom Token contract?
|
What does the following strange check do in the Custom Token contract?
|
||||||
======================================================================
|
======================================================================
|
||||||
@ -855,7 +855,7 @@ What does the following strange check do in the Custom Token contract?
|
|||||||
throw;
|
throw;
|
||||||
|
|
||||||
Integers in Solidity (and most other machine-related programming languages) are restricted to a certain range.
|
Integers in Solidity (and most other machine-related programming languages) are restricted to a certain range.
|
||||||
For :code:`uint256`, this is :code:`0` up to :code:`2**256 - 1`. If the result of some operation on those numbers
|
For ``uint256``, this is ``0`` up to ``2**256 - 1``. If the result of some operation on those numbers
|
||||||
does not fit inside this range, it is truncated. These truncations can have
|
does not fit inside this range, it is truncated. These truncations can have
|
||||||
`serious consequences <https://en.bitcoin.it/wiki/Value_overflow_incident>`_, so code like the one
|
`serious consequences <https://en.bitcoin.it/wiki/Value_overflow_incident>`_, so code like the one
|
||||||
above is necessary to avoid certain attacks.
|
above is necessary to avoid certain attacks.
|
||||||
|
@ -113,7 +113,7 @@ For Ubuntu 15.10 (Wily Werewolf) or newer, use the following command instead:
|
|||||||
|
|
||||||
sudo apt-get -y install build-essential git cmake libboost-all-dev libgmp-dev libleveldb-dev libminiupnpc-dev libreadline-dev libncurses5-dev libcurl4-openssl-dev libcryptopp-dev libjsonrpccpp-dev libmicrohttpd-dev libjsoncpp-dev libedit-dev libz-dev
|
sudo apt-get -y install build-essential git cmake libboost-all-dev libgmp-dev libleveldb-dev libminiupnpc-dev libreadline-dev libncurses5-dev libcurl4-openssl-dev libcryptopp-dev libjsonrpccpp-dev libmicrohttpd-dev libjsoncpp-dev libedit-dev libz-dev
|
||||||
|
|
||||||
The reason for the change is that :code:`libjsonrpccpp-dev` is available in the universe repository for newer versions of Ubuntu.
|
The reason for the change is that ``libjsonrpccpp-dev`` is available in the universe repository for newer versions of Ubuntu.
|
||||||
|
|
||||||
Building
|
Building
|
||||||
--------
|
--------
|
||||||
@ -147,7 +147,7 @@ you should fork Solidity and add your personal fork as a second remote:
|
|||||||
git remote add personal git@github.com:username/solidity.git
|
git remote add personal git@github.com:username/solidity.git
|
||||||
|
|
||||||
Note that webthree-umbrella uses submodules, so solidity is its own git
|
Note that webthree-umbrella uses submodules, so solidity is its own git
|
||||||
repository, but its settings are not stored in :code:`.git/config`, but in
|
repository, but its settings are not stored in ``.git/config``, but in
|
||||||
:code:`webthree-umbrella/.git/modules/solidity/config`.
|
``webthree-umbrella/.git/modules/solidity/config``.
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,20 +32,20 @@ Storage
|
|||||||
|
|
||||||
A contract in the sense of Solidity is a collection of code (its functions) and
|
A contract in the sense of Solidity is a collection of code (its functions) and
|
||||||
data (its *state*) that resides at a specific address on the Ethereum
|
data (its *state*) that resides at a specific address on the Ethereum
|
||||||
blockchain. The line :code:`uint storedData;` declares a state variable called :code:`storedData` of
|
blockchain. The line ``uint storedData;`` declares a state variable called ``storedData`` of
|
||||||
type :code:`uint` (unsigned integer of 256 bits). You can think of it as a single slot
|
type ``uint`` (unsigned integer of 256 bits). You can think of it as a single slot
|
||||||
in a database that can be queried and altered by calling functions of the
|
in a database that can be queried and altered by calling functions of the
|
||||||
code that manages the database. In the case of Ethereum, this is always the owning
|
code that manages the database. In the case of Ethereum, this is always the owning
|
||||||
contract. And in this case, the functions :code:`set` and :code:`get` can be used to modify
|
contract. And in this case, the functions ``set`` and ``get`` can be used to modify
|
||||||
or retrieve the value of the variable.
|
or retrieve the value of the variable.
|
||||||
|
|
||||||
To access a state variable, you do not need the prefix :code:`this.` as is common in
|
To access a state variable, you do not need the prefix ``this.`` as is common in
|
||||||
other languages.
|
other languages.
|
||||||
|
|
||||||
This contract does not yet do much apart from (due to the infrastructure
|
This contract does not yet do much apart from (due to the infrastructure
|
||||||
built by Ethereum) allowing anyone to store a single number that is accessible by
|
built by Ethereum) allowing anyone to store a single number that is accessible by
|
||||||
anyone in the world without (feasible) a way to prevent you from publishing
|
anyone in the world without (feasible) a way to prevent you from publishing
|
||||||
this number. Of course, anyone could just call :code:`set` again with a different value
|
this number. Of course, anyone could just call ``set`` again with a different value
|
||||||
and overwrite your number, but the number will still be stored in the history
|
and overwrite your number, but the number will still be stored in the history
|
||||||
of the blockchain. Later, we will see how you can impose access restrictions
|
of the blockchain. Later, we will see how you can impose access restrictions
|
||||||
so that only you can alter the number.
|
so that only you can alter the number.
|
||||||
@ -98,11 +98,11 @@ registering with username and password - all you need is an Ethereum keypair.
|
|||||||
|
|
||||||
This contract introduces some new concepts, let us go through them one by one.
|
This contract introduces some new concepts, let us go through them one by one.
|
||||||
|
|
||||||
The line :code:`address public minter;` declares a state variable of type address
|
The line ``address public minter;`` declares a state variable of type address
|
||||||
that is publicly accessible. The :code:`address` type is a 160 bit value
|
that is publicly accessible. The ``address`` type is a 160 bit value
|
||||||
that does not allow any arithmetic operations. It is suitable for
|
that does not allow any arithmetic operations. It is suitable for
|
||||||
storing addresses of contracts or keypairs belonging to external
|
storing addresses of contracts or keypairs belonging to external
|
||||||
persons. The keyword :code:`public` automatically generates a function that
|
persons. The keyword ``public`` automatically generates a function that
|
||||||
allows you to access the current value of the state variable.
|
allows you to access the current value of the state variable.
|
||||||
Without this keyword, other contracts have no way to access the variable
|
Without this keyword, other contracts have no way to access the variable
|
||||||
and only the code of this contract can write to it.
|
and only the code of this contract can write to it.
|
||||||
@ -117,7 +117,7 @@ get the idea - the compiler figures that out for you.
|
|||||||
|
|
||||||
.. index:: mapping
|
.. index:: mapping
|
||||||
|
|
||||||
The next line, :code:`mapping (address => uint) public balances;` also
|
The next line, ``mapping (address => uint) public balances;`` also
|
||||||
creates a public state variable, but it is a more complex datatype.
|
creates a public state variable, but it is a more complex datatype.
|
||||||
The type maps addresses to unsigned integers.
|
The type maps addresses to unsigned integers.
|
||||||
Mappings can be seen as hashtables which are
|
Mappings can be seen as hashtables which are
|
||||||
@ -127,7 +127,7 @@ too far, though, as it is neither possible to obtain a list of all keys of
|
|||||||
a mapping, nor a list of all values. So either keep in mind (or
|
a mapping, nor a list of all values. So either keep in mind (or
|
||||||
better, keep a list or use a more advanced data type) what you
|
better, keep a list or use a more advanced data type) what you
|
||||||
added to the mapping or use it in a context where this is not needed,
|
added to the mapping or use it in a context where this is not needed,
|
||||||
like this one. The accessor function created by the :code:`public` keyword
|
like this one. The accessor function created by the ``public`` keyword
|
||||||
is a bit more complex in this case. It roughly looks like the
|
is a bit more complex in this case. It roughly looks like the
|
||||||
following::
|
following::
|
||||||
|
|
||||||
@ -140,12 +140,12 @@ single account.
|
|||||||
|
|
||||||
.. index:: event
|
.. index:: event
|
||||||
|
|
||||||
The line :code:`event Sent(address from, address to, uint value);` declares
|
The line ``event Sent(address from, address to, uint value);`` declares
|
||||||
a so-called "event" which is fired in the last line of the function
|
a so-called "event" which is fired in the last line of the function
|
||||||
:code:`send`. User interfaces (as well as server appliances of course) can
|
``send``. User interfaces (as well as server appliances of course) can
|
||||||
listen for those events being fired on the blockchain without much
|
listen for those events being fired on the blockchain without much
|
||||||
cost. As soon as it is fired, the listener will also receive the
|
cost. As soon as it is fired, the listener will also receive the
|
||||||
arguments :code:`from`, :code:`to` and :code:`value`, which makes it easy to track
|
arguments ``from``, ``to`` and ``value``, which makes it easy to track
|
||||||
transactions. In order to listen for this event, you would use ::
|
transactions. In order to listen for this event, you would use ::
|
||||||
|
|
||||||
Coin.Sent().watch({}, '', function(error, result) {
|
Coin.Sent().watch({}, '', function(error, result) {
|
||||||
@ -159,22 +159,22 @@ transactions. In order to listen for this event, you would use ::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Note how the automatically generated function :code:`balances` is called from
|
Note how the automatically generated function ``balances`` is called from
|
||||||
the user interface.
|
the user interface.
|
||||||
|
|
||||||
.. index:: coin
|
.. index:: coin
|
||||||
|
|
||||||
The special function :code:`Coin` is the
|
The special function ``Coin`` is the
|
||||||
constructor which is run during creation of the contract and
|
constructor which is run during creation of the contract and
|
||||||
cannot be called afterwards. It permanently stores the address of the person creating the
|
cannot be called afterwards. It permanently stores the address of the person creating the
|
||||||
contract: :code:`msg` (together with :code:`tx` and :code:`block`) is a magic global variable that
|
contract: ``msg`` (together with ``tx`` and ``block``) is a magic global variable that
|
||||||
contains some properties which allow access to the blockchain. :code:`msg.sender` is
|
contains some properties which allow access to the blockchain. ``msg.sender`` is
|
||||||
always the address where the current (external) function call came from.
|
always the address where the current (external) function call came from.
|
||||||
|
|
||||||
Finally, the functions that will actually end up with the contract and can be called
|
Finally, the functions that will actually end up with the contract and can be called
|
||||||
by users and contracts alike are :code:`mint` and :code:`send`.
|
by users and contracts alike are ``mint`` and ``send``.
|
||||||
If :code:`mint` is called by anyone except the account that created the contract,
|
If ``mint`` is called by anyone except the account that created the contract,
|
||||||
nothing will happen. On the other hand, :code:`send` can be used by anyone (who already
|
nothing will happen. On the other hand, ``send`` can be used by anyone (who already
|
||||||
has some of these coins) to send coins to anyone else. Note that if you use
|
has some of these coins) to send coins to anyone else. Note that if you use
|
||||||
this contract to send coins to an address, you will not see anything when you
|
this contract to send coins to an address, you will not see anything when you
|
||||||
look at that address on a blockchain explorer, because the fact that you sent
|
look at that address on a blockchain explorer, because the fact that you sent
|
||||||
@ -301,7 +301,7 @@ If the target account contains code, that code is executed and
|
|||||||
the payload is provided as input data.
|
the payload is provided as input data.
|
||||||
|
|
||||||
If the target account is the zero-account (the account with the
|
If the target account is the zero-account (the account with the
|
||||||
address :code:`0`), the transaction creates a **new contract**.
|
address ``0``), the transaction creates a **new contract**.
|
||||||
As already mentioned, the address of that contract is not
|
As already mentioned, the address of that contract is not
|
||||||
the zero address but an address derived from the sender and
|
the zero address but an address derived from the sender and
|
||||||
its number of transaction sent (the "nonce"). The payload
|
its number of transaction sent (the "nonce"). The payload
|
||||||
@ -323,7 +323,7 @@ the transaction and to pay for this execution. While the EVM executes the
|
|||||||
transaction, the gas is gradually depleted according to specific rules.
|
transaction, the gas is gradually depleted according to specific rules.
|
||||||
|
|
||||||
The **gas price** is a value set by the creator of the transaction, who
|
The **gas price** is a value set by the creator of the transaction, who
|
||||||
has to pay :code:`gas_price * gas` up front from the sending account.
|
has to pay ``gas_price * gas`` up front from the sending account.
|
||||||
If some gas is left after the execution, it is refunded in the same way.
|
If some gas is left after the execution, it is refunded in the same way.
|
||||||
|
|
||||||
If the gas is used up at any point (i.e. it is negative),
|
If the gas is used up at any point (i.e. it is negative),
|
||||||
@ -410,7 +410,7 @@ Delegatecall / Callcode and Libraries
|
|||||||
There exists a special variant of a message call, named **delegatecall**
|
There exists a special variant of a message call, named **delegatecall**
|
||||||
which is identical to a message call apart from the fact that
|
which is identical to a message call apart from the fact that
|
||||||
the code at the target address is executed in the context of the calling
|
the code at the target address is executed in the context of the calling
|
||||||
contract and :code:`msg.sender` and :code:`msg.value` do not change their values.
|
contract and ``msg.sender`` and ``msg.value`` do not change their values.
|
||||||
|
|
||||||
This means that a contract can dynamically load code from a different
|
This means that a contract can dynamically load code from a different
|
||||||
address at runtime. Storage, current address and balance still
|
address at runtime. Storage, current address and balance still
|
||||||
@ -452,9 +452,9 @@ Selfdestruct
|
|||||||
============
|
============
|
||||||
|
|
||||||
The only possibility that code is removed from the blockchain is
|
The only possibility that code is removed from the blockchain is
|
||||||
when a contract at that address performs the :code:`SELFDESTRUCT` operation.
|
when a contract at that address performs the ``SELFDESTRUCT`` operation.
|
||||||
The remaining Ether stored at that address is sent to a designated
|
The remaining Ether stored at that address is sent to a designated
|
||||||
target and then the storage and code is removed.
|
target and then the storage and code is removed.
|
||||||
|
|
||||||
Note that even if a contract's code does not contain the :code:`SELFDESTRUCT`
|
Note that even if a contract's code does not contain the ``SELFDESTRUCT``
|
||||||
opcode, it can still perform that operation using delegatecall or callcode.
|
opcode, it can still perform that operation using delegatecall or callcode.
|
||||||
|
@ -28,13 +28,13 @@ current global scope (different than in ES6 but backwards-compatible for Solidit
|
|||||||
|
|
||||||
import * as symbolName from "filename";
|
import * as symbolName from "filename";
|
||||||
|
|
||||||
...creates a new global symbol :code:`symbolName` whose members are all the global symbols from :code:`"filename"`.
|
...creates a new global symbol ``symbolName`` whose members are all the global symbols from ``"filename"``.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
import {symbol1 as alias, symbol2} from "filename";
|
import {symbol1 as alias, symbol2} from "filename";
|
||||||
|
|
||||||
...creates new global symbols :code:`alias` and :code:`symbol2` which reference :code:`symbol1` and :code:`symbol2` from :code:`"filename"`, respectively.
|
...creates new global symbols ``alias`` and ``symbol2`` which reference ``symbol1`` and ``symbol2`` from ``"filename"``, respectively.
|
||||||
|
|
||||||
Another syntax is not part of ES6, but probably convenient:
|
Another syntax is not part of ES6, but probably convenient:
|
||||||
|
|
||||||
@ -42,17 +42,17 @@ Another syntax is not part of ES6, but probably convenient:
|
|||||||
|
|
||||||
import "filename" as symbolName;
|
import "filename" as symbolName;
|
||||||
|
|
||||||
...is equivalent to :code:`import * as symbolName from "filename";`.
|
...is equivalent to ``import * as symbolName from "filename";``.
|
||||||
|
|
||||||
Paths
|
Paths
|
||||||
-----
|
-----
|
||||||
|
|
||||||
In the above, :code:`filename` is always treated as a path with :code:`/` as directory separator,
|
In the above, ``filename`` is always treated as a path with ``/`` as directory separator,
|
||||||
:code:`.` as the current and :code:`..` as the parent directory. Path names that do not start
|
``.`` as the current and ``..`` as the parent directory. Path names that do not start
|
||||||
with :code:`.` are treated as absolute paths.
|
with ``.`` are treated as absolute paths.
|
||||||
|
|
||||||
To import a file :code:`x` from the same directory as the current file, use :code:`import "./x" as x;`.
|
To import a file ``x`` from the same directory as the current file, use ``import "./x" as x;``.
|
||||||
If you use :code:`import "x" as x;` instead, a different file could be referenced
|
If you use ``import "x" as x;`` instead, a different file could be referenced
|
||||||
(in a global "include directory").
|
(in a global "include directory").
|
||||||
|
|
||||||
It depends on the compiler (see below) how to actually resolve the paths.
|
It depends on the compiler (see below) how to actually resolve the paths.
|
||||||
@ -64,22 +64,22 @@ Use in actual Compilers
|
|||||||
|
|
||||||
When the compiler is invoked, it is not only possible to specify how to
|
When the compiler is invoked, it is not only possible to specify how to
|
||||||
discover the first element of a path, but it is possible to specify path prefix
|
discover the first element of a path, but it is possible to specify path prefix
|
||||||
remappings so that e.g. :code:`github.com/ethereum/dapp-bin/library` is remapped to
|
remappings so that e.g. ``github.com/ethereum/dapp-bin/library`` is remapped to
|
||||||
:code:`/usr/local/dapp-bin/library` and the compiler will read the files from there. If
|
``/usr/local/dapp-bin/library`` and the compiler will read the files from there. If
|
||||||
remapping keys are prefixes of each other, the longest is tried first. This
|
remapping keys are prefixes of each other, the longest is tried first. This
|
||||||
allows for a "fallback-remapping" with e.g. :code:`""` maps to
|
allows for a "fallback-remapping" with e.g. ``""`` maps to
|
||||||
:code:`"/usr/local/include/solidity"`.
|
``"/usr/local/include/solidity"``.
|
||||||
|
|
||||||
**solc**:
|
**solc**:
|
||||||
|
|
||||||
For solc (the commandline compiler), these remappings are provided as :code:`key=value`
|
For solc (the commandline compiler), these remappings are provided as ``key=value``
|
||||||
arguments, where the :code:`=value` part is optional (and defaults to key in that
|
arguments, where the ``=value`` part is optional (and defaults to key in that
|
||||||
case). All remapping values that are regular files are compiled (including
|
case). All remapping values that are regular files are compiled (including
|
||||||
their dependencies). This mechanism is completely backwards-compatible (as long
|
their dependencies). This mechanism is completely backwards-compatible (as long
|
||||||
as no filename contains a =) and thus not a breaking change.
|
as no filename contains a =) and thus not a breaking change.
|
||||||
|
|
||||||
So as an example, if you clone
|
So as an example, if you clone
|
||||||
:code:`github.com/ethereum/dapp-bin/` locally to :code:`/usr/local/dapp-bin`, you can use
|
``github.com/ethereum/dapp-bin/`` locally to ``/usr/local/dapp-bin``, you can use
|
||||||
the following in your source file:
|
the following in your source file:
|
||||||
|
|
||||||
::
|
::
|
||||||
@ -96,7 +96,7 @@ Note that solc only allows you to include files from certain directories:
|
|||||||
They have to be in the directory (or subdirectory) of one of the explicitly
|
They have to be in the directory (or subdirectory) of one of the explicitly
|
||||||
specified source files or in the directory (or subdirectory) of a remapping
|
specified source files or in the directory (or subdirectory) of a remapping
|
||||||
target. If you want to allow direct absolute includes, just add the
|
target. If you want to allow direct absolute includes, just add the
|
||||||
remapping :code:`=/`.
|
remapping ``=/``.
|
||||||
|
|
||||||
If there are multiple remappings that lead to a valid file, the remapping
|
If there are multiple remappings that lead to a valid file, the remapping
|
||||||
with the longest common prefix is chosen.
|
with the longest common prefix is chosen.
|
||||||
@ -107,7 +107,7 @@ The `browser-based compiler <https://ethereum.github.io/browser-solidity>`_
|
|||||||
provides an automatic remapping for github and will also automatically retrieve
|
provides an automatic remapping for github and will also automatically retrieve
|
||||||
the file over the network:
|
the file over the network:
|
||||||
You can import the iterable mapping by e.g.
|
You can import the iterable mapping by e.g.
|
||||||
:code:`import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;`.
|
``import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;``.
|
||||||
|
|
||||||
Other source code providers may be added in the future.
|
Other source code providers may be added in the future.
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ Other source code providers may be added in the future.
|
|||||||
Comments
|
Comments
|
||||||
========
|
========
|
||||||
|
|
||||||
Single-line comments (:code:`//`) and multi-line comments (:code:`/*...*/`) are possible.
|
Single-line comments (``//``) and multi-line comments (``/*...*/``) are possible.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ Single-line comments (:code:`//`) and multi-line comments (:code:`/*...*/`) are
|
|||||||
|
|
||||||
Additionally, there is another type of comment called a natspec comment,
|
Additionally, there is another type of comment called a natspec comment,
|
||||||
for which the documentation is not yet written. They are written with a
|
for which the documentation is not yet written. They are written with a
|
||||||
triple slash (:code:`///`) or a double asterisk block(:code:`/** ... */`) and
|
triple slash (``///``) or a double asterisk block(``/** ... */``) and
|
||||||
they should be used directly above function declarations or statements.
|
they should be used directly above function declarations or statements.
|
||||||
You can use Doxygen-style tags inside these comments to document
|
You can use Doxygen-style tags inside these comments to document
|
||||||
functions, annotate conditions for formal verification, and provide a
|
functions, annotate conditions for formal verification, and provide a
|
||||||
|
@ -8,7 +8,7 @@ Miscellaneous
|
|||||||
Layout of State Variables in Storage
|
Layout of State Variables in Storage
|
||||||
************************************
|
************************************
|
||||||
|
|
||||||
Statically-sized variables (everything except mapping and dynamically-sized array types) are laid out contiguously in storage starting from position :code:`0`. Multiple items that need less than 32 bytes are packed into a single storage slot if possible, according to the following rules:
|
Statically-sized variables (everything except mapping and dynamically-sized array types) are laid out contiguously in storage starting from position ``0``. Multiple items that need less than 32 bytes are packed into a single storage slot if possible, according to the following rules:
|
||||||
|
|
||||||
- The first item in a storage slot is stored lower-order aligned.
|
- The first item in a storage slot is stored lower-order aligned.
|
||||||
- Elementary types use only that many bytes that are necessary to store them.
|
- Elementary types use only that many bytes that are necessary to store them.
|
||||||
@ -17,17 +17,17 @@ Statically-sized variables (everything except mapping and dynamically-sized arra
|
|||||||
|
|
||||||
The elements of structs and arrays are stored after each other, just as if they were given explicitly.
|
The elements of structs and arrays are stored after each other, just as if they were given explicitly.
|
||||||
|
|
||||||
Due to their unpredictable size, mapping and dynamically-sized array types use a :code:`sha3`
|
Due to their unpredictable size, mapping and dynamically-sized array types use a ``sha3``
|
||||||
computation to find the starting position of the value or the array data. These starting positions are always full stack slots.
|
computation to find the starting position of the value or the array data. These starting positions are always full stack slots.
|
||||||
|
|
||||||
The mapping or the dynamic array itself
|
The mapping or the dynamic array itself
|
||||||
occupies an (unfilled) slot in storage at some position :code:`p` according to the above rule (or by
|
occupies an (unfilled) slot in storage at some position ``p`` according to the above rule (or by
|
||||||
recursively applying this rule for mappings to mappings or arrays of arrays). For a dynamic array, this slot stores the number of elements in the array (byte arrays and strings are an exception here, see below). For a mapping, the slot is unused (but it is needed so that two equal mappings after each other will use a different hash distribution).
|
recursively applying this rule for mappings to mappings or arrays of arrays). For a dynamic array, this slot stores the number of elements in the array (byte arrays and strings are an exception here, see below). For a mapping, the slot is unused (but it is needed so that two equal mappings after each other will use a different hash distribution).
|
||||||
Array data is located at :code:`sha3(p)` and the value corresponding to a mapping key
|
Array data is located at ``sha3(p)`` and the value corresponding to a mapping key
|
||||||
:code:`k` is located at :code:`sha3(k . p)` where :code:`.` is concatenation. If the value is again a
|
``k`` is located at ``sha3(k . p)`` where ``.`` is concatenation. If the value is again a
|
||||||
non-elementary type, the positions are found by adding an offset of :code:`sha3(k . p)`.
|
non-elementary type, the positions are found by adding an offset of ``sha3(k . p)``.
|
||||||
|
|
||||||
:code:`bytes` and :code:`string` store their data in the same slot where also the length is stored if they are short. In particular: If the data is at most :code:`31` bytes long, it is stored in the higher-order bytes (left aligned) and the lowest-order byte stores :code:`length * 2`. If it is longer, the main slot stores :code:`length * 2 + 1` and the data is stored as usual in :code:`sha3(slot)`.
|
``bytes`` and ``string`` store their data in the same slot where also the length is stored if they are short. In particular: If the data is at most ``31`` bytes long, it is stored in the higher-order bytes (left aligned) and the lowest-order byte stores ``length * 2``. If it is longer, the main slot stores ``length * 2 + 1`` and the data is stored as usual in ``sha3(slot)``.
|
||||||
|
|
||||||
So for the following contract snippet::
|
So for the following contract snippet::
|
||||||
|
|
||||||
@ -37,13 +37,13 @@ So for the following contract snippet::
|
|||||||
mapping(uint => mapping(uint => s)) data;
|
mapping(uint => mapping(uint => s)) data;
|
||||||
}
|
}
|
||||||
|
|
||||||
The position of :code:`data[4][9].b` is at :code:`sha3(uint256(9) . sha3(uint256(4) . uint256(1))) + 1`.
|
The position of ``data[4][9].b`` is at ``sha3(uint256(9) . sha3(uint256(4) . uint256(1))) + 1``.
|
||||||
|
|
||||||
*****************
|
*****************
|
||||||
Esoteric Features
|
Esoteric Features
|
||||||
*****************
|
*****************
|
||||||
|
|
||||||
There are some types in Solidity's type system that have no counterpart in the syntax. One of these types are the types of functions. But still, using :code:`var` it is possible to have local variables of these types::
|
There are some types in Solidity's type system that have no counterpart in the syntax. One of these types are the types of functions. But still, using ``var`` it is possible to have local variables of these types::
|
||||||
|
|
||||||
contract FunctionSelector {
|
contract FunctionSelector {
|
||||||
function select(bool useB, uint x) returns (uint z) {
|
function select(bool useB, uint x) returns (uint z) {
|
||||||
@ -61,7 +61,7 @@ There are some types in Solidity's type system that have no counterpart in the s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Calling :code:`select(false, x)` will compute :code:`x * x` and :code:`select(true, x)` will compute :code:`2 * x`.
|
Calling ``select(false, x)`` will compute ``x * x`` and ``select(true, x)`` will compute ``2 * x``.
|
||||||
|
|
||||||
.. index:: optimizer, common subexpression elimination, constant propagation
|
.. index:: optimizer, common subexpression elimination, constant propagation
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ Calling :code:`select(false, x)` will compute :code:`x * x` and :code:`select(tr
|
|||||||
Internals - the Optimizer
|
Internals - the Optimizer
|
||||||
*************************
|
*************************
|
||||||
|
|
||||||
The Solidity optimizer operates on assembly, so it can be and also is used by other languages. It splits the sequence of instructions into basic blocks at JUMPs and JUMPDESTs. Inside these blocks, the instructions are analysed and every modification to the stack, to memory or storage is recorded as an expression which consists of an instruction and a list of arguments which are essentially pointers to other expressions. The main idea is now to find expressions that are always equal (on every input) and combine them into an expression class. The optimizer first tries to find each new expression in a list of already known expressions. If this does not work, the expression is simplified according to rules like :code:`constant + constant = sum_of_constants` or :code:`X * 1 = X`. Since this is done recursively, we can also apply the latter rule if the second factor is a more complex expression where we know that it will always evaluate to one. Modifications to storage and memory locations have to erase knowledge about storage and memory locations which are not known to be different: If we first write to location x and then to location y and both are input variables, the second could overwrite the first, so we actually do not know what is stored at x after we wrote to y. On the other hand, if a simplification of the expression x - y evaluates to a non-zero constant, we know that we can keep our knowledge about what is stored at x.
|
The Solidity optimizer operates on assembly, so it can be and also is used by other languages. It splits the sequence of instructions into basic blocks at JUMPs and JUMPDESTs. Inside these blocks, the instructions are analysed and every modification to the stack, to memory or storage is recorded as an expression which consists of an instruction and a list of arguments which are essentially pointers to other expressions. The main idea is now to find expressions that are always equal (on every input) and combine them into an expression class. The optimizer first tries to find each new expression in a list of already known expressions. If this does not work, the expression is simplified according to rules like ``constant + constant = sum_of_constants`` or ``X * 1 = X``. Since this is done recursively, we can also apply the latter rule if the second factor is a more complex expression where we know that it will always evaluate to one. Modifications to storage and memory locations have to erase knowledge about storage and memory locations which are not known to be different: If we first write to location x and then to location y and both are input variables, the second could overwrite the first, so we actually do not know what is stored at x after we wrote to y. On the other hand, if a simplification of the expression x - y evaluates to a non-zero constant, we know that we can keep our knowledge about what is stored at x.
|
||||||
|
|
||||||
At the end of this process, we know which expressions have to be on the stack in the end and have a list of modifications to memory and storage. This information is stored together with the basic blocks and is used to link them. Furthermore, knowledge about the stack, storage and memory configuration is forwarded to the next block(s). If we know the targets of all JUMP and JUMPI instructions, we can build a complete control flow graph of the program. If there is only one target we do not know (this can happen as in principle, jump targets can be computed from inputs), we have to erase all knowledge about the input state of a block as it can be the target of the unknown JUMP. If a JUMPI is found whose condition evaluates to a constant, it is transformed to an unconditional jump.
|
At the end of this process, we know which expressions have to be on the stack in the end and have a list of modifications to memory and storage. This information is stored together with the basic blocks and is used to link them. Furthermore, knowledge about the stack, storage and memory configuration is forwarded to the next block(s). If we know the targets of all JUMP and JUMPI instructions, we can build a complete control flow graph of the program. If there is only one target we do not know (this can happen as in principle, jump targets can be computed from inputs), we have to erase all knowledge about the input state of a block as it can be the target of the unknown JUMP. If a JUMPI is found whose condition evaluates to a constant, it is transformed to an unconditional jump.
|
||||||
|
|
||||||
@ -103,43 +103,43 @@ even though the instructions contained a jump in the beginning.
|
|||||||
Using the Commandline Compiler
|
Using the Commandline Compiler
|
||||||
******************************
|
******************************
|
||||||
|
|
||||||
One of the build targets of the Solidity repository is :code:`solc`, the solidity commandline compiler.
|
One of the build targets of the Solidity repository is ``solc``, the solidity commandline compiler.
|
||||||
Using :code:`solc --help` provides you with an explanation of all options. The compiler can produce various outputs, ranging from simple binaries and assembly over an abstract syntax tree (parse tree) to estimations of gas usage.
|
Using ``solc --help`` provides you with an explanation of all options. The compiler can produce various outputs, ranging from simple binaries and assembly over an abstract syntax tree (parse tree) to estimations of gas usage.
|
||||||
If you only want to compile a single file, you run it as :code:`solc --bin sourceFile.sol` and it will print the binary. Before you deploy your contract, activate the optimizer while compiling using :code:`solc --optimize --bin sourceFile.sol`. If you want to get some of the more advanced output variants of :code:`solc`, it is probably better to tell it to output everything to separate files using :code:`solc -o outputDirectory --bin --ast --asm sourceFile.sol`.
|
If you only want to compile a single file, you run it as ``solc --bin sourceFile.sol`` and it will print the binary. Before you deploy your contract, activate the optimizer while compiling using ``solc --optimize --bin sourceFile.sol``. If you want to get some of the more advanced output variants of ``solc``, it is probably better to tell it to output everything to separate files using ``solc -o outputDirectory --bin --ast --asm sourceFile.sol``.
|
||||||
|
|
||||||
The commandline compiler will automatically read imported files from the filesystem, but
|
The commandline compiler will automatically read imported files from the filesystem, but
|
||||||
it is also possible to provide path redirects using :code:`prefix=path` in the following way:
|
it is also possible to provide path redirects using ``prefix=path`` in the following way:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
solc github.com/ethereum/dapp-bin/=/usr/local/lib/dapp-bin/ =/usr/local/lib/fallback file.sol
|
solc github.com/ethereum/dapp-bin/=/usr/local/lib/dapp-bin/ =/usr/local/lib/fallback file.sol
|
||||||
|
|
||||||
This essentially instructs the compiler to search for anything starting with
|
This essentially instructs the compiler to search for anything starting with
|
||||||
:code:`github.com/ethereum/dapp-bin/` under :code:`/usr/local/lib/dapp-bin` and if it does not
|
``github.com/ethereum/dapp-bin/`` under ``/usr/local/lib/dapp-bin`` and if it does not
|
||||||
find the file there, it will look at :code:`/usr/local/lib/fallback` (the empty prefix
|
find the file there, it will look at ``/usr/local/lib/fallback`` (the empty prefix
|
||||||
always matches). :code:`solc` will not read files from the filesystem that lie outside of
|
always matches). ``solc`` will not read files from the filesystem that lie outside of
|
||||||
the remapping targets and outside of the directories where explicitly specified source
|
the remapping targets and outside of the directories where explicitly specified source
|
||||||
files reside, so things like :code:`import "/etc/passwd";` only work if you add :code:`=/` as a remapping.
|
files reside, so things like ``import "/etc/passwd";`` only work if you add ``=/`` as a remapping.
|
||||||
|
|
||||||
If there are multiple matches due to remappings, the one with the longest common prefix is selected.
|
If there are multiple matches due to remappings, the one with the longest common prefix is selected.
|
||||||
|
|
||||||
If your contracts use :ref:`libraries <libraries>`, you will notice that the bytecode contains substrings of the form :code:`__LibraryName______`. You can use :code:`solc` as a linker meaning that it will insert the library addresses for you at those points:
|
If your contracts use :ref:`libraries <libraries>`, you will notice that the bytecode contains substrings of the form ``__LibraryName______``. You can use ``solc`` as a linker meaning that it will insert the library addresses for you at those points:
|
||||||
|
|
||||||
Either add :code:`--libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456"` to your command to provide an address for each library or store the string in a file (one library per line) and run :code:`solc` using :code:`--libraries fileName`.
|
Either add ``--libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456"`` to your command to provide an address for each library or store the string in a file (one library per line) and run ``solc`` using ``--libraries fileName``.
|
||||||
|
|
||||||
If :code:`solc` is called with the option :code:`--link`, all input files are interpreted to be unlinked binaries (hex-encoded) in the :code:`__LibraryName____`-format given above and are linked in-place (if the input is read from stdin, it is written to stdout). All options except :code:`--libraries` are ignored (including :code:`-o`) in this case.
|
If ``solc`` is called with the option ``--link``, all input files are interpreted to be unlinked binaries (hex-encoded) in the ``__LibraryName____``-format given above and are linked in-place (if the input is read from stdin, it is written to stdout). All options except ``--libraries`` are ignored (including ``-o``) in this case.
|
||||||
|
|
||||||
***************
|
***************
|
||||||
Tips and Tricks
|
Tips and Tricks
|
||||||
***************
|
***************
|
||||||
|
|
||||||
* Use :code:`delete` on arrays to delete all its elements.
|
* Use ``delete`` on arrays to delete all its elements.
|
||||||
* Use shorter types for struct elements and sort them such that short types are grouped together. This can lower the gas costs as multiple SSTORE operations might be combined into a single (SSTORE costs 5000 or 20000 gas, so this is what you want to optimise). Use the gas price estimator (with optimiser enabled) to check!
|
* Use shorter types for struct elements and sort them such that short types are grouped together. This can lower the gas costs as multiple SSTORE operations might be combined into a single (SSTORE costs 5000 or 20000 gas, so this is what you want to optimise). Use the gas price estimator (with optimiser enabled) to check!
|
||||||
* Make your state variables public - the compiler will create :ref:`getters <visibility-and-accessors>` for you for free.
|
* Make your state variables public - the compiler will create :ref:`getters <visibility-and-accessors>` for you for free.
|
||||||
* If you end up checking conditions on input or state a lot at the beginning of your functions, try using :ref:`modifiers`.
|
* If you end up checking conditions on input or state a lot at the beginning of your functions, try using :ref:`modifiers`.
|
||||||
* If your contract has a function called :code:`send` but you want to use the built-in send-function, use :code:`address(contractVariable).send(amount)`.
|
* If your contract has a function called ``send`` but you want to use the built-in send-function, use ``address(contractVariable).send(amount)``.
|
||||||
* If you do **not** want your contracts to receive ether when called via :code:`send`, you can add a throwing fallback function :code:`function() { throw; }`.
|
* If you do **not** want your contracts to receive ether when called via ``send``, you can add a throwing fallback function ``function() { throw; }``.
|
||||||
* Initialise storage structs with a single assignment: :code:`x = MyStruct({a: 1, b: 2});`
|
* Initialise storage structs with a single assignment: ``x = MyStruct({a: 1, b: 2});``
|
||||||
|
|
||||||
********
|
********
|
||||||
Pitfalls
|
Pitfalls
|
||||||
@ -147,7 +147,7 @@ Pitfalls
|
|||||||
|
|
||||||
Unfortunately, there are some subtleties the compiler does not yet warn you about.
|
Unfortunately, there are some subtleties the compiler does not yet warn you about.
|
||||||
|
|
||||||
- In :code:`for (var i = 0; i < arrayName.length; i++) { ... }`, the type of :code:`i` will be :code:`uint8`, because this is the smallest type that is required to hold the value :code:`0`. If the array has more than 255 elements, the loop will not terminate.
|
- In ``for (var i = 0; i < arrayName.length; i++) { ... }``, the type of ``i`` will be ``uint8``, because this is the smallest type that is required to hold the value ``0``. If the array has more than 255 elements, the loop will not terminate.
|
||||||
|
|
||||||
**********
|
**********
|
||||||
Cheatsheet
|
Cheatsheet
|
||||||
@ -158,30 +158,30 @@ Cheatsheet
|
|||||||
Global Variables
|
Global Variables
|
||||||
================
|
================
|
||||||
|
|
||||||
- :code:`block.coinbase` (:code:`address`): current block miner's address
|
- ``block.coinbase`` (``address``): current block miner's address
|
||||||
- :code:`block.difficulty` (:code:`uint`): current block difficulty
|
- ``block.difficulty`` (``uint``): current block difficulty
|
||||||
- :code:`block.gaslimit` (:code:`uint`): current block gaslimit
|
- ``block.gaslimit`` (``uint``): current block gaslimit
|
||||||
- :code:`block.number` (:code:`uint`): current block number
|
- ``block.number`` (``uint``): current block number
|
||||||
- :code:`block.blockhash` (:code:`function(uint) returns (bytes32)`): hash of the given block - only works for 256 most recent blocks
|
- ``block.blockhash`` (``function(uint) returns (bytes32)``): hash of the given block - only works for 256 most recent blocks
|
||||||
- :code:`block.timestamp` (:code:`uint`): current block timestamp
|
- ``block.timestamp`` (``uint``): current block timestamp
|
||||||
- :code:`msg.data` (:code:`bytes`): complete calldata
|
- ``msg.data`` (``bytes``): complete calldata
|
||||||
- :code:`msg.gas` (:code:`uint`): remaining gas
|
- ``msg.gas`` (``uint``): remaining gas
|
||||||
- :code:`msg.sender` (:code:`address`): sender of the message (current call)
|
- ``msg.sender`` (``address``): sender of the message (current call)
|
||||||
- :code:`msg.value` (:code:`uint`): number of wei sent with the message
|
- ``msg.value`` (``uint``): number of wei sent with the message
|
||||||
- :code:`now` (:code:`uint`): current block timestamp (alias for :code:`block.timestamp`)
|
- ``now`` (``uint``): current block timestamp (alias for ``block.timestamp``)
|
||||||
- :code:`tx.gasprice` (:code:`uint`): gas price of the transaction
|
- ``tx.gasprice`` (``uint``): gas price of the transaction
|
||||||
- :code:`tx.origin` (:code:`address`): sender of the transaction (full call chain)
|
- ``tx.origin`` (``address``): sender of the transaction (full call chain)
|
||||||
- :code:`sha3(...) returns (bytes32)`: compute the Ethereum-SHA3 hash of the (tightly packed) arguments
|
- ``sha3(...) returns (bytes32)``: compute the Ethereum-SHA3 hash of the (tightly packed) arguments
|
||||||
- :code:`sha256(...) returns (bytes32)`: compute the SHA256 hash of the (tightly packed) arguments
|
- ``sha256(...) returns (bytes32)``: compute the SHA256 hash of the (tightly packed) arguments
|
||||||
- :code:`ripemd160(...) returns (bytes20)`: compute RIPEMD of 256 the (tightly packed) arguments
|
- ``ripemd160(...) returns (bytes20)``: compute RIPEMD of 256 the (tightly packed) arguments
|
||||||
- :code:`ecrecover(bytes32, uint8, bytes32, bytes32) returns (address)`: recover address associated with the public key from elliptic curve signature
|
- ``ecrecover(bytes32, uint8, bytes32, bytes32) returns (address)``: recover address associated with the public key from elliptic curve signature
|
||||||
- :code:`addmod(uint x, uint y, uint k) returns (uint)`: compute :code:`(x + y) % k` where the addition is performed with arbitrary precision and does not wrap around at :code:`2**256`.
|
- ``addmod(uint x, uint y, uint k) returns (uint)``: compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``.
|
||||||
- :code:`mulmod(uint x, uint y, uint k) returns (uint)`: compute :code:`(x * y) % k` where the multiplication is performed with arbitrary precision and does not wrap around at :code:`2**256`.
|
- ``mulmod(uint x, uint y, uint k) returns (uint)``: compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``.
|
||||||
- :code:`this` (current contract's type): the current contract, explicitly convertible to :code:`address`
|
- ``this`` (current contract's type): the current contract, explicitly convertible to ``address``
|
||||||
- :code:`super`: the contract one level higher in the inheritance hierarchy
|
- ``super``: the contract one level higher in the inheritance hierarchy
|
||||||
- :code:`selfdestruct(address)`: destroy the current contract, sending its funds to the given address
|
- ``selfdestruct(address)``: destroy the current contract, sending its funds to the given address
|
||||||
- :code:`<address>.balance`: balance of the address in Wei
|
- ``<address>.balance``: balance of the address in Wei
|
||||||
- :code:`<address>.send(uint256) returns (bool)`: send given amount of Wei to address, returns :code:`false` on failure.
|
- ``<address>.send(uint256) returns (bool)``: send given amount of Wei to address, returns ``false`` on failure.
|
||||||
|
|
||||||
.. index:: visibility, public, private, external, internal
|
.. index:: visibility, public, private, external, internal
|
||||||
|
|
||||||
@ -194,10 +194,10 @@ Function Visibility Specifiers
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
- :code:`public`: visible externally and internally (creates accessor function for storage/state variables)
|
- ``public``: visible externally and internally (creates accessor function for storage/state variables)
|
||||||
- :code:`private`: only visible in the current contract
|
- ``private``: only visible in the current contract
|
||||||
- :code:`external`: only visible externally (only for functions) - i.e. can only be message-called (via :code:`this.fun`)
|
- ``external``: only visible externally (only for functions) - i.e. can only be message-called (via ``this.fun``)
|
||||||
- :code:`internal`: only visible internally
|
- ``internal``: only visible internally
|
||||||
|
|
||||||
|
|
||||||
.. index:: modifiers, constant, anonymous, indexed
|
.. index:: modifiers, constant, anonymous, indexed
|
||||||
@ -205,8 +205,8 @@ Function Visibility Specifiers
|
|||||||
Modifiers
|
Modifiers
|
||||||
=========
|
=========
|
||||||
|
|
||||||
- :code:`constant` for state variables: Disallows assignment (except initialisation), does not occupy storage slot.
|
- ``constant`` for state variables: Disallows assignment (except initialisation), does not occupy storage slot.
|
||||||
- :code:`constant` for functions: Disallows modification of state - this is not enforced yet.
|
- ``constant`` for functions: Disallows modification of state - this is not enforced yet.
|
||||||
- :code:`anonymous` for events: Does not store event signature as topic.
|
- ``anonymous`` for events: Does not store event signature as topic.
|
||||||
- :code:`indexed` for event parameters: Stores the parameter as topic.
|
- ``indexed`` for event parameters: Stores the parameter as topic.
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ The persons behind the addresses can then choose
|
|||||||
to either vote themselves or to delegate their
|
to either vote themselves or to delegate their
|
||||||
vote to a person they trust.
|
vote to a person they trust.
|
||||||
|
|
||||||
At the end of the voting time, :code:`winningProposal()`
|
At the end of the voting time, ``winningProposal()``
|
||||||
will return the proposal with the largest number
|
will return the proposal with the largest number
|
||||||
of votes.
|
of votes.
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ Yes::
|
|||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
spam( ham[ 1 ], Coin( { name: "ham" } ) );`
|
spam( ham[ 1 ], Coin( { name: "ham" } ) );
|
||||||
|
|
||||||
Immediately before a comma, semicolon:
|
Immediately before a comma, semicolon:
|
||||||
|
|
||||||
@ -221,11 +221,11 @@ No::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The same recommendations apply to the control structures :code:`if`, :code:`else`, :code:`while`,
|
The same recommendations apply to the control structures ``if``, ``else``, ``while``,
|
||||||
and :code:`for`.
|
and ``for``.
|
||||||
|
|
||||||
Additionally there should be a single space between the control structures
|
Additionally there should be a single space between the control structures
|
||||||
:code:`if`, :code:`while`, and :code:`for` and the parenthetic block representing the
|
``if``, ``while``, and ``for`` and the parenthetic block representing the
|
||||||
conditional, as well as a single space between the conditional parenthetic
|
conditional, as well as a single space between the conditional parenthetic
|
||||||
block and the opening brace.
|
block and the opening brace.
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ No::
|
|||||||
value: 42
|
value: 42
|
||||||
}));
|
}));
|
||||||
|
|
||||||
For :code:`if` blocks which have an :code:`else` or :code:`else if` clause, the :code:`else` should be
|
For ``if`` blocks which have an ``else`` or ``else if`` clause, the ``else`` should be
|
||||||
placed on it's own line following the previous closing parenthesis. The
|
placed on it's own line following the previous closing parenthesis. The
|
||||||
parenthesis for the else block should follow the same rules as the other
|
parenthesis for the else block should follow the same rules as the other
|
||||||
conditional control structures.
|
conditional control structures.
|
||||||
|
166
docs/types.rst
166
docs/types.rst
@ -26,30 +26,30 @@ are used as function arguments or in assignments.
|
|||||||
Booleans
|
Booleans
|
||||||
--------
|
--------
|
||||||
|
|
||||||
:code:`bool`: The possible values are constants :code:`true` and :code:`false`.
|
``bool``: The possible values are constants ``true`` and ``false``.
|
||||||
|
|
||||||
Operators:
|
Operators:
|
||||||
|
|
||||||
* :code:`!` (logical negation)
|
* ``!`` (logical negation)
|
||||||
* :code:`&&` (logical conjunction, "and")
|
* ``&&`` (logical conjunction, "and")
|
||||||
* :code:`||` (logical disjunction, "or")
|
* ``||`` (logical disjunction, "or")
|
||||||
* :code:`==` (equality)
|
* ``==`` (equality)
|
||||||
* :code:`!=` (inequality)
|
* ``!=`` (inequality)
|
||||||
|
|
||||||
The operators :code:`||` and :code:`&&` apply the common short-circuiting rules. This means that in the expression :code:`f(x) || g(y)`, if :code:`f(x)` evaluates to :code:`true`, :code:`g(y)` will not be evaluated even if it may have side-effects.
|
The operators ``||`` and ``&&`` apply the common short-circuiting rules. This means that in the expression ``f(x) || g(y)``, if ``f(x)`` evaluates to ``true``, ``g(y)`` will not be evaluated even if it may have side-effects.
|
||||||
|
|
||||||
.. index:: ! uint, ! int, ! integer
|
.. index:: ! uint, ! int, ! integer
|
||||||
|
|
||||||
Integers
|
Integers
|
||||||
--------
|
--------
|
||||||
|
|
||||||
:code:`int` / :code:`uint`: Signed and unsigned integers of various sizes. Keywords :code:`uint8` to :code:`uint256` in steps of :code:`8` (unsigned of 8 up to 256 bits) and :code:`int8` to :code:`int256`. :code:`uint` and :code:`int` are aliases for :code:`uint256` and :code:`int256`, respectively.
|
``int`` / ``uint``: Signed and unsigned integers of various sizes. Keywords ``uint8`` to ``uint256`` in steps of ``8`` (unsigned of 8 up to 256 bits) and ``int8`` to ``int256``. ``uint`` and ``int`` are aliases for ``uint256`` and ``int256``, respectively.
|
||||||
|
|
||||||
Operators:
|
Operators:
|
||||||
|
|
||||||
* Comparisons: :code:`<=`, :code:`<`, :code:`==`, :code:`!=`, :code:`>=`, :code:`>` (evaluate to :code:`bool`)
|
* Comparisons: ``<=``, ``<``, ``==``, ``!=``, ``>=``, ``>`` (evaluate to ``bool``)
|
||||||
* Bit operators: :code:`&`, :code:`|`, :code:`^` (bitwise exclusive or), :code:`~` (bitwise negation)
|
* Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation)
|
||||||
* Arithmetic operators: :code:`+`, :code:`-`, unary :code:`-`, unary :code:`+`, :code:`*`, :code:`/`, :code:`%` (remainder), :code:`**` (exponentiation)
|
* Arithmetic operators: ``+``, ``-``, unary ``-``, unary ``+``, ``*``, ``/``, ``%`` (remainder), ``**`` (exponentiation)
|
||||||
|
|
||||||
Division always truncates (it just maps to the DIV opcode of the EVM), but it does not truncate if both
|
Division always truncates (it just maps to the DIV opcode of the EVM), but it does not truncate if both
|
||||||
operators are :ref:`literals<rational_literals>` (or literal expressions).
|
operators are :ref:`literals<rational_literals>` (or literal expressions).
|
||||||
@ -61,19 +61,19 @@ operators are :ref:`literals<rational_literals>` (or literal expressions).
|
|||||||
Address
|
Address
|
||||||
-------
|
-------
|
||||||
|
|
||||||
:code:`address`: Holds a 20 byte value (size of an Ethereum address). Address types also have members and serve as base for all contracts.
|
``address``: Holds a 20 byte value (size of an Ethereum address). Address types also have members and serve as base for all contracts.
|
||||||
|
|
||||||
Operators:
|
Operators:
|
||||||
|
|
||||||
* :code:`<=`, :code:`<`, :code:`==`, :code:`!=`, :code:`>=` and :code:`>`
|
* ``<=``, ``<``, ``==``, ``!=``, ``>=`` and ``>``
|
||||||
|
|
||||||
Members of Addresses
|
Members of Addresses
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
* :code:`balance` and :code:`send`
|
* ``balance`` and ``send``
|
||||||
|
|
||||||
It is possible to query the balance of an address using the property :code:`balance`
|
It is possible to query the balance of an address using the property ``balance``
|
||||||
and to send Ether (in units of wei) to an address using the :code:`send` function:
|
and to send Ether (in units of wei) to an address using the ``send`` function:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -82,12 +82,12 @@ and to send Ether (in units of wei) to an address using the :code:`send` functio
|
|||||||
if (x.balance < 10 && myAddress.balance >= 10) x.send(10);
|
if (x.balance < 10 && myAddress.balance >= 10) x.send(10);
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
If :code:`x` is a contract address, its code (more specifically: its fallback function, if present) will be executed together with the :code:`send` call (this is a limitation of the EVM and cannot be prevented). If that execution runs out of gas or fails in any way, the Ether transfer will be reverted. In this case, :code:`send` returns :code:`false`.
|
If ``x`` is a contract address, its code (more specifically: its fallback function, if present) will be executed together with the ``send`` call (this is a limitation of the EVM and cannot be prevented). If that execution runs out of gas or fails in any way, the Ether transfer will be reverted. In this case, ``send`` returns ``false``.
|
||||||
|
|
||||||
* :code:`call`, :code:`callcode` and :code:`delegatecall`
|
* ``call``, ``callcode`` and ``delegatecall``
|
||||||
|
|
||||||
Furthermore, to interface with contracts that do not adhere to the ABI,
|
Furthermore, to interface with contracts that do not adhere to the ABI,
|
||||||
the function :code:`call` is provided which takes an arbitrary number of arguments of any type. These arguments are padded to 32 bytes and concatenated. One exception is the case where the first argument is encoded to exactly four bytes. In this case, it is not padded to allow the use of function signatures here.
|
the function ``call`` is provided which takes an arbitrary number of arguments of any type. These arguments are padded to 32 bytes and concatenated. One exception is the case where the first argument is encoded to exactly four bytes. In this case, it is not padded to allow the use of function signatures here.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -95,15 +95,15 @@ the function :code:`call` is provided which takes an arbitrary number of argumen
|
|||||||
nameReg.call("register", "MyName");
|
nameReg.call("register", "MyName");
|
||||||
nameReg.call(bytes4(sha3("fun(uint256)")), a);
|
nameReg.call(bytes4(sha3("fun(uint256)")), a);
|
||||||
|
|
||||||
:code:`call` returns a boolean indicating whether the invoked function terminated (:code:`true`) or caused an EVM exception (`false:code:`). It is not possible to access the actual data returned (for this we would need to know the encoding and size in advance).
|
``call`` returns a boolean indicating whether the invoked function terminated (``true``) or caused an EVM exception (`false:code:`). It is not possible to access the actual data returned (for this we would need to know the encoding and size in advance).
|
||||||
|
|
||||||
In a similar way, the function `delegatecall:code:` can be used: The difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of `delegatecall:code:` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for delegatecall to be used. Prior to homestead, only a limited variant called `callcode:code:` was available that did not provide access to the original `msg.sender:code:` and `msg.value:code:` values.
|
In a similar way, the function ``delegatecall`` can be used: The difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of ``delegatecall`` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for delegatecall to be used. Prior to homestead, only a limited variant called ``callcode`` was available that did not provide access to the original ``msg.sender`` and ``msg.value`` values.
|
||||||
|
|
||||||
All three functions `call:code:`, `delegatecall:code:` and `callcode:code:` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity.
|
All three functions ``call``, ``delegatecall`` and ``callcode`` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
All contracts inherit the members of address, so it is possible to query the balance of the
|
All contracts inherit the members of address, so it is possible to query the balance of the
|
||||||
current contract using :code:`this.balance`.
|
current contract using ``this.balance``.
|
||||||
|
|
||||||
.. index:: byte array, bytes32
|
.. index:: byte array, bytes32
|
||||||
|
|
||||||
@ -111,29 +111,29 @@ All three functions `call:code:`, `delegatecall:code:` and `callcode:code:` are
|
|||||||
Fixed-size byte arrays
|
Fixed-size byte arrays
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
:code:`bytes1`, :code:`bytes2`, :code:`bytes3`, ..., :code:`bytes32`. :code:`byte` is an alias for :code:`bytes1`.
|
``bytes1``, ``bytes2``, ``bytes3``, ..., ``bytes32``. ``byte`` is an alias for ``bytes1``.
|
||||||
|
|
||||||
Operators:
|
Operators:
|
||||||
|
|
||||||
* Comparisons: :code:`<=`, :code:`<`, :code:`==`, :code:`!=`, :code:`>=`, :code:`>` (evaluate to :code:`bool`)
|
* Comparisons: ``<=``, ``<``, ``==``, ``!=``, ``>=``, ``>`` (evaluate to ``bool``)
|
||||||
* Bit operators: :code:`&`, :code:`|`, :code:`^` (bitwise exclusive or), :code:`~` (bitwise negation)
|
* Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation)
|
||||||
* Index access: If :code:`x` is of type :code:`bytesI`, then :code:`x[k]` for :code:`0 <= k < I` returns the :code:`k` th byte (read-only).
|
* Index access: If ``x`` is of type ``bytesI``, then ``x[k]`` for ``0 <= k < I`` returns the ``k`` th byte (read-only).
|
||||||
|
|
||||||
Members:
|
Members:
|
||||||
|
|
||||||
* :code:`.length` yields the fixed length of the byte array (read-only).
|
* ``.length`` yields the fixed length of the byte array (read-only).
|
||||||
|
|
||||||
Dynamically-sized byte array
|
Dynamically-sized byte array
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
:code:`bytes`:
|
``bytes``:
|
||||||
Dynamically-sized byte array, see :ref:`arrays`. Not a value-type!
|
Dynamically-sized byte array, see :ref:`arrays`. Not a value-type!
|
||||||
:code:`string`:
|
``string``:
|
||||||
Dynamically-sized UTF8-encoded string, see :ref:`arrays`. Not a value-type!
|
Dynamically-sized UTF8-encoded string, see :ref:`arrays`. Not a value-type!
|
||||||
|
|
||||||
As a rule of thumb, use :code:`bytes` for arbitrary-length raw byte data and :code:`string`
|
As a rule of thumb, use ``bytes`` for arbitrary-length raw byte data and ``string``
|
||||||
for arbitrary-length string (utf-8) data. If you can limit the length to a certain
|
for arbitrary-length string (utf-8) data. If you can limit the length to a certain
|
||||||
number of bytes, always use one of :code:`bytes1` to :code:`bytes32` because they are much cheaper.
|
number of bytes, always use one of ``bytes1`` to ``bytes32`` because they are much cheaper.
|
||||||
|
|
||||||
.. index:: ! ufixed, ! fixed, ! fixed point number
|
.. index:: ! ufixed, ! fixed, ! fixed point number
|
||||||
|
|
||||||
@ -153,16 +153,16 @@ All number literals retain arbitrary precision until they are converted to a non
|
|||||||
using them together with a non-literal type). This means that computations do not overflow but also
|
using them together with a non-literal type). This means that computations do not overflow but also
|
||||||
divisions do not truncate.
|
divisions do not truncate.
|
||||||
|
|
||||||
For example, :code:`(2**800 + 1) - 2**800` results in the constant :code:`1` (of type :code:`uint8`)
|
For example, ``(2**800 + 1) - 2**800`` results in the constant ``1`` (of type ``uint8``)
|
||||||
although intermediate results would not even fit the machine word size. Furthermore, :code:`.5 * 8` results
|
although intermediate results would not even fit the machine word size. Furthermore, ``.5 * 8`` results
|
||||||
in the integer :code:`4` (although non-integers were used in between).
|
in the integer ``4`` (although non-integers were used in between).
|
||||||
|
|
||||||
If the result is not an integer,
|
If the result is not an integer,
|
||||||
an appropriate :code:`ufixed` or :code:`fixed` type is used whose number of fractional bits is as large as
|
an appropriate ``ufixed`` or ``fixed`` type is used whose number of fractional bits is as large as
|
||||||
required (approximating the rational number in the worst case).
|
required (approximating the rational number in the worst case).
|
||||||
|
|
||||||
In :code:`var x = 1/4;`, :code:`x` will receive the type :code:`ufixed0x8` while in :code:`var x = 1/3` it will receive
|
In ``var x = 1/4;``, ``x`` will receive the type ``ufixed0x8`` while in ``var x = 1/3`` it will receive
|
||||||
the type :code:`ufixed0x256` because :code:`1/3` is not finitely representable in binary and will thus be
|
the type ``ufixed0x256`` because ``1/3`` is not finitely representable in binary and will thus be
|
||||||
approximated.
|
approximated.
|
||||||
|
|
||||||
Any operator that can be applied to integers can also be applied to literal expressions as
|
Any operator that can be applied to integers can also be applied to literal expressions as
|
||||||
@ -171,18 +171,18 @@ and exponentiation is disallowed if the exponent is fractional (because that mig
|
|||||||
a non-rational number).
|
a non-rational number).
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Most finite decimal fractions like :code:`5.3743` are not finitely representable in binary. The correct type
|
Most finite decimal fractions like ``5.3743`` are not finitely representable in binary. The correct type
|
||||||
for :code:`5.3743` is :code:`ufixed8x248` because that allows to best approximate the number. If you want to
|
for ``5.3743`` is ``ufixed8x248`` because that allows to best approximate the number. If you want to
|
||||||
use the number together with types like :code:`ufixed` (i.e. :code:`ufixed128x128`), you have to explicitly
|
use the number together with types like ``ufixed`` (i.e. ``ufixed128x128``), you have to explicitly
|
||||||
specify the desired precision: :code:`x + ufixed(5.3743)`.
|
specify the desired precision: ``x + ufixed(5.3743)``.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
Division on integer literals used to truncate in earlier versions, but it will now convert into a rational number, i.e. :code:`5 / 2` is not equal to :code:`2`, but to :code:`2.5`.
|
Division on integer literals used to truncate in earlier versions, but it will now convert into a rational number, i.e. ``5 / 2`` is not equal to ``2``, but to ``2.5``.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Literal expressions are converted to a permanent type as soon as they are used with other
|
Literal expressions are converted to a permanent type as soon as they are used with other
|
||||||
expressions. Even though we know that the value of the
|
expressions. Even though we know that the value of the
|
||||||
expression assigned to :code:`b` in the following example evaluates to an integer, it still
|
expression assigned to ``b`` in the following example evaluates to an integer, it still
|
||||||
uses fixed point types (and not rational number literals) in between and so the code
|
uses fixed point types (and not rational number literals) in between and so the code
|
||||||
does not compile
|
does not compile
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ a non-rational number).
|
|||||||
String Literals
|
String Literals
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
String Literals are written with double quotes (:code:`"abc"`). As with integer literals, their type can vary, but they are implicitly convertible to :code:`bytes` if they fit, to :code:`bytes` and to :code:`string`.
|
String Literals are written with double quotes (``"abc"``). As with integer literals, their type can vary, but they are implicitly convertible to ``bytes`` if they fit, to ``bytes`` and to ``string``.
|
||||||
|
|
||||||
.. index:: enum
|
.. index:: enum
|
||||||
|
|
||||||
@ -250,8 +250,8 @@ Data location
|
|||||||
Every complex type, i.e. *arrays* and *structs*, has an additional
|
Every complex type, i.e. *arrays* and *structs*, has an additional
|
||||||
annotation, the "data location", about whether it is stored in memory or in storage. Depending on the
|
annotation, the "data location", about whether it is stored in memory or in storage. Depending on the
|
||||||
context, there is always a default, but it can be overridden by appending
|
context, there is always a default, but it can be overridden by appending
|
||||||
either :code:`storage` or :code:`memory` to the type. The default for function parameters (including return parameters) is :code:`memory`, the default for local variables is :code:`storage` and the location is forced
|
either ``storage`` or ``memory`` to the type. The default for function parameters (including return parameters) is ``memory``, the default for local variables is ``storage`` and the location is forced
|
||||||
to :code:`storage` for state variables (obviously).
|
to ``storage`` for state variables (obviously).
|
||||||
|
|
||||||
There is also a third data location, "calldata", which is a non-modifyable
|
There is also a third data location, "calldata", which is a non-modifyable
|
||||||
non-persistent area where function arguments are stored. Function parameters
|
non-persistent area where function arguments are stored. Function parameters
|
||||||
@ -316,23 +316,23 @@ For storage arrays, the element type can be arbitrary (i.e. also other
|
|||||||
arrays, mappings or structs). For memory arrays, it cannot be a mapping and
|
arrays, mappings or structs). For memory arrays, it cannot be a mapping and
|
||||||
has to be an ABI type if it is an argument of a publicly-visible function.
|
has to be an ABI type if it is an argument of a publicly-visible function.
|
||||||
|
|
||||||
An array of fixed size :code:`k` and element type :code:`T` is written as :code:`T[k]`,
|
An array of fixed size ``k`` and element type ``T`` is written as ``T[k]``,
|
||||||
an array of dynamic size as :code:`T[]`. As an example, an array of 5 dynamic
|
an array of dynamic size as ``T[]``. As an example, an array of 5 dynamic
|
||||||
arrays of :code:`uint` is :code:`uint[][5]` (note that the notation is reversed when
|
arrays of ``uint`` is ``uint[][5]`` (note that the notation is reversed when
|
||||||
compared to some other languages). To access the second uint in the
|
compared to some other languages). To access the second uint in the
|
||||||
third dynamic array, you use :code:`x[2][1]` (indices are zero-based and
|
third dynamic array, you use ``x[2][1]`` (indices are zero-based and
|
||||||
access works in the opposite way of the declaration, i.e. :code:`x[2]`
|
access works in the opposite way of the declaration, i.e. ``x[2]``
|
||||||
shaves off one level in the type from the right).
|
shaves off one level in the type from the right).
|
||||||
|
|
||||||
Variables of type :code:`bytes` and :code:`string` are special arrays. A :code:`bytes` is similar to :code:`byte[]`,
|
Variables of type ``bytes`` and ``string`` are special arrays. A ``bytes`` is similar to ``byte[]``,
|
||||||
but it is packed tightly in calldata. :code:`string` is equal to :code:`bytes` but does not allow
|
but it is packed tightly in calldata. ``string`` is equal to ``bytes`` but does not allow
|
||||||
length or index access (for now).
|
length or index access (for now).
|
||||||
|
|
||||||
So :code:`bytes` should always be preferred over :code:`byte[]` because it is cheaper.
|
So ``bytes`` should always be preferred over ``byte[]`` because it is cheaper.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
If you want to access the byte-representation of a string :code:`s`, use
|
If you want to access the byte-representation of a string ``s``, use
|
||||||
:code:`bytes(s).length / bytes(s)[7] = x';`. Keep in mind
|
``bytes(s).length / bytes(s)[7] = x';``. Keep in mind
|
||||||
that you are accessing the low-level bytes of the utf-8 representation,
|
that you are accessing the low-level bytes of the utf-8 representation,
|
||||||
and not the individual characters!
|
and not the individual characters!
|
||||||
|
|
||||||
@ -341,9 +341,9 @@ So :code:`bytes` should always be preferred over :code:`byte[]` because it is ch
|
|||||||
Allocating Memory Arrays
|
Allocating Memory Arrays
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Creating arrays with variable length in memory can be done using the :code:`new` keyword.
|
Creating arrays with variable length in memory can be done using the ``new`` keyword.
|
||||||
As opposed to storage arrays, it is **not** possible to resize memory arrays by assigning to
|
As opposed to storage arrays, it is **not** possible to resize memory arrays by assigning to
|
||||||
the :code:`.length` member.
|
the ``.length`` member.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -363,19 +363,19 @@ Members
|
|||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
**length**:
|
**length**:
|
||||||
Arrays have a :code:`length` member to hold their number of elements.
|
Arrays have a ``length`` member to hold their number of elements.
|
||||||
Dynamic arrays can be resized in storage (not in memory) by changing the
|
Dynamic arrays can be resized in storage (not in memory) by changing the
|
||||||
:code:`.length` member. This does not happen automatically when attempting to access elements outside the current length. The size of memory arrays is fixed (but dynamic, i.e. it can depend on runtime parameters) once they are created.
|
``.length`` member. This does not happen automatically when attempting to access elements outside the current length. The size of memory arrays is fixed (but dynamic, i.e. it can depend on runtime parameters) once they are created.
|
||||||
**push**:
|
**push**:
|
||||||
Dynamic storage arrays and :code:`bytes` (not :code:`string`) have a member function called :code:`push` that can be used to append an element at the end of the array. The function returns the new length.
|
Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``push`` that can be used to append an element at the end of the array. The function returns the new length.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
It is not yet possible to use arrays of arrays in external functions.
|
It is not yet possible to use arrays of arrays in external functions.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
Due to limitations of the EVM, it is not possible to return
|
Due to limitations of the EVM, it is not possible to return
|
||||||
dynamic content from external function calls. The function :code:`f` in
|
dynamic content from external function calls. The function ``f`` in
|
||||||
:code:`contract C { function f() returns (uint[]) { ... } }` will return
|
``contract C { function f() returns (uint[]) { ... } }`` will return
|
||||||
something if called from web3.js, but not if called from Solidity.
|
something if called from web3.js, but not if called from Solidity.
|
||||||
|
|
||||||
The only workaround for now is to use large statically-sized arrays.
|
The only workaround for now is to use large statically-sized arrays.
|
||||||
@ -511,21 +511,21 @@ members of the local variable actually write to the state.
|
|||||||
|
|
||||||
Of course, you can also directly access the members of the struct without
|
Of course, you can also directly access the members of the struct without
|
||||||
assigning it to a local variable, as in
|
assigning it to a local variable, as in
|
||||||
:code:`campaigns[campaignID].amount = 0`.
|
``campaigns[campaignID].amount = 0``.
|
||||||
|
|
||||||
.. index:: !mapping
|
.. index:: !mapping
|
||||||
|
|
||||||
Mappings
|
Mappings
|
||||||
========
|
========
|
||||||
|
|
||||||
Mapping types are declared as :code:`mapping _KeyType => _ValueType`, where
|
Mapping types are declared as ``mapping _KeyType => _ValueType``, where
|
||||||
:code:`_KeyType` can be almost any type except for a mapping and :code:`_ValueType`
|
``_KeyType`` can be almost any type except for a mapping and ``_ValueType``
|
||||||
can actually be any type, including mappings.
|
can actually be any type, including mappings.
|
||||||
|
|
||||||
Mappings can be seen as hashtables which are virtually initialized such that
|
Mappings can be seen as hashtables which are virtually initialized such that
|
||||||
every possible key exists and is mapped to a value whose byte-representation is
|
every possible key exists and is mapped to a value whose byte-representation is
|
||||||
all zeros. The similarity ends here, though: The key data is not actually stored
|
all zeros. The similarity ends here, though: The key data is not actually stored
|
||||||
in a mapping, only its :code:`sha3` hash used to look up the value.
|
in a mapping, only its ``sha3`` hash used to look up the value.
|
||||||
|
|
||||||
Because of this, mappings do not have a length or a concept of a key or value being "set".
|
Because of this, mappings do not have a length or a concept of a key or value being "set".
|
||||||
|
|
||||||
@ -537,18 +537,18 @@ in internal functions).
|
|||||||
Operators Involving LValues
|
Operators Involving LValues
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
If :code:`a` is an LValue (i.e. a variable or something that can be assigned to), the following operators are available as shorthands:
|
If ``a`` is an LValue (i.e. a variable or something that can be assigned to), the following operators are available as shorthands:
|
||||||
|
|
||||||
:code:`a += e` is equivalent to :code:`a = a + e`. The operators :code:`-=`, :code:`*=`, :code:`/=`, :code:`%=`, :code:`a |=`, :code:`&=` and :code:`^=` are defined accordingly. :code:`a++` and :code:`a--` are equivalent to :code:`a += 1` / :code:`a -= 1` but the expression itself still has the previous value of :code:`a`. In contrast, :code:`--a` and :code:`++a` have the same effect on :code:`a` but return the value after the change.
|
``a += e`` is equivalent to ``a = a + e``. The operators ``-=``, ``*=``, ``/=``, ``%=``, ``a |=``, ``&=`` and ``^=`` are defined accordingly. ``a++`` and ``a--`` are equivalent to ``a += 1`` / ``a -= 1`` but the expression itself still has the previous value of ``a``. In contrast, ``--a`` and ``++a`` have the same effect on ``a`` but return the value after the change.
|
||||||
|
|
||||||
delete
|
delete
|
||||||
------
|
------
|
||||||
|
|
||||||
:code:`delete a` assigns the initial value for the type to :code:`a`. I.e. for integers it is equivalent to :code:`a = 0`, but it can also be used on arrays, where it assigns a dynamic array of length zero or a static array of the same length with all elements reset. For structs, it assigns a struct with all members reset.
|
``delete a`` assigns the initial value for the type to ``a``. I.e. for integers it is equivalent to ``a = 0``, but it can also be used on arrays, where it assigns a dynamic array of length zero or a static array of the same length with all elements reset. For structs, it assigns a struct with all members reset.
|
||||||
|
|
||||||
:code:`delete` has no effect on whole mappings (as the keys of mappings may be arbitrary and are generally unknown). So if you delete a struct, it will reset all members that are not mappings and also recurse into the members unless they are mappings. However, individual keys and what they map to can be deleted.
|
``delete`` has no effect on whole mappings (as the keys of mappings may be arbitrary and are generally unknown). So if you delete a struct, it will reset all members that are not mappings and also recurse into the members unless they are mappings. However, individual keys and what they map to can be deleted.
|
||||||
|
|
||||||
It is important to note that :code:`delete a` really behaves like an assignment to :code:`a`, i.e. it stores a new object in :code:`a`.
|
It is important to note that ``delete a`` really behaves like an assignment to ``a``, i.e. it stores a new object in ``a``.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -580,12 +580,12 @@ If an operator is applied to different types, the compiler tries to
|
|||||||
implicitly convert one of the operands to the type of the other (the same is
|
implicitly convert one of the operands to the type of the other (the same is
|
||||||
true for assignments). In general, an implicit conversion between value-types
|
true for assignments). In general, an implicit conversion between value-types
|
||||||
is possible if it
|
is possible if it
|
||||||
makes sense semantically and no information is lost: :code:`uint8` is convertible to
|
makes sense semantically and no information is lost: ``uint8`` is convertible to
|
||||||
:code:`uint16` and :code:`int128` to :code:`int256`, but :code:`int8` is not convertible to :code:`uint256`
|
``uint16`` and ``int128`` to ``int256``, but ``int8`` is not convertible to ``uint256``
|
||||||
(because :code:`uint256` cannot hold e.g. :code:`-1`).
|
(because ``uint256`` cannot hold e.g. ``-1``).
|
||||||
Furthermore, unsigned integers can be converted to bytes of the same or larger
|
Furthermore, unsigned integers can be converted to bytes of the same or larger
|
||||||
size, but not vice-versa. Any type that can be converted to :code:`uint160` can also
|
size, but not vice-versa. Any type that can be converted to ``uint160`` can also
|
||||||
be converted to :code:`address`.
|
be converted to ``address``.
|
||||||
|
|
||||||
Explicit Conversions
|
Explicit Conversions
|
||||||
--------------------
|
--------------------
|
||||||
@ -596,7 +596,7 @@ doing, an explicit type conversion is sometimes possible::
|
|||||||
int8 y = -3;
|
int8 y = -3;
|
||||||
uint x = uint(y);
|
uint x = uint(y);
|
||||||
|
|
||||||
At the end of this code snippet, :code:`x` will have the value :code:`0xfffff..fd` (64 hex
|
At the end of this code snippet, ``x`` will have the value ``0xfffff..fd`` (64 hex
|
||||||
characters), which is -3 in two's complement representation of 256 bits.
|
characters), which is -3 in two's complement representation of 256 bits.
|
||||||
|
|
||||||
If a type is explicitly converted to a smaller type, higher-order bits are
|
If a type is explicitly converted to a smaller type, higher-order bits are
|
||||||
@ -619,12 +619,12 @@ expression that is assigned to the variable::
|
|||||||
uint20 x = 0x123;
|
uint20 x = 0x123;
|
||||||
var y = x;
|
var y = x;
|
||||||
|
|
||||||
Here, the type of :code:`y` will be :code:`uint20`. Using :code:`var` is not possible for function
|
Here, the type of ``y`` will be ``uint20``. Using ``var`` is not possible for function
|
||||||
parameters or return parameters.
|
parameters or return parameters.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
The type is only deduced from the first assignment, so
|
The type is only deduced from the first assignment, so
|
||||||
the loop in the following snippet is infinite, as :code:`i` will have the type
|
the loop in the following snippet is infinite, as ``i`` will have the type
|
||||||
:code:`uint8` and any value of this type is smaller than :code:`2000`.
|
``uint8`` and any value of this type is smaller than ``2000``.
|
||||||
:code:`for (var i = 0; i < 2000; i++) { ... }`
|
``for (var i = 0; i < 2000; i++) { ... }``
|
||||||
|
|
||||||
|
@ -7,23 +7,23 @@ Units and Globally Available Variables
|
|||||||
Ether Units
|
Ether Units
|
||||||
===========
|
===========
|
||||||
|
|
||||||
A literal number can take a suffix of :code:`wei`, :code:`finney`, :code:`szabo` or :code:`ether` to convert between the subdenominations of Ether, where Ether currency numbers without a postfix are assumed to be "wei", e.g. :code:`2 ether == 2000 finney` evaluates to :code:`true`.
|
A literal number can take a suffix of ``wei``, ``finney``, ``szabo`` or ``ether`` to convert between the subdenominations of Ether, where Ether currency numbers without a postfix are assumed to be "wei", e.g. ``2 ether == 2000 finney`` evaluates to ``true``.
|
||||||
|
|
||||||
.. index:: time, seconds, minutes, hours, days, weeks, years
|
.. index:: time, seconds, minutes, hours, days, weeks, years
|
||||||
|
|
||||||
Time Units
|
Time Units
|
||||||
==========
|
==========
|
||||||
|
|
||||||
Suffixes of :code:`seconds`, :code:`minutes`, :code:`hours`, :code:`days`, :code:`weeks` and
|
Suffixes of ``seconds``, ``minutes``, ``hours``, ``days``, ``weeks`` and
|
||||||
`years` after literal numbers can be used to convert between units of time where seconds are the base
|
`years` after literal numbers can be used to convert between units of time where seconds are the base
|
||||||
unit and units are considered naively in the following way:
|
unit and units are considered naively in the following way:
|
||||||
|
|
||||||
* :code:`1 == 1 second`
|
* ``1 == 1 second``
|
||||||
* :code:`1 minutes == 60 seconds`
|
* ``1 minutes == 60 seconds``
|
||||||
* :code:`1 hours == 60 minutes`
|
* ``1 hours == 60 minutes``
|
||||||
* :code:`1 days == 24 hours`
|
* ``1 days == 24 hours``
|
||||||
* :code:`1 weeks = 7 days`
|
* ``1 weeks = 7 days``
|
||||||
* :code:`1 years = 365 days`
|
* ``1 years = 365 days``
|
||||||
|
|
||||||
Take care if you perform calendar calculations using these units, because
|
Take care if you perform calendar calculations using these units, because
|
||||||
not every year equals 365 days and not even every day has 24 hours
|
not every year equals 365 days and not even every day has 24 hours
|
||||||
@ -50,29 +50,29 @@ namespace and are mainly used to provide information about the blockchain.
|
|||||||
Block and Transaction Properties
|
Block and Transaction Properties
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
- :code:`block.coinbase` (:code:`address`): current block miner's address
|
- ``block.coinbase`` (``address``): current block miner's address
|
||||||
- :code:`block.difficulty` (:code:`uint`): current block difficulty
|
- ``block.difficulty`` (``uint``): current block difficulty
|
||||||
- :code:`block.gaslimit` (:code:`uint`): current block gaslimit
|
- ``block.gaslimit`` (``uint``): current block gaslimit
|
||||||
- :code:`block.number` (:code:`uint`): current block number
|
- ``block.number`` (``uint``): current block number
|
||||||
- :code:`block.blockhash` (:code:`function(uint) returns (bytes32)`): hash of the given block - only for 256 most recent blocks
|
- ``block.blockhash`` (``function(uint) returns (bytes32)``): hash of the given block - only for 256 most recent blocks
|
||||||
- :code:`block.timestamp` (:code:`uint`): current block timestamp
|
- ``block.timestamp`` (``uint``): current block timestamp
|
||||||
- :code:`msg.data` (:code:`bytes`): complete calldata
|
- ``msg.data`` (``bytes``): complete calldata
|
||||||
- :code:`msg.gas` (:code:`uint`): remaining gas
|
- ``msg.gas`` (``uint``): remaining gas
|
||||||
- :code:`msg.sender` (:code:`address`): sender of the message (current call)
|
- ``msg.sender`` (``address``): sender of the message (current call)
|
||||||
- :code:`msg.sig` (:code:`bytes4`): first four bytes of the calldata (i.e. function identifier)
|
- ``msg.sig`` (``bytes4``): first four bytes of the calldata (i.e. function identifier)
|
||||||
- :code:`msg.value` (:code:`uint`): number of wei sent with the message
|
- ``msg.value`` (``uint``): number of wei sent with the message
|
||||||
- :code:`now` (:code:`uint`): current block timestamp (alias for :code:`block.timestamp`)
|
- ``now`` (``uint``): current block timestamp (alias for ``block.timestamp``)
|
||||||
- :code:`tx.gasprice` (:code:`uint`): gas price of the transaction
|
- ``tx.gasprice`` (``uint``): gas price of the transaction
|
||||||
- :code:`tx.origin` (:code:`address`): sender of the transaction (full call chain)
|
- ``tx.origin`` (``address``): sender of the transaction (full call chain)
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
The values of all members of :code:`msg`, including :code:`msg.sender` and
|
The values of all members of ``msg``, including ``msg.sender`` and
|
||||||
:code:`msg.value` can change for every **external** function call.
|
``msg.value`` can change for every **external** function call.
|
||||||
This includes calls to library functions.
|
This includes calls to library functions.
|
||||||
|
|
||||||
If you want to implement access restrictions in library functions using
|
If you want to implement access restrictions in library functions using
|
||||||
:code:`msg.sender`, you have to manually supply the value of
|
``msg.sender``, you have to manually supply the value of
|
||||||
:code:`msg.sender` as an argument.
|
``msg.sender`` as an argument.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
The block hashes are not available for all blocks for scalability reasons.
|
The block hashes are not available for all blocks for scalability reasons.
|
||||||
@ -84,17 +84,17 @@ Block and Transaction Properties
|
|||||||
Mathematical and Cryptographic Functions
|
Mathematical and Cryptographic Functions
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
:code:`addmod(uint x, uint y, uint k) returns (uint)`:
|
``addmod(uint x, uint y, uint k) returns (uint)``:
|
||||||
compute :code:`(x + y) % k` where the addition is performed with arbitrary precision and does not wrap around at :code:`2**256`.
|
compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``.
|
||||||
:code:`mulmod(uint x, uint y, uint k) returns (uint)`:
|
``mulmod(uint x, uint y, uint k) returns (uint)``:
|
||||||
compute :code:`(x * y) % k` where the multiplication is performed with arbitrary precision and does not wrap around at :code:`2**256`.
|
compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``.
|
||||||
:code:`sha3(...) returns (bytes32)`:
|
``sha3(...) returns (bytes32)``:
|
||||||
compute the Ethereum-SHA-3 hash of the (tightly packed) arguments
|
compute the Ethereum-SHA-3 hash of the (tightly packed) arguments
|
||||||
:code:`sha256(...) returns (bytes32)`:
|
``sha256(...) returns (bytes32)``:
|
||||||
compute the SHA-256 hash of the (tightly packed) arguments
|
compute the SHA-256 hash of the (tightly packed) arguments
|
||||||
:code:`ripemd160(...) returns (bytes20)`:
|
``ripemd160(...) returns (bytes20)``:
|
||||||
compute RIPEMD-160 hash of the (tightly packed) arguments
|
compute RIPEMD-160 hash of the (tightly packed) arguments
|
||||||
:code:`ecrecover(bytes32 data, uint8 v, bytes32 r, bytes32 s) returns (address)`:
|
``ecrecover(bytes32 data, uint8 v, bytes32 r, bytes32 s) returns (address)``:
|
||||||
recover the address associated with the public key from elliptic curve signature
|
recover the address associated with the public key from elliptic curve signature
|
||||||
|
|
||||||
In the above, "tightly packed" means that the arguments are concatenated without padding.
|
In the above, "tightly packed" means that the arguments are concatenated without padding.
|
||||||
@ -106,20 +106,20 @@ This means that the following are all identical::
|
|||||||
sha3(6382179)
|
sha3(6382179)
|
||||||
sha3(97, 98, 99)
|
sha3(97, 98, 99)
|
||||||
|
|
||||||
If padding is needed, explicit type conversions can be used: :code:`sha3("\x00\x12")` is the
|
If padding is needed, explicit type conversions can be used: ``sha3("\x00\x12")`` is the
|
||||||
same as :code:`sha3(uint16(0x12))`.
|
same as ``sha3(uint16(0x12))``.
|
||||||
|
|
||||||
It might be that you run into Out-of-Gas for :code:`sha256`, :code:`ripemd160` or :code:`ecrecover` on a *private blockchain*. The reason for this is that those are implemented as so-called precompiled contracts and these contracts only really exist after they received the first message (although their contract code is hardcoded). Messages to non-existing contracts are more expensive and thus the execution runs into an Out-of-Gas error. A workaround for this problem is to first send e.g. 1 Wei to each of the contracts before you use them in your actual contracts. This is not an issue on the official or test net.
|
It might be that you run into Out-of-Gas for ``sha256``, ``ripemd160`` or ``ecrecover`` on a *private blockchain*. The reason for this is that those are implemented as so-called precompiled contracts and these contracts only really exist after they received the first message (although their contract code is hardcoded). Messages to non-existing contracts are more expensive and thus the execution runs into an Out-of-Gas error. A workaround for this problem is to first send e.g. 1 Wei to each of the contracts before you use them in your actual contracts. This is not an issue on the official or test net.
|
||||||
|
|
||||||
.. index:: this, selfdestruct
|
.. index:: this, selfdestruct
|
||||||
|
|
||||||
Contract Related
|
Contract Related
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
:code:`this` (current contract's type):
|
``this`` (current contract's type):
|
||||||
the current contract, explicitly convertible to :ref:`address`
|
the current contract, explicitly convertible to :ref:`address`
|
||||||
|
|
||||||
:code:`selfdestruct(address)`:
|
``selfdestruct(address)``:
|
||||||
destroy the current contract, sending its funds to the given :ref:`address`
|
destroy the current contract, sending its funds to the given :ref:`address`
|
||||||
|
|
||||||
Furthermore, all functions of the current contract are callable directly including the current function.
|
Furthermore, all functions of the current contract are callable directly including the current function.
|
||||||
|
Loading…
Reference in New Issue
Block a user