docs: Gather information about linker in one place and reorganize the section a bit

This commit is contained in:
Kamil Śliwak 2020-11-14 01:20:38 +01:00
parent 1ff00488bb
commit b7694b9a14
2 changed files with 37 additions and 24 deletions

View File

@ -184,26 +184,15 @@ custom types without the overhead of external function calls:
It is possible to obtain the address of a library by converting
the library type to the ``address`` type, i.e. using ``address(LibraryName)``.
As the compiler cannot know where the library will be
deployed at, these addresses have to be filled into the
final bytecode by a linker
(see :ref:`commandline-compiler` for how to use the
commandline compiler for linking). If the addresses are not
given as arguments to the compiler, the compiled hex code
will contain placeholders of the form ``__Set______`` (where
``Set`` is the name of the library). The address can be filled
manually by replacing all those 40 symbols by the hex
encoding of the address of the library contract.
.. note::
Manually linking libraries on the generated bytecode is discouraged because it does not update
contract metadata. Since metadata contains a list of libraries specified at the time of
compilation and bytecode contains a metadata hash, you will get different binaries, depending
on when linking is performed.
You should ask the compiler to link the libraries at the time a contract is compiled by either
using the ``--libraries`` option of ``solc`` or the ``libraries`` key if you use the
standard-JSON interface to the compiler.
As the compiler does not know the address where the library will be deployed, the compiled hex code
will contain placeholders of the form ``__$30bbc0abd4d6364515865950d3e0d10953$__``. The placeholder
is a 34 character prefix of the hex encoding of the keccak256 hash of the fully qualified library
name, which would be for example ``libraries/bigint.sol:BigInt`` if the library was stored in a file
called ``bigint.sol`` in a ``libraries/`` directory. Such bytecode is incomplete and should not be
deployed. Placeholders need to be replaced with actual addresses. You can do that by either passing
them to the compiler when the library is being compiled or by using the linker to update an already
compiled binary. See :ref:`library-linking` for information on how to use the commandline compiler
for linking.
In comparison to contracts, libraries are restricted in the following ways:
@ -287,4 +276,4 @@ for any non-view and non-pure function.
This means that the actual code stored on chain for a library
is different from the code reported by the compiler as
``deployedBytecode``.
``deployedBytecode``.

View File

@ -12,10 +12,16 @@ Using the Commandline Compiler
.. note::
This section does not apply to :ref:`solcjs <solcjs>`, not even if it is used in commandline mode.
Basic usage
-----------
One of the build targets of the Solidity repository is ``solc``, the solidity commandline compiler.
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 ``solc --bin sourceFile.sol`` and it will print the binary. 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-json --asm sourceFile.sol``.
Optimizer options
-----------------
Before you deploy your contract, activate the optimizer when compiling using ``solc --optimize --bin sourceFile.sol``.
By default, the optimizer will optimize the contract assuming it is called 200 times across its lifetime
(more specifically, it assumes each opcode is executed around 200 times).
@ -27,6 +33,9 @@ This parameter has effects on the following (this might change in the future):
- the size of the binary search in the function dispatch routine
- the way constants like large numbers or strings are stored
Path remapping
--------------
The commandline compiler will automatically read imported files from the filesystem, but
it is also possible to provide path redirects using ``prefix=path`` in the following way:
@ -53,6 +62,11 @@ For security reasons the compiler has restrictions what directories it can acces
Everything inside the path specified via ``--base-path`` is always allowed.
.. _library-linking:
Library linking
---------------
If your contracts use :ref:`libraries <libraries>`, you will notice that the bytecode contains substrings of the form ``__$53aea86b7d70b31448b230b20ae141a537$__``. These are placeholders for the actual library addresses.
The placeholder is a 34 character prefix of the hex encoding of the keccak256 hash of the fully qualified library name.
The bytecode file will also contain lines of the form ``// <placeholder> -> <fq library name>`` at the end to help
@ -60,13 +74,23 @@ identify which libraries the placeholders represent. Note that the fully qualifi
is the path of its source file and the library name separated by ``:``.
You can use ``solc`` as a linker meaning that it will insert the library addresses for you at those points:
Either add ``--libraries "file.sol:Math:0x1234567890123456789012345678901234567890 file.sol:Heap:0xabCD567890123456789012345678901234567890"`` 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 ``solc`` is called with the option ``--link``, all input files are interpreted to be unlinked binaries (hex-encoded) in the ``__$53aea86b7d70b31448b230b20ae141a537$__``-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.
Either add ``--libraries "file.sol:Math:0x1234567890123456789012345678901234567890 file.sol:Heap:0xabCD567890123456789012345678901234567890"`` to your command to provide an address for each library (use commas or spaces as separators) or store the string in a file (one library per line) and run ``solc`` using ``--libraries fileName``.
If ``solc`` is called with the option ``--standard-json``, it will expect a JSON input (as explained below) on the standard input, and return a JSON output on the standard output. This is the recommended interface for more complex and especially automated uses. The process will always terminate in a "success" state and report any errors via the JSON output.
The option ``--base-path`` is also processed in standard-json mode.
If ``solc`` is called with the option ``--link``, all input files are interpreted to be unlinked binaries (hex-encoded) in the ``__$53aea86b7d70b31448b230b20ae141a537$__``-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.
.. warning::
Manually linking libraries on the generated bytecode is discouraged because it does not update
contract metadata. Since metadata contains a list of libraries specified at the time of
compilation and bytecode contains a metadata hash, you will get different binaries, depending
on when linking is performed.
You should ask the compiler to link the libraries at the time a contract is compiled by either
using the ``--libraries`` option of ``solc`` or the ``libraries`` key if you use the
standard-JSON interface to the compiler.
.. note::
The library placeholder used to be the fully qualified name of the library itself
instead of the hash of it. This format is still supported by ``solc --link`` but