diff --git a/CMakeLists.txt b/CMakeLists.txt index f3a03d94e8..1406d9720c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,11 @@ cmake_minimum_required(VERSION 3.13.0) -set(ETH_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake" CACHE PATH "The the path to the cmake directory") +set(ETH_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake" CACHE PATH "The path to the cmake directory") list(APPEND CMAKE_MODULE_PATH ${ETH_CMAKE_DIR}) # Set the build type, if none was specified. if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - if(EXISTS "${CMAKE_SOURCE_DIR}/.git") + if(EXISTS "${PROJECT_SOURCE_DIR}/.git") set(DEFAULT_BUILD_TYPE "RelWithDebInfo") else() set(DEFAULT_BUILD_TYPE "Release") @@ -21,7 +21,7 @@ include(EthPolicy) eth_policy() # project name and version should be set after cmake_policy CMP0048 -set(PROJECT_VERSION "0.8.12") +set(PROJECT_VERSION "0.8.25") # OSX target needed in order to support std::visit set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14") project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX) @@ -35,6 +35,8 @@ endif() option(SOLC_LINK_STATIC "Link solc executable statically on supported platforms" OFF) option(SOLC_STATIC_STDLIBS "Link solc against static versions of libgcc and libstdc++ on supported platforms" OFF) option(STRICT_Z3_VERSION "Use the latest version of Z3" ON) +option(PEDANTIC "Enable extra warnings and pedantic build flags. Treat all warnings as errors." ON) +option(PROFILE_OPTIMIZER_STEPS "Output performance metrics for the optimiser steps." OFF) # Setup cccache. include(EthCcache) @@ -48,6 +50,14 @@ include_directories(SYSTEM ${JSONCPP_INCLUDE_DIR}) find_package(Threads) +if(NOT PEDANTIC) + message(WARNING "-- Pedantic build flags turned off. Warnings will not make compilation fail. This is NOT recommended in development builds.") +endif() + +if (PROFILE_OPTIMIZER_STEPS) + add_definitions(-DPROFILE_OPTIMIZER_STEPS) +endif() + # Figure out what compiler and system are we using include(EthCompilerSettings) @@ -56,17 +66,22 @@ include(EthUtils) # Create license.h from LICENSE.txt and template # Converting to char array is required due to MSVC's string size limit. -file(READ ${CMAKE_SOURCE_DIR}/LICENSE.txt LICENSE_TEXT HEX) +file(READ ${PROJECT_SOURCE_DIR}/LICENSE.txt LICENSE_TEXT HEX) string(REGEX MATCHALL ".." LICENSE_TEXT "${LICENSE_TEXT}") string(REGEX REPLACE ";" ",\n\t0x" LICENSE_TEXT "${LICENSE_TEXT}") set(LICENSE_TEXT "0x${LICENSE_TEXT}") -configure_file("${CMAKE_SOURCE_DIR}/cmake/templates/license.h.in" include/license.h) +configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/license.h.in" include/license.h) include(EthOptions) configure_project(TESTS) +<<<<<<< HEAD set(LATEST_Z3_VERSION "4.8.13") set(MINIMUM_Z3_VERSION "4.8.0") +======= +set(LATEST_Z3_VERSION "4.12.1") +set(MINIMUM_Z3_VERSION "4.8.16") +>>>>>>> english/develop find_package(Z3) if (${Z3_FOUND}) if (${STRICT_Z3_VERSION}) @@ -130,6 +145,7 @@ add_subdirectory(libevmasm) add_subdirectory(libyul) add_subdirectory(libsolidity) add_subdirectory(libsolc) +add_subdirectory(libstdlib) add_subdirectory(tools) if (NOT EMSCRIPTEN) diff --git a/docs/050-breaking-changes.rst b/docs/050-breaking-changes.rst index d7e3ca63ba..7a6e3e7ef4 100644 --- a/docs/050-breaking-changes.rst +++ b/docs/050-breaking-changes.rst @@ -89,6 +89,7 @@ Pour la plupart des sujets, le compilateur fournira des suggestions. fonction et constructeur, et ``external`` à chaque fonction de fallback ou d'interface d'interface qui ne spécifie pas déjà sa visibilité. +<<<<<<< HEAD * La localisation explicite des données pour toutes les variables de type struct, array ou mapping est maintenant obligatoire. Ceci s'applique également aux paramètres des fonctions et aux de retour. Par exemple, changez ``uint[] x = m_x`` en ``uint[] storage x = @@ -96,6 +97,15 @@ Pour la plupart des sujets, le compilateur fournira des suggestions. où "memory" est l'emplacement des données et peut être remplacé par "storage" ou "calldata". ``calldata`` en conséquence. Notez que les fonctions ``externes`` requièrent des paramètres dont l'emplacement des données est ``calldata``. +======= +* Explicit data location for all variables of struct, array or mapping types is + now mandatory. This is also applied to function parameters and return + variables. For example, change ``uint[] x = z`` to ``uint[] storage x = + z``, and ``function f(uint[][] x)`` to ``function f(uint[][] memory x)`` + where ``memory`` is the data location and might be replaced by ``storage`` or + ``calldata`` accordingly. Note that ``external`` functions require + parameters with a data location of ``calldata``. +>>>>>>> english/develop * Les types de contrats n'incluent plus les membres ``addresses`` afin de afin de séparer les espaces de noms. Par conséquent, il est maintenant nécessaire de @@ -139,8 +149,13 @@ Pour la plupart des sujets, le compilateur fournira des suggestions. payante " ou créez une nouvelle fonction interne pour la logique du programme qui utilise ``msg.value``. +<<<<<<< HEAD * Pour des raisons de clarté, l'interface de la ligne de commande exige maintenant ``-`` si l' l'entrée standard est utilisée comme source. +======= +* For clarity reasons, the command-line interface now requires ``-`` if the + standard input is used as source. +>>>>>>> english/develop Éléments dépréciés =================== @@ -149,6 +164,7 @@ Cette section liste les changements qui déprécient des fonctionnalités ou des plusieurs de ces changements étaient déjà activés dans le mode expérimental ``v0.5.0``. +<<<<<<< HEAD Interfaces en ligne de commande et JSON -------------------------------- @@ -162,6 +178,21 @@ Interfaces en ligne de commande et JSON * Les options de ligne de commande ``--clone-bin`` et ``--combined-json clone-bin`` ont été supprimées. ont été supprimées. +======= +Command-line and JSON Interfaces +-------------------------------- + +* The command-line option ``--formal`` (used to generate Why3 output for + further formal verification) was deprecated and is now removed. A new + formal verification module, the SMTChecker, is enabled via ``pragma + experimental SMTChecker;``. + +* The command-line option ``--julia`` was renamed to ``--yul`` due to the + renaming of the intermediate language ``Julia`` to ``Yul``. + +* The ``--clone-bin`` and ``--combined-json clone-bin`` command-line options + were removed. +>>>>>>> english/develop * Les remappages avec un préfixe vide ne sont pas autorisés. @@ -485,7 +516,7 @@ Nouvelle version : return data; } - using address_make_payable for address; + using AddressMakePayable for address; // Data location for 'arr' must be specified function g(uint[] memory /* arr */, bytes8 x, OtherContract otherContract, address unknownContract) public payable { // 'otherContract.transfer' is not provided. @@ -502,7 +533,7 @@ Nouvelle version : // 'address payable' should be used whenever possible. // To increase clarity, we suggest the use of a library for // the conversion (provided after the contract in this example). - address payable addr = unknownContract.make_payable(); + address payable addr = unknownContract.makePayable(); require(addr.send(1 ether)); // Since uint32 (4 bytes) is smaller than bytes8 (8 bytes), @@ -518,8 +549,8 @@ Nouvelle version : // We can define a library for explicitly converting ``address`` // to ``address payable`` as a workaround. - library address_make_payable { - function make_payable(address x) internal pure returns (address payable) { + library AddressMakePayable { + function makePayable(address x) internal pure returns (address payable) { return address(uint160(x)); } } diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst index 7c97c49177..003ce12612 100644 --- a/docs/060-breaking-changes.rst +++ b/docs/060-breaking-changes.rst @@ -12,8 +12,13 @@ Pour la liste complète, consultez Changements dont le compilateur pourrait ne pas être averti ========================================= +<<<<<<< HEAD Cette section liste les changements pour lesquels le comportement de votre code pourrait changer sans que le compilateur vous en avertisse. +======= +This section lists changes where the behavior of your code might +change without the compiler telling you about it. +>>>>>>> english/develop * Le type résultant d'une exponentiation est le type de la base. Il s'agissait auparavant du plus petit type qui peut contenir à la fois le type de la base et le type de l'exposant, comme pour les opérations symétriques. @@ -53,9 +58,17 @@ Pour la plupart des sujets, le compilateur fournira des suggestions. Si le nom contient un point, son préfixe jusqu'au point ne doit pas entrer en conflit avec une déclaration en dehors du bloc d'assemblage en ligne. d'assemblage. +<<<<<<< HEAD * Le shadowing de variables d'état est désormais interdit. Un contrat dérivé peut seulement déclarer une variable d'état ``x``, que s'il n'y a pas de variable d'état visible avec le même nom d'état visible portant le même nom dans l'une de ses bases. +======= +* In inline assembly, opcodes that do not take arguments are now represented as "built-in functions" instead of standalone identifiers. So ``gas`` is now ``gas()``. + +* State variable shadowing is now disallowed. A derived contract can only + declare a state variable ``x``, if there is no visible state variable with + the same name in any of its bases. +>>>>>>> english/develop Changements sémantiques et syntaxiques @@ -102,25 +115,45 @@ ou qui étaient plus difficiles à réaliser. Changements d'interface ================= +<<<<<<< HEAD Cette section liste les changements qui ne sont pas liés au langage lui-même, mais qui ont un effet sur les interfaces du compilateur. le compilateur. Ces modifications peuvent changer la façon dont vous utilisez le compilateur sur la ligne de commande, la façon dont vous utilisez son interface programmable, ou la façon dont vous analysez la sortie qu'il produit. ou comment vous analysez la sortie qu'il produit. +======= +This section lists changes that are unrelated to the language itself, but that have an effect on the interfaces of +the compiler. These may change the way how you use the compiler on the command-line, how you use its programmable +interface, or how you analyze the output produced by it. +>>>>>>> english/develop Nouveau rapporteur d'erreurs ~~~~~~~~~~~~~~~~~~ +<<<<<<< HEAD Un nouveau rapporteur d'erreur a été introduit, qui vise à produire des messages d'erreur plus accessibles sur la ligne de commande. Il est activé par défaut, mais si vous passez ``--old-reporter``, vous revenez à l'ancien rapporteur d'erreurs, qui est déprécié. +======= +A new error reporter was introduced, which aims at producing more accessible error messages on the command-line. +It is enabled by default, but passing ``--old-reporter`` falls back to the deprecated old error reporter. +>>>>>>> english/develop Options de hachage des métadonnées ~~~~~~~~~~~~~~~~~~~~~ +<<<<<<< HEAD Le compilateur ajoute maintenant le hash `IPFS `_ du fichier de métadonnées à la fin du bytecode par défaut. (pour plus de détails, voir la documentation sur :doc:`contract metadata `). Avant la version 0.6.0, le compilateur ajoutait la balise `Swarm `_ hash par défaut, et afin de toujours supporter ce comportement, la nouvelle option de ligne de commande ``--metadata-hash`` a été introduite. Elle permet de sélectionner le hachage à produire et à ajouter ajouté, en passant soit ``ipfs`` soit ``swarm`` comme valeur à l'option de ligne de commande ``--metadata-hash``. Passer la valeur ``none`` supprime complètement le hachage. +======= +The compiler now appends the `IPFS `_ hash of the metadata file to the end of the bytecode by default +(for details, see documentation on :doc:`contract metadata `). Before 0.6.0, the compiler appended the +`Swarm `_ hash by default, and in order to still support this behavior, +the new command-line option ``--metadata-hash`` was introduced. It allows you to select the hash to be produced and +appended, by passing either ``ipfs`` or ``swarm`` as value to the ``--metadata-hash`` command-line option. +Passing the value ``none`` completely removes the hash. +>>>>>>> english/develop Ces changements peuvent également être utilisés via l'interface :ref:`Standard JSON Interface` et affecter les métadonnées JSON générées par le compilateur. @@ -169,8 +202,19 @@ Cette section donne des instructions détaillées sur la façon de mettre à jou * Choisissez des identifiants uniques pour les déclarations de variables dans l'assemblage en ligne qui n'entrent pas en conflit avec les déclarations en dehors de l'assemblage en ligne. avec des déclarations en dehors du bloc d'assemblage en ligne. +<<<<<<< HEAD * Ajoutez "virtual" à chaque fonction non interface que vous avez l'intention de remplacer. Ajoutez ``virtual`` à toutes les fonctions sans implémentation en dehors des interfaces. à toutes les fonctions sans implémentation en dehors des interfaces. Pour l'héritage simple, ajoutez ``override`` à chaque fonction de remplacement. Pour l'héritage multiple, ajoutez ``override(A, B, ..)``, où vous listez entre parenthèses tous les contrats qui définissent la fonction surchargée. Lorsque plusieurs bases définissent la même fonction, le contrat qui hérite doit remplacer toutes les fonctions conflictuelles. +======= +* Add ``virtual`` to every non-interface function you intend to override. Add ``virtual`` + to all functions without implementation outside interfaces. For single inheritance, add + ``override`` to every overriding function. For multiple inheritance, add ``override(A, B, ..)``, + where you list all contracts that define the overridden function in the parentheses. When + multiple bases define the same function, the inheriting contract must override all conflicting functions. + +* In inline assembly, add ``()`` to all opcodes that do not otherwise accept an argument. + For example, change ``pc`` to ``pc()``, and ``gas`` to ``gas()``. +>>>>>>> english/develop diff --git a/docs/080-breaking-changes.rst b/docs/080-breaking-changes.rst index e2c1c293b7..a7c7792040 100644 --- a/docs/080-breaking-changes.rst +++ b/docs/080-breaking-changes.rst @@ -10,20 +10,34 @@ le changelog de la version `0.8.0 >>>>>> english/develop Les vérifications pour le débordement sont très communes, donc nous les avons faites par défaut pour augmenter la lisibilité du code, même si cela entraîne une légère augmentation du coût de l'essence. * ABI coder v2 est activé par défaut. +<<<<<<< HEAD Vous pouvez choisir d'utiliser l'ancien comportement en utilisant ``pragma abicoder v1;``. Le pragma ``pragma experimental ABIEncoderV2;`` est toujours valide, mais il est déprécié et n'a aucun effet. Si vous voulez être explicite, veuillez utiliser le pragma ``pragma abicoder v2;`` à la place. +======= + You can choose to use the old behavior using ``pragma abicoder v1;``. + The pragma ``pragma experimental ABIEncoderV2;`` is still valid, but it is deprecated and has no effect. + If you want to be explicit, please use ``pragma abicoder v2;`` instead. +>>>>>>> english/develop Notez que ABI coder v2 supporte plus de types que v1 et effectue plus de contrôles d'intégrité sur les entrées. ABI coder v2 rend certains appels de fonctions plus coûteux et il peut aussi faire des appels de contrats @@ -57,8 +71,13 @@ Nouvelles restrictions Cette section énumère les changements qui pourraient empêcher les contrats existants de se compiler. +<<<<<<< HEAD * Il existe de nouvelles restrictions liées aux conversions explicites de littéraux. Le comportement précédent dans les cas suivants était probablement ambigu : +======= +* There are new restrictions related to explicit conversions of literals. The previous behavior in + the following cases was likely ambiguous: +>>>>>>> english/develop 1. Les conversions explicites de littéraux négatifs et de littéraux plus grands que ``type(uint160).max`` en ``adresse`` sont interdites. @@ -106,7 +125,11 @@ Cette section énumère les changements qui pourraient empêcher les contrats ex * Les fonctions globales ``log0``, ``log1``, ``log2``, ``log3`` et ``log4`` ont été supprimées. +<<<<<<< HEAD Ce sont des fonctions de bas niveau qui étaient largement inutilisées. Leur comportement est accessible depuis l'assemblage en ligne. +======= + These are low-level functions that were largely unused. Their behavior can be accessed from inline assembly. +>>>>>>> english/develop * Les définitions de ``enum`` ne peuvent pas contenir plus de 256 membres. @@ -163,6 +186,7 @@ Changements d'interface Comment mettre à jour votre code ======================= +<<<<<<< HEAD - Si vous comptez sur l'arithmétique enveloppante, entourez chaque opération de ``unchecked { ... }``. - Optionnel : Si vous utilisez SafeMath ou une bibliothèque similaire, changez ``x.add(y)`` en ``x + y``, ``x.mul(y)`` en ``x * y`` etc. - Ajoutez ``pragma abicoder v1;`` si vous voulez rester avec l'ancien codeur ABI. @@ -174,3 +198,16 @@ Comment mettre à jour votre code - Remplacez ``x**y**z`` par ``(x**y)**z``. - Utilisez l'assemblage en ligne en remplacement de ``log0``, ..., ``log4``. - Négation des entiers non signés en les soustrayant de la valeur maximale du type et en ajoutant 1 (par exemple, ``type(uint256).max - x + 1``, tout en s'assurant que `x` n'est pas zéro) +======= +- If you rely on wrapping arithmetic, surround each operation with ``unchecked { ... }``. +- Optional: If you use SafeMath or a similar library, change ``x.add(y)`` to ``x + y``, ``x.mul(y)`` to ``x * y`` etc. +- Add ``pragma abicoder v1;`` if you want to stay with the old ABI coder. +- Optionally remove ``pragma experimental ABIEncoderV2`` or ``pragma abicoder v2`` since it is redundant. +- Change ``byte`` to ``bytes1``. +- Add intermediate explicit type conversions if required. +- Combine ``c.f{gas: 10000}{value: 1}()`` to ``c.f{gas: 10000, value: 1}()``. +- Change ``msg.sender.transfer(x)`` to ``payable(msg.sender).transfer(x)`` or use a stored variable of ``address payable`` type. +- Change ``x**y**z`` to ``(x**y)**z``. +- Use inline assembly as a replacement for ``log0``, ..., ``log4``. +- Negate unsigned integers by subtracting them from the maximum value of the type and adding 1 (e.g. ``type(uint256).max - x + 1``, while ensuring that ``x`` is not zero) +>>>>>>> english/develop diff --git a/docs/Makefile b/docs/Makefile index 3cc98f6990..01660bd388 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -34,7 +34,6 @@ help: @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @@ -116,12 +115,6 @@ latexpdf: $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..a3b5f25aed --- /dev/null +++ b/docs/README.md @@ -0,0 +1,23 @@ +# Solidity Language Docs + +## Local environment setup + +1. Install python https://www.python.org/downloads/ +1. Install sphinx (the tool used to generate the docs) https://www.sphinx-doc.org/en/master/usage/installation.html + +Go to `/docs` and run `./docs.sh` to install dependencies and build the project: + +```sh +cd docs +./docs.sh +``` + +That will output the generated htmls under _build/ + +## Serve environment + +```py +python3 -m http.server -d _build/html --cgi 8080 +``` + +Visit dev server at http://localhost:8080 diff --git a/docs/_static/css/custom-dark.css b/docs/_static/css/custom-dark.css new file mode 100644 index 0000000000..044a8f800d --- /dev/null +++ b/docs/_static/css/custom-dark.css @@ -0,0 +1,595 @@ + + +/* DARK MODE STYLING */ + +/* code directives */ + +:root[style*=dark] .method dt, +:root[style*=dark] .class dt, +:root[style*=dark] .data dt, +:root[style*=dark] .attribute dt, +:root[style*=dark] .function dt, +:root[style*=dark] .classmethod dt, +:root[style*=dark] .exception dt, +:root[style*=dark] .descclassname, +:root[style*=dark] .descname { + background-color: #2d2d2d !important; +} + +:root[style*=dark] .rst-content dl:not(.docutils) dt { + background-color: #0008; + border-top: solid 3px #fff2; + border-left: solid 3px #fff2; +} + +:root[style*=dark] em.property { + color: #888888; +} + + +/* tables */ + +:root[style*=dark] .rst-content table.docutils td { + border: 0px; +} + +:root[style*=dark] .rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td { + background-color: #0002; +} + +:root[style*=dark] .rst-content pre { + background: none; +} + +/* inlined code highlights */ + +:root[style*=dark] .xref, +:root[style*=dark] .py-meth { + color: #aaddff !important; + font-weight: normal !important; +} + +/* highlight color search text */ + +:root[style*=dark] .rst-content .highlighted { + background: #ff5722; + box-shadow: 0 0 0 2px #f0978b; +} + +/* notes, warnings, hints */ + +:root[style*=dark] .hint .admonition-title { + background: #2aa87c !important; +} + +:root[style*=dark] .warning .admonition-title { + background: #cc4444 !important; +} + +:root[style*=dark] .admonition-title { + background: #3a7ca8 !important; +} + +:root[style*=dark] .admonition, +:root[style*=dark] .note { + background-color: #0008 !important; +} + + +/* table of contents */ + +:root[style*=dark] .sidebar { + background-color: #191919 !important; +} + +:root[style*=dark] .sidebar-title { + background-color: #2b2b2b !important; +} + +:root[style*=dark] .wy-menu-vertical code.docutils.literal.notranslate { + background: none !important; + border: none !important; +} + + +:root[style*=dark] .toc-backref { + color: grey !important; +} + +:root[style*=dark] .highlight { + background: #0008; + color: #f8f8f2 +} + +:root[style*=dark] .highlight .c { + color: #888 +} + + +/* Comment */ + +:root[style*=dark] .highlight .err { + color: #960050; + background-color: #1e0010 +} + + +/* Error */ + +:root[style*=dark] .highlight .k { + color: #66d9ef +} + + +/* Keyword */ + +:root[style*=dark] .highlight .l { + color: #ae81ff +} + + +/* Literal */ + +:root[style*=dark] .highlight .n { + color: #f8f8f2 +} + + +/* Name */ + +:root[style*=dark] .highlight .o { + color: #f92672 +} + + +/* Operator */ + +:root[style*=dark] .highlight .p { + color: #f8f8f2 +} + + +/* Punctuation */ + +:root[style*=dark] .highlight .ch { + color: #888 +} + + +/* Comment.Hashbang */ + +:root[style*=dark] .highlight .cm { + color: #888 +} + + +/* Comment.Multiline */ + +:root[style*=dark] .highlight .cp { + color: #888 +} + + +/* Comment.Preproc */ + +:root[style*=dark] .highlight .cpf { + color: #888 +} + + +/* Comment.PreprocFile */ + +:root[style*=dark] .highlight .c1 { + color: #888 +} + + +/* Comment.Single */ + +:root[style*=dark] .highlight .cs { + color: #888 +} + + +/* Comment.Special */ + +:root[style*=dark] .highlight .gd { + color: #f92672 +} + + +/* Generic.Deleted */ + +:root[style*=dark] .highlight .ge { + font-style: italic +} + + +/* Generic.Emph */ + +:root[style*=dark] .highlight .gi { + color: #a6e22e +} + + +/* Generic.Inserted */ + +:root[style*=dark] .highlight .gs { + font-weight: bold +} + + +/* Generic.Strong */ + +:root[style*=dark] .highlight .gu { + color: #888 +} + + +/* Generic.Subheading */ + +:root[style*=dark] .highlight .kc { + color: #66d9ef +} + + +/* Keyword.Constant */ + +:root[style*=dark] .highlight .kd { + color: #66d9ef +} + + +/* Keyword.Declaration */ + +:root[style*=dark] .highlight .kn { + color: #f92672 +} + + +/* Keyword.Namespace */ + +:root[style*=dark] .highlight .kp { + color: #66d9ef +} + + +/* Keyword.Pseudo */ + +:root[style*=dark] .highlight .kr { + color: #66d9ef +} + + +/* Keyword.Reserved */ + +:root[style*=dark] .highlight .kt { + color: #66d9ef +} + + +/* Keyword.Type */ + +:root[style*=dark] .highlight .ld { + color: #e6db74 +} + + +/* Literal.Date */ + +:root[style*=dark] .highlight .m { + color: #ae81ff +} + + +/* Literal.Number */ + +:root[style*=dark] .highlight .s { + color: #e6db74 +} + + +/* Literal.String */ + +:root[style*=dark] .highlight .na { + color: #a6e22e +} + + +/* Name.Attribute */ + +:root[style*=dark] .highlight .nb { + color: #f8f8f2 +} + + +/* Name.Builtin */ + +:root[style*=dark] .highlight .nc { + color: #a6e22e +} + + +/* Name.Class */ + +:root[style*=dark] .highlight .no { + color: #66d9ef +} + + +/* Name.Constant */ + +:root[style*=dark] .highlight .nd { + color: #a6e22e +} + + +/* Name.Decorator */ + +:root[style*=dark] .highlight .ni { + color: #f8f8f2 +} + + +/* Name.Entity */ + +:root[style*=dark] .highlight .ne { + color: #a6e22e +} + + +/* Name.Exception */ + +:root[style*=dark] .highlight .nf { + color: #a6e22e +} + + +/* Name.Function */ + +:root[style*=dark] .highlight .nl { + color: #f8f8f2 +} + + +/* Name.Label */ + +:root[style*=dark] .highlight .nn { + color: #f8f8f2 +} + + +/* Name.Namespace */ + +:root[style*=dark] .highlight .nx { + color: #a6e22e +} + + +/* Name.Other */ + +:root[style*=dark] .highlight .py { + color: #f8f8f2 +} + + +/* Name.Property */ + +:root[style*=dark] .highlight .nt { + color: #f92672 +} + + +/* Name.Tag */ + +:root[style*=dark] .highlight .nv { + color: #f8f8f2 +} + + +/* Name.Variable */ + +:root[style*=dark] .highlight .ow { + color: #f92672 +} + + +/* Operator.Word */ + +:root[style*=dark] .highlight .w { + color: #f8f8f2 +} + + +/* Text.Whitespace */ + +:root[style*=dark] .highlight .mb { + color: #ae81ff +} + + +/* Literal.Number.Bin */ + +:root[style*=dark] .highlight .mf { + color: #ae81ff +} + + +/* Literal.Number.Float */ + +:root[style*=dark] .highlight .mh { + color: #ae81ff +} + + +/* Literal.Number.Hex */ + +:root[style*=dark] .highlight .mi { + color: #ae81ff +} + + +/* Literal.Number.Integer */ + +:root[style*=dark] .highlight .mo { + color: #ae81ff +} + + +/* Literal.Number.Oct */ + +:root[style*=dark] .highlight .sa { + color: #e6db74 +} + + +/* Literal.String.Affix */ + +:root[style*=dark] .highlight .sb { + color: #e6db74 +} + + +/* Literal.String.Backtick */ + +:root[style*=dark] .highlight .sc { + color: #e6db74 +} + + +/* Literal.String.Char */ + +:root[style*=dark] .highlight .dl { + color: #e6db74 +} + + +/* Literal.String.Delimiter */ + +:root[style*=dark] .highlight .sd { + color: #e6db74 +} + + +/* Literal.String.Doc */ + +:root[style*=dark] .highlight .s2 { + color: #e6db74 +} + + +/* Literal.String.Double */ + +:root[style*=dark] .highlight .se { + color: #ae81ff +} + + +/* Literal.String.Escape */ + +:root[style*=dark] .highlight .sh { + color: #e6db74 +} + + +/* Literal.String.Heredoc */ + +:root[style*=dark] .highlight .si { + color: #e6db74 +} + + +/* Literal.String.Interpol */ + +:root[style*=dark] .highlight .sx { + color: #e6db74 +} + + +/* Literal.String.Other */ + +:root[style*=dark] .highlight .sr { + color: #e6db74 +} + + +/* Literal.String.Regex */ + +:root[style*=dark] .highlight .s1 { + color: #e6db74 +} + + +/* Literal.String.Single */ + +:root[style*=dark] .highlight .ss { + color: #e6db74 +} + + +/* Literal.String.Symbol */ + +:root[style*=dark] .highlight .bp { + color: #f8f8f2 +} + + +/* Name.Builtin.Pseudo */ + +:root[style*=dark] .highlight .fm { + color: #a6e22e +} + + +/* Name.Function.Magic */ + +:root[style*=dark] .highlight .vc { + color: #f8f8f2 +} + + +/* Name.Variable.Class */ + +:root[style*=dark] .highlight .vg { + color: #f8f8f2 +} + + +/* Name.Variable.Global */ + +:root[style*=dark] .highlight .vi { + color: #f8f8f2 +} + + +/* Name.Variable.Instance */ + +:root[style*=dark] .highlight .vm { + color: #f8f8f2 +} + + +/* Name.Variable.Magic */ + +:root[style*=dark] .highlight .il { + color: #ae81ff +} + + +/* Grammar */ + +:root[style*=dark] .railroad-diagram { + fill: white; +} + +:root[style*=dark] .railroad-diagram path { + stroke: white; +} + +:root[style*=dark] .railroad-diagram rect { + stroke: white; +} + +:root[style*=dark] .a4 .sig-name { + background-color: transparent !important; +} diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css index 4ff53f3a7b..25ab265443 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -1,23 +1,185 @@ +/* ROOT DECLARATIONS */ +:root { + /* Text */ + --color-a: #2B247C; + --color-b: #672AC8; + --color-c: #5554D9; + --color-d: #9F94E8; + --color-e: #AEC0F1; + --color-f: #E6E3EC; + /* Background */ + + --white: #FAF8FF; + --black: #110C4E; + --menu-bg: #2B247C06; + --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + + --navHeight: 4.5rem; + --sideWidth: 300px; + --maxWidth: 80rem; + --desktopInlinePadding: 2rem; + --mobileInlinePadding: 1rem; + --currentVersionHeight: 45px; + + text-rendering: geometricPrecision; + -webkit-font-smoothing: antialiased; +} + +a, +button { + border-radius: 0; +} + +:root[style*=dark] { + --color-a: #E6E3EC !important; + --color-b: #AEC0F1 !important; + --color-c: #9F94E8 !important; + --color-d: #5554D9 !important; + --color-e: #672AC8 !important; + --color-f: #2B247C !important; + + --white: #110C4E !important; + --black: #FAF8FF !important; + --menu-bg: #E6E3EC06 !important; +} + +html, +body, +.unified-header::before, +.wy-nav-side, +.rst-versions, +code, +div, +input[type=text], +a, +.wy-grid-for-nav { + transition: background 150ms ease-in-out; +} + +html, +body, +.wy-grid-for-nav { + background-color: var(--color-f) !important; +} + +body { + font-family: "Overpass", sans-serif; +} + +a { + color: var(--color-c); +} + +a, section { + scroll-margin-top: calc(var(--navHeight) + 2rem); +} + +hr { + margin-block: 2rem; + border-color: var(--color-d) !important; +} + + +/* HEADER STYLES */ +h1 { + font-family: 'Overpass', sans-serif; + font-weight: 700; + font-size: 44px; + color: var(--color-a) !important; + line-height: 1.1; + text-wrap: balance; + margin-top: 4rem; + margin-bottom: 1.5rem; +} + +section:first-of-type h1:first-of-type { + font-family: 'Overpass mono', monospace; + font-size: 48px; + margin-top: 3rem; + margin-bottom: 5rem; +} + +h2 { + font-family: 'Overpass', sans-serif; + font-weight: 700; + font-size: 38px; + color: var(--color-a) !important; + line-height: 46px; + text-wrap: balance; + margin-top: 4rem; + margin-bottom: 1.5rem; +} + +*:not([role=navigation])>p[role=heading]>span, +h3 { + font-family: 'Overpass', sans-serif; + font-weight: 700; + font-size: 32px; + color: var(--color-a) !important; + line-height: 46px; + text-wrap: balance; + margin-top: 4rem; + margin-bottom: 1.5rem; +} + +h4 { + font-family: 'Overpass', sans-serif; + font-weight: 700; + font-size: 32px; + color: var(--color-a) !important; + line-height: 46px; + text-wrap: balance; + margin-top: 3rem; + margin-bottom: 1.5rem; +} + +h5 { + font-family: 'Overpass', sans-serif; + font-weight: 700; + font-size: 18px; + color: var(--color-a) !important; + line-height: 1.4; + text-wrap: balance; +} + +h6 { + font-family: 'Overpass', sans-serif; + font-weight: 700; + font-size: 16px; + color: var(--color-a) !important; + line-height: 1.4; + text-wrap: balance; +} + +span.pre, pre { - white-space: pre-wrap; /* css-3 */ - white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ + /* css-3 */ + white-space: pre-wrap; + /* Mozilla, since 1999 */ + white-space: -moz-pre-wrap; + /* Opera 4-6 */ + white-space: -pre-wrap; + /* Opera 7 */ + white-space: -o-pre-wrap; word-wrap: break-word; + font-family: 'Overpass Mono', monospace; } -.wy-table-responsive table td, .wy-table-responsive table th { +small, +small * { + font-size: 12px; +} + +.wy-table-responsive table td, +.wy-table-responsive table th { white-space: normal; } + .rst-content table.docutils td { vertical-align: top; } /* links */ -.rst-content a:not(:visited) { - color: #002fa7; -} - .rst-content .highlighted { background: #eac545; } @@ -27,60 +189,638 @@ pre { background: #fafafa; } -.wy-side-nav-search img.logo { - width: 100px !important; - padding: 0; +/* project version (displayed under project logo) */ +.wy-side-nav-search>div.version { + color: var(--color-b); + margin-top: 0; + margin-bottom: 0.5rem; + text-align: start; } -.wy-side-nav-search > a { - padding: 0; +/* Link to Remix IDE shown next to code snippets */ +.rst-content p.remix-link-container { + display: block; + text-align: right; margin: 0; + line-height: 1em; } -/* project version (displayed under project logo) */ -.wy-side-nav-search .version { - color: #272525 !important; +.rst-content .remix-link-container a.remix-link { + font-size: 0.7em; + padding: 0.1em 0.5em; + background: transparent; + color: var(--color-a) !important; + border: 1px solid var(--color-a); + text-decoration: none; } -/* menu section headers */ -.wy-menu .caption { - color: #65afff !important; +.rst-content div.highlight-solidity, +.rst-content div.highlight-yul { + margin-top: 0; } -/* Link to Remix IDE shown next to code snippets */ -p.remix-link-container { +/* CUSTOMIZATION UPDATES */ + +.wy-nav-content-wrap, +.wy-nav-content { + background: transparent !important; +} + +.wy-side-nav-search { + background-color: transparent !important; + color: var(--color-a) !important; + box-shadow: 0 4 4 0 var(--color-a); + border-bottom: 1px solid var(--color-d) !important; +} + +.wy-side-nav-search svg { + color: var(--color-a) !important; +} + +.wy-nav-top { + background-color: transparent !important; + color: var(--color-a) !important; +} + +.wy-nav-top a { + color: var(--color-a) !important; +} + +.wy-breadcrumbs a.icon-home:before { + content: "Documentation"; + font-family: "Overpass", sans-serif; +} + +.rst-content table.docutils thead { + color: var(--color-a); +} + +code.docutils.literal.notranslate { + padding: 2px 4px; + font-size: 0.875em; + font-family: "Overpass Mono", monospace; + background: var(--white); + color: var(--color-c); + border: 0px; +} + +dt code.docutils.literal.notranslate { + background: none; +} + +.wy-nav-content { + color: var(--color-a); +} + +/* .rst-content a:not(:visited) { */ +/* color: var(--color-b) !important; */ +/* } */ + +.rst-content a:visited { + color: var(--color-c) !important; +} + +.rst-content a { + text-decoration: underline; +} + +.rst-content a:where(:focus, :focus-visible, :hover) { + color: var(--color-d) !important; +} + +.wy-side-scroll a { + color: var(--color-a); + background: transparent; + font-size: 1rem; + line-height: 125%; +} + +.wy-menu-vertical li.current a, +.wy-menu-vertical li.current li a, +.wy-menu-vertical li.current li a code { + border: none; + color: var(--color-a); +} + +ul.current ul, +.wy-menu-vertical li.current a:hover, +.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a, +.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a, +.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a, +.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a, +.wy-menu-vertical li.current { + background: var(--menu-bg) !important; +} + +.wy-menu.wy-menu-vertical>ul { + margin-bottom: 3rem; +} + +.wy-menu.wy-menu-vertical>p { + color: var(--color-c); +} + +.wy-menu-vertical li.on a, +.wy-menu-vertical li.current>a { + background: var(--menu-bg) !important; + border-bottom: 0px !important; + border-top: 0px !important; +} + +.btn { + border-radius: 0; + text-decoration: none !important; +} + +.wy-breadcrumbs-aside a, +.wy-breadcrumbs-aside a:visited, +a.fa.fa-github, +a.fa.fa-github:visited, +a.fa.fa-github:not(:visited), +a.btn.btn-neutral:visited, +a.btn.btn-neutral:not(:visited), +a.btn.btn-neutral { + background: transparent !important; + color: var(--color-a) !important; + border: 2px solid var(--color-a) !important; + text-decoration: none; +} + +.rst-content .remix-link-container a.remix-link:hover, +.wy-breadcrumbs-aside a:hover, +a.fa.fa-github:hover, +a.btn.btn-neutral:hover { + background: var(--white) !important; + color: var(--color-b) !important; + border-color: var(--color-b) !important; +} + +footer .rst-footer-buttons { + display: flex; + justify-content: center; + gap: 2rem; +} + +/** + * Customization for the unified layout + */ + +/* Site wrapper, and two children: header and rest */ +.unified-wrapper { position: relative; - right: -100%; /* Positioned next to the the top-right corner of the code block following it. */ + display: flex; + flex-direction: column; + inset: 0; + max-width: var(--maxWidth); + margin-inline: auto; +} + +/* Site header */ +.unified-header { + position: fixed; + top: 0; + inset-inline: 0; + z-index: 99999; + display: flex; + align-items: center; + box-shadow: var(--shadow); } -a.remix-link { - position: absolute; /* Remove it from normal flow not to affect the original position of the snippet. */ - top: 0.5em; - width: 3.236em; /* Size of the margin (= right-side padding in .wy-nav-content in the current theme). */ +.unified-header .inner-header { + display: flex; + margin-inline: auto; + width: 100%; + max-width: var(--maxWidth); + align-items: center; + justify-content: space-between; + padding-inline: var(--desktopInlinePadding); + padding-block: 1rem; } -a.remix-link .link-icon { - background: url("../img/solid-share-arrow.svg") no-repeat; +.unified-header::before { + content: ""; + position: absolute; + inset: 0; + opacity: 95%; + background: var(--color-f); + z-index: -1; + backdrop-filter: blur(3px); +} + +.unified-header .home-link { display: block; - width: 1.5em; - height: 1.5em; - margin: auto; + text-decoration: none; + width: 25px; + height: 40px; } -a.remix-link .link-text { - display: none; /* Visible only on hover. */ - width: 3.3em; /* Narrow enough to get two lines of text. */ - margin: auto; - text-align: center; - font-size: 0.8em; - line-height: normal; - color: black; +.unified-header .home-link:hover .solidity-logo { + transform: scale(1.1); + transition: transform 100ms ease-in-out; } -a.remix-link:hover { +.unified-header img.solidity-logo { + transform: scale(1); + transition: transform 100ms ease-in-out; + width: 100%; + height: 100%; +} + +.unified-header .nav-bar { + display: flex; + align-items: center; + justify-content: flex-end; +} + +.unified-header .nav-bar .nav-button-container { + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; +} + +.unified-header .nav-link { + display: inline-block; + padding-inline: 8px; + padding-block: 4px; + font-size: 14px; + font-family: 'Overpass Mono', monospace; + text-decoration: none; + color: var(--color-a); + letter-spacing: -0.02em; + font-weight: 400; + box-sizing: content-box; + border-bottom: 1px solid transparent; + white-space: nowrap; +} + +.unified-header .nav-link.active { + background: var(--white); +} + +.unified-header .nav-link:hover { + color: var(--color-c); + border-bottom: 1px solid var(--color-c); +} + +/* Rest: Flex-row, with two children: side bar, and content */ +.unified-wrapper .wy-grid-for-nav { + position: relative !important; + display: flex; + margin-inline: auto; +} + +/* First child: Side bar */ +.unified-wrapper .wy-grid-for-nav nav.wy-nav-side { + position: fixed; + display: flex; + flex-direction: column; + background: var(--color-f); + color: var(--color-a); + padding-bottom: unset !important; + z-index: 10 !important; + min-height: unset !important; + width: var(--sideWidth) !important; + top: var(--navHeight); + bottom: 0; + left: auto; + overflow: auto; +} + +.unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll { + position: static !important; + width: unset !important; + overflow: unset !important; + height: unset !important; + padding-bottom: 2rem; +} + +.unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll .wy-side-nav-search { + margin: 0 !important; + width: var(--sideWidth) !important; +} + +.wy-nav-side, +.wy-side-scroll, +.wy-side-nav-search, +.my-menu { + width: 100% !important; +} + +.wy-nav-side input[type=text] { + font-family: "Overpass", sans-serif; + border-radius: 0; + border-color: var(--color-d); + background: var(--white); + box-shadow: none; + color: var(--color-a); +} + +.wy-nav-side input[type=text]::placeholder { + font-family: "Overpass", sans-serif; + color: var(--color-e); + font-size: 16px; + position: relative; + top: 4px; +} + +/* Second child: Content */ +.unified-wrapper .wy-grid-for-nav .wy-nav-content { + width: 100%; + max-width: unset !important; /* override */ + padding-inline: var(--desktopInlinePadding); + margin-inline-start: var(--sideWidth); + margin-top: var(--navHeight); +} + +.unified-wrapper .wy-grid-for-nav .wy-nav-content .rst-content { + max-width: min(70ch, calc(100vw - 2 * var(--desktopInlinePadding) - var(--sideWidth))); + margin-inline: auto; +} + +.unified-wrapper.menu-open .backdrop { opacity: 0.5; } -a.remix-link:hover .link-text { +.unified-wrapper .wy-nav-side, +.unified-wrapper .rst-versions { + left: auto; + +} + +.unified-wrapper .backdrop { + opacity: 0; + transition: opacity 200ms ease-in-out; +} + +@media (max-width: 768px) { + h2 { + margin-top: 3rem; + margin-bottom: 1rem; + } + + h3 { + margin-top: 3rem; + margin-bottom: 1rem; + } + + h4 { + margin-top: 2rem; + margin-bottom: 1rem; + } + + /* Menu closed styles */ + .unified-header .nav-link { + display: none; + } + + .unified-header .inner-header { + padding-inline: var(--mobileInlinePadding); + } + + .unified-wrapper .wy-grid-for-nav nav.wy-nav-side { + transform: translateX(-100%); + transition: transform 200ms ease-in-out; + } + + /* Menu open styles */ + .unified-wrapper.menu-open nav.wy-nav-side { + transform: translateX(0); + transition: transform 200ms ease-in-out; + } + + .unified-wrapper.menu-open .rst-versions { + position: sticky; + bottom: 0; + width: 100%; + } + + .unified-wrapper.menu-open .backdrop { + display: block; + position: fixed; + inset: 0; + opacity: 1; + transition: opacity 200ms ease-in-out; + z-index: 5; + background: #0006; + } + + a.skip-to-content { + display: none; + } + + .wy-nav-content { + margin-inline-start: 0 !important; + } + + .rst-content { + max-width: 100% !important; + } + + .wy-side-scroll { + padding-bottom: 0 !important; + } +} + +ul.search .context { + color: var(--color-a) !important; +} + +.rst-versions { + background: var(--color-f); +} + +.rst-versions.shift-up { + height: unset !important; + max-height: unset !important; + overflow-y: unset !important; +} + +.rst-content dl:not(.docutils) dt { + color: var(--color-a); + background-color: #fff8; + border-top: solid 3px #0002; + border-inline-start: solid 3px #0002; + padding: 2px 6px; +} + +.rst-versions .rst-current-version { + border-color: var(--color-d) !important; +} + +.rst-current-version *, +.rst-current-version .fa:before, +.rst-current-version .fa-element { + color: var(--color-b) !important; +} + +.rst-current-version dt, +.rst-current-version dd, +.rst-current-version dd a, +.rst-other-versions dl:last-of-type dt, +.rst-other-versions dl:last-of-type dd, +.rst-other-versions dl:last-of-type dd a { + font-size: 14px !important; +} + +.rst-other-versions { + background: var(--white) !important; + color: var(--color-a) !important; + max-height: calc(100vh - var(--navHeight) - var(--currentVersionHeight)); + overflow-y: scroll; +} + +.rst-other-versions a { + text-decoration: underline; + color: var(--color-c) !important; +} + +.rst-other-versions dt { + color: var(--color-a) !important; +} + +.rst-other-versions dl { + margin-bottom: 1.5rem !important; +} + +.rst-other-versions dl:last-of-type { + margin-top: 2rem !important; +} + +/* Bottom Search */ +.wy-nav-side input[type=text], +.rst-other-versions dl:last-of-type dd { + width: 100%; +} + +.rst-other-versions dl:last-of-type dt { + color: var(--color-b) !important; +} + +.rst-other-versions dl:last-of-type div[style*=padding], +.rst-other-versions dl dd:first-of-type a { + padding-inline-start: 0 !important; +} + +button.toctree-expand { + color: var(--black) !important; +} + +/* Light/dark color mode toggle 🌓 */ +button.color-toggle { + display: inline-flex; + appearance: none; + -webkit-box-align: center; + align-items: center; + -webkit-box-pack: center; + justify-content: center; + user-select: none; + outline: none; + height: 28px; + width: 28px; + background: none; + border: none; + padding: 6px; + margin: 6px; + transition-duration: 200ms; + transition-property: background-color, + color, + fill, + stroke, + opacity; +} + +button.color-toggle:focus-visible { + outline: 2px solid var(--color-c); + color: var(--color-c); +} + +button.color-toggle:hover { + color: var(--color-c); + background: #0002; +} + +button.color-toggle .color-toggle-icon { + width: 100%; + height: 100%; + margin: 0; + display: inline-block; + line-height: 1em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + vertical-align: middle; + /* color: var(--color-a); */ +} + + +button.mobile-menu-button { + display: none; +} + +@media (max-width: 768px) { + nav.wy-nav-top { + display: none; + } + + button.mobile-menu-button { + display: flex; + } +} + + +.hidden { + display: none; +} + +#search-results .search li:first-child, +#search-results .search li { + border-color: var(--color-d); +} + +#search-results .search li:last-child { + border: 0px; +} + +.forum-link::after { + content: ' ↗'; + font-size: 14px; + font-family: 'Overpass Mono', monospace; +} + +.wy-breadcrumbs>li { + padding-top: 8px; +} + +.wy-breadcrumbs-aside a { + padding: 0.5rem 0.75rem; + font-size: 12px; + font-family: "'Overpass'", sans-serif; + font-weight: 700; +} + +a.skip-to-content:visited, +a.skip-to-content:not(:visited), +a.skip-to-content { display: block; + pointer-events: none; + width: fit-content; + opacity: 0; + transition: opacity 200ms ease-in-out; + padding: 2px 4px; + font-size: 14px; + margin-inline-end: auto; + margin-inline-start: 1.5rem; + color: var(--color-a); + white-space: nowrap; } + +a.skip-to-content:focus { + opacity: 1; + transition: opacity 200ms ease-in-out; +} + +#content { + scroll-margin-top: 6rem; + scroll-behavior: smooth; +} \ No newline at end of file diff --git a/docs/_static/css/dark.css b/docs/_static/css/dark.css deleted file mode 100644 index a87ff09ebe..0000000000 --- a/docs/_static/css/dark.css +++ /dev/null @@ -1,635 +0,0 @@ -/* links */ - -.rst-content a:not(:visited) { - color: #aaddff !important; -} - -/* code directives */ - -.method dt, -.class dt, -.data dt, -.attribute dt, -.function dt, -.classmethod dt, -.exception dt, -.descclassname, -.descname { - background-color: #2d2d2d !important; -} - -.rst-content dl:not(.docutils) dt { - color: #aaddff; - background-color: #2d2d2d; - border-top: solid 3px #525252; - border-left: solid 3px #525252; -} - -em.property { - color: #888888; -} - - -/* tables */ - -.rst-content table.docutils thead { - color: #ddd; -} - -.rst-content table.docutils td { - border: 0px; -} - -.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td { - background-color: #5a5a5a; -} - -.rst-content pre { - background: none; -} - -/* inlined code highlights */ - -.xref, -.py-meth, -.rst-content a code { - color: #aaddff !important; - font-weight: normal !important; -} - -.rst-content code { - color: #eee !important; - font-weight: normal !important; -} - -code.literal { - background-color: #2d2d2d !important; - border: 1px solid #6d6d6d !important; -} - -code.docutils.literal.notranslate { - color: #ddd; -} - -/* highlight color search text */ - -.rst-content .highlighted { - background: #ff5722; - box-shadow: 0 0 0 2px #f0978b; -} - -/* notes, warnings, hints */ - -.hint .admonition-title { - background: #2aa87c !important; -} - -.warning .admonition-title { - background: #cc4444 !important; -} - -.admonition-title { - background: #3a7ca8 !important; -} - -.admonition, -.note { - background-color: #2d2d2d !important; -} - - -/* table of contents */ - -.wy-nav-content-wrap { - background-color: rgba(0, 0, 0, 0.6) !important; -} - -.sidebar { - background-color: #191919 !important; -} - -.sidebar-title { - background-color: #2b2b2b !important; -} - -.wy-menu-vertical a { - color: #ddd; -} - -.wy-menu-vertical code.docutils.literal.notranslate { - color: #404040; - background: none !important; - border: none !important; -} - -.wy-nav-content { - background: #3c3c3c; - color: #dddddd; -} - -.wy-menu-vertical li.on a, -.wy-menu-vertical li.current>a { - background: #a3a3a3; - border-bottom: 0px !important; - border-top: 0px !important; -} - -.wy-menu-vertical li.current { - background: #b3b3b3; -} - -.toc-backref { - color: grey !important; -} - -.highlight .hll { - background-color: #49483e -} - -.highlight { - background: #222; - color: #f8f8f2 -} - -.highlight .c { - color: #888 -} - - -/* Comment */ - -.highlight .err { - color: #960050; - background-color: #1e0010 -} - - -/* Error */ - -.highlight .k { - color: #66d9ef -} - - -/* Keyword */ - -.highlight .l { - color: #ae81ff -} - - -/* Literal */ - -.highlight .n { - color: #f8f8f2 -} - - -/* Name */ - -.highlight .o { - color: #f92672 -} - - -/* Operator */ - -.highlight .p { - color: #f8f8f2 -} - - -/* Punctuation */ - -.highlight .ch { - color: #888 -} - - -/* Comment.Hashbang */ - -.highlight .cm { - color: #888 -} - - -/* Comment.Multiline */ - -.highlight .cp { - color: #888 -} - - -/* Comment.Preproc */ - -.highlight .cpf { - color: #888 -} - - -/* Comment.PreprocFile */ - -.highlight .c1 { - color: #888 -} - - -/* Comment.Single */ - -.highlight .cs { - color: #888 -} - - -/* Comment.Special */ - -.highlight .gd { - color: #f92672 -} - - -/* Generic.Deleted */ - -.highlight .ge { - font-style: italic -} - - -/* Generic.Emph */ - -.highlight .gi { - color: #a6e22e -} - - -/* Generic.Inserted */ - -.highlight .gs { - font-weight: bold -} - - -/* Generic.Strong */ - -.highlight .gu { - color: #888 -} - - -/* Generic.Subheading */ - -.highlight .kc { - color: #66d9ef -} - - -/* Keyword.Constant */ - -.highlight .kd { - color: #66d9ef -} - - -/* Keyword.Declaration */ - -.highlight .kn { - color: #f92672 -} - - -/* Keyword.Namespace */ - -.highlight .kp { - color: #66d9ef -} - - -/* Keyword.Pseudo */ - -.highlight .kr { - color: #66d9ef -} - - -/* Keyword.Reserved */ - -.highlight .kt { - color: #66d9ef -} - - -/* Keyword.Type */ - -.highlight .ld { - color: #e6db74 -} - - -/* Literal.Date */ - -.highlight .m { - color: #ae81ff -} - - -/* Literal.Number */ - -.highlight .s { - color: #e6db74 -} - - -/* Literal.String */ - -.highlight .na { - color: #a6e22e -} - - -/* Name.Attribute */ - -.highlight .nb { - color: #f8f8f2 -} - - -/* Name.Builtin */ - -.highlight .nc { - color: #a6e22e -} - - -/* Name.Class */ - -.highlight .no { - color: #66d9ef -} - - -/* Name.Constant */ - -.highlight .nd { - color: #a6e22e -} - - -/* Name.Decorator */ - -.highlight .ni { - color: #f8f8f2 -} - - -/* Name.Entity */ - -.highlight .ne { - color: #a6e22e -} - - -/* Name.Exception */ - -.highlight .nf { - color: #a6e22e -} - - -/* Name.Function */ - -.highlight .nl { - color: #f8f8f2 -} - - -/* Name.Label */ - -.highlight .nn { - color: #f8f8f2 -} - - -/* Name.Namespace */ - -.highlight .nx { - color: #a6e22e -} - - -/* Name.Other */ - -.highlight .py { - color: #f8f8f2 -} - - -/* Name.Property */ - -.highlight .nt { - color: #f92672 -} - - -/* Name.Tag */ - -.highlight .nv { - color: #f8f8f2 -} - - -/* Name.Variable */ - -.highlight .ow { - color: #f92672 -} - - -/* Operator.Word */ - -.highlight .w { - color: #f8f8f2 -} - - -/* Text.Whitespace */ - -.highlight .mb { - color: #ae81ff -} - - -/* Literal.Number.Bin */ - -.highlight .mf { - color: #ae81ff -} - - -/* Literal.Number.Float */ - -.highlight .mh { - color: #ae81ff -} - - -/* Literal.Number.Hex */ - -.highlight .mi { - color: #ae81ff -} - - -/* Literal.Number.Integer */ - -.highlight .mo { - color: #ae81ff -} - - -/* Literal.Number.Oct */ - -.highlight .sa { - color: #e6db74 -} - - -/* Literal.String.Affix */ - -.highlight .sb { - color: #e6db74 -} - - -/* Literal.String.Backtick */ - -.highlight .sc { - color: #e6db74 -} - - -/* Literal.String.Char */ - -.highlight .dl { - color: #e6db74 -} - - -/* Literal.String.Delimiter */ - -.highlight .sd { - color: #e6db74 -} - - -/* Literal.String.Doc */ - -.highlight .s2 { - color: #e6db74 -} - - -/* Literal.String.Double */ - -.highlight .se { - color: #ae81ff -} - - -/* Literal.String.Escape */ - -.highlight .sh { - color: #e6db74 -} - - -/* Literal.String.Heredoc */ - -.highlight .si { - color: #e6db74 -} - - -/* Literal.String.Interpol */ - -.highlight .sx { - color: #e6db74 -} - - -/* Literal.String.Other */ - -.highlight .sr { - color: #e6db74 -} - - -/* Literal.String.Regex */ - -.highlight .s1 { - color: #e6db74 -} - - -/* Literal.String.Single */ - -.highlight .ss { - color: #e6db74 -} - - -/* Literal.String.Symbol */ - -.highlight .bp { - color: #f8f8f2 -} - - -/* Name.Builtin.Pseudo */ - -.highlight .fm { - color: #a6e22e -} - - -/* Name.Function.Magic */ - -.highlight .vc { - color: #f8f8f2 -} - - -/* Name.Variable.Class */ - -.highlight .vg { - color: #f8f8f2 -} - - -/* Name.Variable.Global */ - -.highlight .vi { - color: #f8f8f2 -} - - -/* Name.Variable.Instance */ - -.highlight .vm { - color: #f8f8f2 -} - - -/* Name.Variable.Magic */ - -.highlight .il { - color: #ae81ff -} - - -/* Literal.Number.Integer.Long */ - - -/* Link to Remix IDE shown over code snippets */ -a.remix-link { - filter: invert(1); /* The icon is black. In dark mode we want it white. */ -} diff --git a/docs/_static/css/fonts.css b/docs/_static/css/fonts.css new file mode 100644 index 0000000000..1a987a6da1 --- /dev/null +++ b/docs/_static/css/fonts.css @@ -0,0 +1,2 @@ +@import url("https://fonts.cdnfonts.com/css/overpass"); +@import url("https://fonts.cdnfonts.com/css/overpass-mono"); \ No newline at end of file diff --git a/docs/_static/css/pygments.css b/docs/_static/css/pygments.css new file mode 100644 index 0000000000..0e640681de --- /dev/null +++ b/docs/_static/css/pygments.css @@ -0,0 +1,399 @@ +pre { + line-height: 125%; +} + +td.linenos .normal { + color: inherit; + background-color: transparent; + padding-left: 5px; + padding-right: 5px; +} + +span.linenos { + color: inherit; + background-color: transparent; + padding-left: 5px; + padding-right: 5px; +} + +td.linenos .special { + color: #000000; + background-color: #ffffc0; + padding-left: 5px; + padding-right: 5px; +} + +span.linenos.special { + color: #000000; + background-color: #ffffc0; + padding-left: 5px; + padding-right: 5px; +} + +.highlight .hll { + background-color: #ffffcc +} + +.highlight { + background: #eeffcc; +} + +.highlight .c { + color: #408090; + font-style: italic +} + +/* Comment */ +.highlight .err { + border: 1px solid #FF0000 +} + +/* Error */ +.highlight .k { + color: #007020; + font-weight: bold +} + +/* Keyword */ +.highlight .o { + color: #666666 +} + +/* Operator */ +.highlight .ch { + color: #408090; + font-style: italic +} + +/* Comment.Hashbang */ +.highlight .cm { + color: #408090; + font-style: italic +} + +/* Comment.Multiline */ +.highlight .cp { + color: #007020 +} + +/* Comment.Preproc */ +.highlight .cpf { + color: #408090; + font-style: italic +} + +/* Comment.PreprocFile */ +.highlight .c1 { + color: #408090; + font-style: italic +} + +/* Comment.Single */ +.highlight .cs { + color: #408090; + background-color: #fff0f0 +} + +/* Comment.Special */ +.highlight .gd { + color: #A00000 +} + +/* Generic.Deleted */ +.highlight .ge { + font-style: italic +} + +/* Generic.Emph */ +.highlight .gr { + color: #FF0000 +} + +/* Generic.Error */ +.highlight .gh { + color: #000080; + font-weight: bold +} + +/* Generic.Heading */ +.highlight .gi { + color: #00A000 +} + +/* Generic.Inserted */ +.highlight .go { + color: #333333 +} + +/* Generic.Output */ +.highlight .gp { + color: #c65d09; + font-weight: bold +} + +/* Generic.Prompt */ +.highlight .gs { + font-weight: bold +} + +/* Generic.Strong */ +.highlight .gu { + color: #800080; + font-weight: bold +} + +/* Generic.Subheading */ +.highlight .gt { + color: #0044DD +} + +/* Generic.Traceback */ +.highlight .kc { + color: #007020; + font-weight: bold +} + +/* Keyword.Constant */ +.highlight .kd { + color: #007020; + font-weight: bold +} + +/* Keyword.Declaration */ +.highlight .kn { + color: #007020; + font-weight: bold +} + +/* Keyword.Namespace */ +.highlight .kp { + color: #007020 +} + +/* Keyword.Pseudo */ +.highlight .kr { + color: #007020; + font-weight: bold +} + +/* Keyword.Reserved */ +.highlight .kt { + color: #902000 +} + +/* Keyword.Type */ +.highlight .m { + color: #208050 +} + +/* Literal.Number */ +.highlight .s { + color: #4070a0 +} + +/* Literal.String */ +.highlight .na { + color: #4070a0 +} + +/* Name.Attribute */ +.highlight .nb { + color: #007020 +} + +/* Name.Builtin */ +.highlight .nc { + color: #0e84b5; + font-weight: bold +} + +/* Name.Class */ +.highlight .no { + color: #60add5 +} + +/* Name.Constant */ +.highlight .nd { + color: #555555; + font-weight: bold +} + +/* Name.Decorator */ +.highlight .ni { + color: #d55537; + font-weight: bold +} + +/* Name.Entity */ +.highlight .ne { + color: #007020 +} + +/* Name.Exception */ +.highlight .nf { + color: #06287e +} + +/* Name.Function */ +.highlight .nl { + color: #002070; + font-weight: bold +} + +/* Name.Label */ +.highlight .nn { + color: #0e84b5; + font-weight: bold +} + +/* Name.Namespace */ +.highlight .nt { + color: #062873; + font-weight: bold +} + +/* Name.Tag */ +.highlight .nv { + color: #bb60d5 +} + +/* Name.Variable */ +.highlight .ow { + color: #007020; + font-weight: bold +} + +/* Operator.Word */ +.highlight .w { + color: #bbbbbb +} + +/* Text.Whitespace */ +.highlight .mb { + color: #208050 +} + +/* Literal.Number.Bin */ +.highlight .mf { + color: #208050 +} + +/* Literal.Number.Float */ +.highlight .mh { + color: #208050 +} + +/* Literal.Number.Hex */ +.highlight .mi { + color: #208050 +} + +/* Literal.Number.Integer */ +.highlight .mo { + color: #208050 +} + +/* Literal.Number.Oct */ +.highlight .sa { + color: #4070a0 +} + +/* Literal.String.Affix */ +.highlight .sb { + color: #4070a0 +} + +/* Literal.String.Backtick */ +.highlight .sc { + color: #4070a0 +} + +/* Literal.String.Char */ +.highlight .dl { + color: #4070a0 +} + +/* Literal.String.Delimiter */ +.highlight .sd { + color: #4070a0; + font-style: italic +} + +/* Literal.String.Doc */ +.highlight .s2 { + color: #4070a0 +} + +/* Literal.String.Double */ +.highlight .se { + color: #4070a0; + font-weight: bold +} + +/* Literal.String.Escape */ +.highlight .sh { + color: #4070a0 +} + +/* Literal.String.Heredoc */ +.highlight .si { + color: #70a0d0; + font-style: italic +} + +/* Literal.String.Interpol */ +.highlight .sx { + color: #c65d09 +} + +/* Literal.String.Other */ +.highlight .sr { + color: #235388 +} + +/* Literal.String.Regex */ +.highlight .s1 { + color: #4070a0 +} + +/* Literal.String.Single */ +.highlight .ss { + color: #517918 +} + +/* Literal.String.Symbol */ +.highlight .bp { + color: #007020 +} + +/* Name.Builtin.Pseudo */ +.highlight .fm { + color: #06287e +} + +/* Name.Function.Magic */ +.highlight .vc { + color: #bb60d5 +} + +/* Name.Variable.Class */ +.highlight .vg { + color: #bb60d5 +} + +/* Name.Variable.Global */ +.highlight .vi { + color: #bb60d5 +} + +/* Name.Variable.Instance */ +.highlight .vm { + color: #bb60d5 +} + +/* Name.Variable.Magic */ +.highlight .il { + color: #208050 +} + +/* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/_static/css/toggle.css b/docs/_static/css/toggle.css index add134f6c2..6f03e6fb6a 100644 --- a/docs/_static/css/toggle.css +++ b/docs/_static/css/toggle.css @@ -9,6 +9,13 @@ input[type=checkbox] { padding: 10px; display: flex; justify-content: space-between; + background-color: var(--color-f); + border-top: 1px solid var(--color-c); +} + +.fa-caret-down, +.fa-book { + color: var(--color-a) !important; } .rst-versions .rst-current-version .fa-book, @@ -76,8 +83,6 @@ html.transition *:after { transition-delay: 0 !important; } -nav.wy-nav-side { - /* The default padding of 2em is too small and the "Keyword Index" link gets obscured - * by the version toggle. */ - padding-bottom: 3em; -} +.wy-menu-vertical a:hover { + background-color: #0002; +} \ No newline at end of file diff --git a/docs/_static/img/favicon.ico b/docs/_static/img/favicon.ico new file mode 100644 index 0000000000..a2b8f877a3 Binary files /dev/null and b/docs/_static/img/favicon.ico differ diff --git a/docs/_static/img/favicon.png b/docs/_static/img/favicon.png new file mode 100644 index 0000000000..3991d87e98 Binary files /dev/null and b/docs/_static/img/favicon.png differ diff --git a/docs/_static/img/hamburger-dark.svg b/docs/_static/img/hamburger-dark.svg new file mode 100644 index 0000000000..26d9fed9df --- /dev/null +++ b/docs/_static/img/hamburger-dark.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/docs/_static/img/hamburger-light.svg b/docs/_static/img/hamburger-light.svg new file mode 100644 index 0000000000..d5d0d0aed2 --- /dev/null +++ b/docs/_static/img/hamburger-light.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/docs/_static/img/logo-dark.svg b/docs/_static/img/logo-dark.svg new file mode 100644 index 0000000000..92a12a9fed --- /dev/null +++ b/docs/_static/img/logo-dark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docs/_static/img/logo.svg b/docs/_static/img/logo.svg new file mode 100644 index 0000000000..19391843b4 --- /dev/null +++ b/docs/_static/img/logo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docs/_static/img/moon.svg b/docs/_static/img/moon.svg new file mode 100644 index 0000000000..607dc1b47f --- /dev/null +++ b/docs/_static/img/moon.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/docs/_static/img/sun.svg b/docs/_static/img/sun.svg new file mode 100644 index 0000000000..f86fd22b2d --- /dev/null +++ b/docs/_static/img/sun.svg @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/docs/_static/js/constants.js b/docs/_static/js/constants.js new file mode 100644 index 0000000000..67fa16cdb0 --- /dev/null +++ b/docs/_static/js/constants.js @@ -0,0 +1,38 @@ +// Site URL +const SITE_URL = "https://docs.soliditylang.org" +const { origin, pathname } = location; +const pathSplit = pathname.split("/"); +const rootPath = origin.includes(SITE_URL) && pathSplit.length > 3 ? pathSplit.splice(1, 2).join("/") : '' +const ROOT_URL = `${origin}/${rootPath}`; + +// Color mode constants +const [DARK, LIGHT] = ["dark", "light"]; +const LIGHT_LOGO_PATH = `${ROOT_URL}/_static/img/logo.svg`; +const DARK_LOGO_PATH = `${ROOT_URL}/_static/img/logo-dark.svg`; +const SUN_ICON_PATH = `${ROOT_URL}/_static/img/sun.svg`; +const MOON_ICON_PATH = `${ROOT_URL}/_static/img/moon.svg`; +const LIGHT_HAMBURGER_PATH = `${ROOT_URL}/_static/img/hamburger-light.svg`; +const DARK_HAMBURGER_PATH = `${ROOT_URL}/_static/img/hamburger-dark.svg`; +const COLOR_TOGGLE_ICON_CLASS = "color-toggle-icon"; +const SOLIDITY_LOGO_CLASS = "solidity-logo"; +const LS_COLOR_SCHEME = "color-scheme"; + +// Solidity navigation constants +const SOLIDITY_HOME_URL = "https://soliditylang.org"; +const BLOG_URL = `${SOLIDITY_HOME_URL}/blog`; +const DOCS_URL = "/"; +const USE_CASES_PATH = `${SOLIDITY_HOME_URL}/use-cases`; +const CONTRIBUTE_PATH = `/en/latest/contributing.html`; +const ABOUT_PATH = `${SOLIDITY_HOME_URL}/about`; +const FORUM_URL = "https://forum.soliditylang.org/"; +const NAV_LINKS = [ + { name: "Blog", href: BLOG_URL }, + { name: "Documentation", href: DOCS_URL }, + { name: "Use cases", href: USE_CASES_PATH }, + { name: "Contribute", href: CONTRIBUTE_PATH }, + { name: "About", href: ABOUT_PATH }, + { name: "Forum", href: FORUM_URL }, +]; + +const MOBILE_MENU_TOGGLE_CLASS = "shift"; +const WRAPPER_CLASS = "unified-wrapper"; diff --git a/docs/_static/js/initialize.js b/docs/_static/js/initialize.js new file mode 100644 index 0000000000..a20d4fce71 --- /dev/null +++ b/docs/_static/js/initialize.js @@ -0,0 +1,250 @@ +const getLogoSrc = (isDark) => (isDark ? DARK_LOGO_PATH : LIGHT_LOGO_PATH); + +const getModeIconSrc = (isDark) => (isDark ? SUN_ICON_PATH : MOON_ICON_PATH); + +const getMenuIconSrc = (isDark) => + isDark ? DARK_HAMBURGER_PATH : LIGHT_HAMBURGER_PATH; + +function addFooterNote() { + const contentInfo = document.querySelector("div[role=contentinfo]"); + const footerNote = document.createElement("p"); + footerNote.classList.add("footer-note"); + footerNote.innerHTML = + 'Customized with ❤️ by the ethereum.org team.'; + contentInfo.parentNode.insertBefore(footerNote, contentInfo.nextSibling); +} + +function rearrangeDom() { + const bodyDivs = document.querySelectorAll("body>div"); + bodyDivs.forEach((div) => div.remove()); + const wrapperDiv = document.createElement("div"); + wrapperDiv.classList.add(WRAPPER_CLASS); + bodyDivs.forEach((div) => wrapperDiv.appendChild(div)); + document.body.prepend(wrapperDiv); + + const rstVersions = document.querySelector(".rst-versions"); + rstVersions.remove(); + const wyNavSide = document.querySelector("nav.wy-nav-side"); + wyNavSide.appendChild(rstVersions); + const backdrop = document.createElement("div"); + backdrop.classList.add("backdrop"); + wrapperDiv.appendChild(backdrop); + + const content = document.querySelector(".wy-nav-content"); + content.id = "content"; + const oldWrap = document.querySelector("section.wy-nav-content-wrap"); + oldWrap.remove(); + document.querySelector(".wy-grid-for-nav").appendChild(content); +} + +function buildHeader() { + const isDarkMode = localStorage.getItem(LS_COLOR_SCHEME) == DARK; + + const header = document.createElement("div"); + header.classList.add("unified-header"); + document.querySelector(`.${WRAPPER_CLASS}`).prepend(header); + + const innerHeader = document.createElement("div"); + innerHeader.classList.add("inner-header"); + header.appendChild(innerHeader); + + const homeLink = document.createElement("a"); + homeLink.classList.add("home-link"); + homeLink.href = SOLIDITY_HOME_URL; + homeLink.ariaLabel = "Solidity home"; + innerHeader.appendChild(homeLink); + + const logo = document.createElement("img"); + logo.classList.add(SOLIDITY_LOGO_CLASS); + logo.src = getLogoSrc(isDarkMode); + logo.alt = "Solidity logo"; + homeLink.appendChild(logo); + + const skipToContent = document.createElement("a"); + skipToContent.classList.add("skip-to-content"); + skipToContent.href = "#content"; + skipToContent.innerText = "{skip to content}"; + innerHeader.appendChild(skipToContent); + + const navBar = document.createElement("nav"); + navBar.classList.add("nav-bar"); + innerHeader.appendChild(navBar); + + const linkElements = NAV_LINKS.map(({ name, href }) => { + const link = document.createElement("a"); + link.classList.add("nav-link"); + link.setAttribute("key", name); + link.setAttribute("href", href); + link.setAttribute("aria-label", name); + if (href === FORUM_URL) { + link.classList.add("forum-link"); + link.setAttribute("target", "_blank"); + link.setAttribute("rel", "noopener noreferrer"); + } + link.innerText = name; + return link; + }); + linkElements.forEach((link) => navBar.appendChild(link)); + + // Flex wrapper for color mode and mobile menu buttons + const navButtonContainer = document.createElement("div"); + navButtonContainer.classList.add("nav-button-container"); + navBar.appendChild(navButtonContainer); + + // Build color toggle + const toggleIcon = document.createElement("img"); + toggleIcon.classList.add(COLOR_TOGGLE_ICON_CLASS); + toggleIcon.src = getModeIconSrc(isDarkMode); + toggleIcon.alt = "Color mode toggle icon"; + toggleIcon.setAttribute("aria-hidden", "true"); + toggleIcon.setAttribute("key", "toggle icon"); + const colorModeButton = document.createElement("button"); + colorModeButton.classList.add("color-toggle"); + colorModeButton.setAttribute("type", "button"); + colorModeButton.setAttribute("aria-label", "Toggle light dark mode"); + colorModeButton.setAttribute("key", "color mode button"); + colorModeButton.addEventListener("click", toggleColorMode); + colorModeButton.appendChild(toggleIcon); + navButtonContainer.appendChild(colorModeButton); + + // Build mobile hamburger menu + const menuIcon = document.createElement("img"); + menuIcon.classList.add(COLOR_TOGGLE_ICON_CLASS); + menuIcon.src = getMenuIconSrc(isDarkMode); + menuIcon.alt = "Toggle menu"; + menuIcon.setAttribute("aria-hidden", "true"); + menuIcon.setAttribute("key", "menu icon"); + const menuButton = document.createElement("button"); + menuButton.classList.add("color-toggle"); + menuButton.classList.add("mobile-menu-button"); + menuButton.setAttribute("type", "button"); + menuButton.setAttribute("aria-label", "Toggle menu"); + menuButton.setAttribute("key", "menu button"); + menuButton.addEventListener("click", toggleMenu); + menuButton.appendChild(menuIcon); + navButtonContainer.appendChild(menuButton); +} + +const updateActiveNavLink = () => { + const navLinks = document.querySelectorAll(".unified-header .nav-link"); + navLinks.forEach((link) => { + const href = link.getAttribute("href"); + if (document.documentURI.includes("contributing.html")) { + link.classList[href.includes("contributing.html") ? "add" : "remove"]( + "active" + ); + } else { + link.classList[document.documentURI.includes(href) ? "add" : "remove"]( + "active" + ); + } + }); +}; + +document.addEventListener("locationchange", updateActiveNavLink); + +function updateGitHubEditPath() { + // Replaces the version number in the GitHub edit path with "develop" + const gitHubEditAnchor = document.querySelector(".wy-breadcrumbs-aside > a"); + const url = new URL(gitHubEditAnchor.href); + const split = url.pathname.split("/"); + const versionIndex = split.indexOf("blob") + 1; + split[versionIndex] = "develop"; + url.pathname = split.join("/"); + gitHubEditAnchor.setAttribute("href", url.toString()); + gitHubEditAnchor.setAttribute("target", "_blank"); + gitHubEditAnchor.setAttribute("rel", "noopener noreferrer"); +} + +function initialize() { + // Rearrange DOM elements for styling + rearrangeDom(); + + // Check localStorage for existing color scheme preference + var prefersDark = localStorage.getItem(LS_COLOR_SCHEME) == DARK; + // Check link for search param "color"... it may be "light" or "dark" + var urlParams = new URLSearchParams(window.location.search); + if (urlParams.size > 0) { + // This is used for color mode continuity between the main Solidity Lang site and the docs + var colorSchemeParam = urlParams.get("color"); + // If present, overwrite prefersDark accordingly + if (colorSchemeParam) { + prefersDark = colorSchemeParam == DARK; + } + + // Remove "color" search param from URL + const { location, title } = document; + const { pathname, origin, search, hash } = location; + const newSearchParams = new URLSearchParams(search); + newSearchParams.delete("color"); + const sanitizedSearch = + newSearchParams.size < 1 ? "" : "?" + newSearchParams.toString(); + window.history.replaceState( + origin, + title, + pathname + sanitizedSearch + hash + ); + } + + // In case none existed, establish localStorage color scheme preference + var mode = prefersDark ? DARK : LIGHT; + localStorage.setItem(LS_COLOR_SCHEME, mode); + + // Select the root element and set the style attribute to denote color-scheme attribute + document + .querySelector(":root") + .setAttribute("style", `--color-scheme: ${mode}`); + + // Remove old input and RTD logo anchor element + document.querySelector("input[name=mode]").remove(); + document.querySelector("label[for=switch]").remove(); + document.querySelector(".wy-side-nav-search > a").remove(); + + // Add footer note + addFooterNote(); + + // Build header + buildHeader(); + + // Close menu + toggleMenu({ force: false }); + + // Update active nav link + updateActiveNavLink(); + + // Update GitHub edit path to direct to `develop` branch + updateGitHubEditPath(); +} + +document.addEventListener("DOMContentLoaded", initialize); + +const handleClick = (e) => { + if (e.target.closest(".backdrop")) { + toggleMenu({ force: false }); + } + + if (e.target.closest("a")) { + const target = e.target.closest("a"); + const href = target.getAttribute("href"); + if (href.includes(SOLIDITY_HOME_URL)) { + const url = new URL(href); + const params = new URLSearchParams(url.search); + params.set("color", localStorage.getItem(LS_COLOR_SCHEME)); + url.search = params.toString(); + target.setAttribute("href", url.toString()); + } + } +}; +document.addEventListener("click", handleClick); + +const handleKeyDown = (e) => { + if (e.metaKey && e.key === "k") { + document.querySelector("#rtd-search-form input").focus(); + } else if (e.key === "Escape") { + toggleMenu({ force: false }); + } + if (e.metaKey && e.code === "Backslash") { + toggleColorMode(); + } +}; +document.addEventListener("keydown", handleKeyDown); diff --git a/docs/_static/js/toggle.js b/docs/_static/js/toggle.js index f46a3a6662..6ea2dd1f80 100644 --- a/docs/_static/js/toggle.js +++ b/docs/_static/js/toggle.js @@ -1,38 +1,47 @@ -document.addEventListener('DOMContentLoaded', function() { +function toggleColorMode() { + // Check localStorage for previous color scheme preference, assign the opposite + var newMode = localStorage.getItem(LS_COLOR_SCHEME) == DARK ? LIGHT : DARK; - function toggleCssMode(isDay) { - var mode = (isDay ? "Day" : "Night"); - localStorage.setItem("css-mode", mode); + // Update localStorage with new color scheme preference + localStorage.setItem(LS_COLOR_SCHEME, newMode); - var daysheet = $('link[href="_static/pygments.css"]')[0].sheet; - daysheet.disabled = !isDay; + // Update the root element with the new color scheme preference + document + .querySelector(":root") + .setAttribute("style", `--color-scheme: ${newMode}`); - var nightsheet = $('link[href="_static/css/dark.css"]')[0]; - if (!isDay && nightsheet === undefined) { - var element = document.createElement("link"); - element.setAttribute("rel", "stylesheet"); - element.setAttribute("type", "text/css"); - element.setAttribute("href", "_static/css/dark.css"); - document.getElementsByTagName("head")[0].appendChild(element); - return; - } - if (nightsheet !== undefined) { - nightsheet.sheet.disabled = isDay; - } - } - - var initial = localStorage.getItem("css-mode") != "Night"; - var checkbox = document.querySelector('input[name=mode]'); + // Update logo + document + .querySelector(`img.${SOLIDITY_LOGO_CLASS}`) + .setAttribute("src", newMode === LIGHT ? LIGHT_LOGO_PATH : DARK_LOGO_PATH); - toggleCssMode(initial); - checkbox.checked = initial; + // Update color mode toggle icon + document + .querySelector(`img.${COLOR_TOGGLE_ICON_CLASS}`) + .setAttribute("src", newMode === LIGHT ? MOON_ICON_PATH : SUN_ICON_PATH); - checkbox.addEventListener('change', function() { - document.documentElement.classList.add('transition'); - window.setTimeout(() => { - document.documentElement.classList.remove('transition'); - }, 1000) - toggleCssMode(this.checked); - }) + // Update hamburger menu icon color + document + .querySelector("button.mobile-menu-button img") + .setAttribute( + "src", + newMode === LIGHT ? LIGHT_HAMBURGER_PATH : DARK_HAMBURGER_PATH + ); +} -}); \ No newline at end of file +function toggleMenu(options = {}) { + const handleClassToggle = ({ classList }, className) => { + if (typeof options.force !== "undefined") { + classList.toggle(className, options.force); + } else { + classList.toggle(className); + } + }; + document + .querySelectorAll('[data-toggle="rst-versions"]') + .forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS)); + document + .querySelectorAll('[data-toggle="wy-nav-shift"]') + .forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS)); + handleClassToggle(document.querySelector(`.${WRAPPER_CLASS}`), "menu-open"); +} diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 39f71db63b..6ef5f786f0 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -13,23 +13,37 @@ L'interface binaire d'application de contrat (ABI) est le moyen standard d'inter de l'extérieur de la blockchain que pour l'interaction entre contrats. Les données sont codées en fonction de leur type, comme décrit dans cette spécification. L'encodage n'est pas autodécrit et nécessite donc un schéma pour être décodé. +<<<<<<< HEAD Nous supposons que les fonctions d'interface d'un contrat sont fortement typées, connues au moment de la compilation et statiques. Nous supposons que tous les contrats auront les définitions d'interface de tous les contrats qu'ils appellent disponibles au moment de la compilation. +======= +We assume that the interface functions of a contract are strongly typed, known at compilation time and static. +We assume that all contracts will have the interface definitions of any contracts they call available at compile-time. +>>>>>>> english/develop Cette spécification ne concerne pas les contrats dont l'interface est dynamique ou connue uniquement au moment de l'exécution. .. _abi_function_selector: -.. index:: selector +.. index:: ! selector; of a function Sélecteur de fonctions ================= +<<<<<<< HEAD Les quatre premiers octets des données d'appel d'une fonction spécifient la fonction à appeler. Il s'agit des premiers (gauche, ordre supérieur en big-endian) quatre octets du hachage Keccak-256 de la signature de la fonction. la fonction. La signature est définie comme l'expression canonique du prototype de base sans spécificateur d'emplacement de données, c'est-à-dire qu'il s'agit de l'expression canonique de la fonction. spécificateur d'emplacement de données, c'est-à-dire le nom de la fonction avec la liste des types de paramètres entre parenthèses. Les types de paramètres sont séparés par une simple virgule - aucun espace n'est utilisé. +======= +The first four bytes of the call data for a function call specifies the function to be called. It is the +first (left, high-order in big-endian) four bytes of the Keccak-256 hash of the signature of +the function. The signature is defined as the canonical expression of the basic prototype without data +location specifier, i.e. +the function name with the parenthesised list of parameter types. Parameter types are split by a single +comma — no spaces are used. +>>>>>>> english/develop .. note:: Le type de retour d'une fonction ne fait pas partie de cette signature. Dans @@ -134,8 +148,13 @@ Le codage est conçu pour avoir les propriétés suivantes, qui sont particuliè version précédente de l'ABI, le nombre de lectures était linéairement proportionnel au nombre total de paramètres dynamiques dans le pire des cas. dynamiques dans le pire des cas. +<<<<<<< HEAD 2. Les données d'une variable ou d'un élément de tableau ne sont pas entrelacées avec d'autres données et elles sont relocalisables, c'est-à-dire qu'elles n'utilisent que des "adresses" relatives. +======= +2. The data of a variable or an array element is not interleaved with other data and it is + relocatable, i.e. it only uses relative "addresses". +>>>>>>> english/develop Spécification formelle de l'encodage @@ -192,10 +211,15 @@ du type de ``X`` qui est - ``T[]`` où ``X`` a `k`` éléments (``k`` est supposé être de type ``uint256``) : - ``enc(X) = enc(k) enc([X[0], ..., X[k-1]])`` + ``enc(X) = enc(k) enc((X[0], ..., X[k-1]))`` +<<<<<<< HEAD c'est-à-dire qu'il est encodé comme s'il s'agissait d'un tableau de taille statique ``k``, préfixé par le le nombre d'éléments. +======= + i.e. it is encoded as if it were a tuple with ``k`` elements of the same type (resp. an array of static size ``k``), prefixed with + the number of elements. +>>>>>>> english/develop - ``bytes``, de longueur ``k`` (qui est supposé être de type ``uint256``) : @@ -253,8 +277,27 @@ Exemples } +<<<<<<< HEAD Ainsi, pour notre exemple ``Foo``, si nous voulions appeler ``baz`` avec les paramètres ``69`` et ``true``, nous passerions 68 octets au total, qui peuvent être décomposés en : +======= +Thus, for our ``Foo`` example, if we wanted to call ``bar`` with the argument ``["abc", "def"]``, we would pass 68 bytes total, broken down into: + +- ``0xfce353f6``: the Method ID. This is derived from the signature ``bar(bytes3[2])``. +- ``0x6162630000000000000000000000000000000000000000000000000000000000``: the first part of the first + parameter, a ``bytes3`` value ``"abc"`` (left-aligned). +- ``0x6465660000000000000000000000000000000000000000000000000000000000``: the second part of the first + parameter, a ``bytes3`` value ``"def"`` (left-aligned). + +In total: + +.. code-block:: none + + 0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000 + +If we wanted to call ``baz`` with the parameters ``69`` and +``true``, we would pass 68 bytes total, which can be broken down into: +>>>>>>> english/develop - ``0xcdcd77c0`` : l'ID de la méthode. Il s'agit des 4 premiers octets du hachage de Keccak de la forme la forme ASCII de la signature ``baz(uint32,bool)``. @@ -272,6 +315,7 @@ Au total : Elle renvoie un seul ``bool``. Si, par exemple, elle devait retourner ``false``, sa sortie serait le tableau d'octets unique ``0x000000000000000000000000000000000000000000000000``, un seul bool. +<<<<<<< HEAD Si nous voulions appeler ``bar`` avec l'argument ``["abc", "def"]``, nous passerions 68 octets au total, répartis en : - ``0xfce353f6`` : l'identifiant de la méthode. Celui-ci est dérivé de la signature ``bar(bytes3[2])``. @@ -288,6 +332,10 @@ Au total : Si nous voulions appeler ``sam`` avec les arguments ``"dave"``, ``true`` et ``[1,2,3]``, nous devrions passerait 292 octets au total, répartis comme suit : +======= +If we wanted to call ``sam`` with the arguments ``"dave"``, ``true`` and ``[1,2,3]``, we would +pass 292 bytes total, broken down into: +>>>>>>> english/develop - ``0xa5643bf2`` : l'identifiant de la méthode. Celui-ci est dérivé de la signature ``sam(bytes,bool,uint256[])``. Notez que ``uint`` est remplacé par sa représentation canonique ``uint256``. - ``0x0000000000000000000000000000000000000000000000000000000000000060`` : l'emplacement de la partie données du premier paramètre (type dynamique), mesuré en octets à partir du début du bloc d'arguments. Dans ce cas, ``0x60``. @@ -309,6 +357,7 @@ Au total : Utilisation des types dynamiques ==================== +<<<<<<< HEAD Un appel à une fonction dont la signature est ``f(uint,uint32[],bytes10,bytes)`` avec les valeurs suivantes ``(0x123, [0x456, 0x789], "1234567890", "Hello, world !")`` est codé de la manière suivante : @@ -317,6 +366,16 @@ Ensuite, nous encodons les parties de tête des quatre arguments. Pour les types ce sont directement les valeurs que nous voulons passer, alors que pour les types dynamiques ``uint32[]`` et ``bytes``, nous utilisons le décalage en octets par rapport au début de leur zone de données, mesuré à partir du début de l'encodage de la valeur (c'est-à-dire pas de l'encodage de la valeur). (c'est-à-dire sans compter les quatre premiers octets contenant le hachage de la signature de la fonction). Ces valeurs sont les suivantes +======= +A call to a function with the signature ``f(uint256,uint32[],bytes10,bytes)`` with values +``(0x123, [0x456, 0x789], "1234567890", "Hello, world!")`` is encoded in the following way: + +We take the first four bytes of ``keccak("f(uint256,uint32[],bytes10,bytes)")``, i.e. ``0x8be65246``. +Then we encode the head parts of all four arguments. For the static types ``uint256`` and ``bytes10``, +these are directly the values we want to pass, whereas for the dynamic types ``uint32[]`` and ``bytes``, +we use the offset in bytes to the start of their data area, measured from the start of the value +encoding (i.e. not counting the first four bytes containing the hash of the function signature). These are: +>>>>>>> english/develop - ``0x0000000000000000000000000000000000000000000000000000000000000123`` (``0x123`` padded to 32 bytes) - ``0x0000000000000000000000000000000000000000000000000000000000000080`` (décalage du début de la partie données du second paramètre, 4*32 octets, exactement la taille de la partie tête) @@ -349,8 +408,13 @@ Au total, le codage est le suivant (nouvelle ligne après le sélecteur de fonct 000000000000000000000000000000000000000000000000000000000000000d 48656c6c6f2c20776f726c642100000000000000000000000000000000000000 +<<<<<<< HEAD Appliquons le même principe pour encoder les données d'une fonction de signature ``g(uint[][],string[])`` avec les valeurs ``([1, 2], [3]], ["un", "deux", "trois"])`` mais commençons par les parties les plus atomiques de l'encodage : +======= +Let us apply the same principle to encode the data for a function with a signature ``g(uint256[][],string[])`` +with values ``([[1, 2], [3]], ["one", "two", "three"])`` but start from the most atomic parts of the encoding: +>>>>>>> english/develop D'abord, nous encodons la longueur et les données du premier tableau dynamique intégré ``[1, 2]`` du premier tableau racine ``[[1, 2], [3]]`` : @@ -417,8 +481,13 @@ Le décalage ``e`` pointe vers le début du contenu de la chaîne ``"trois"`` qu donc ``e = 0x00000000000000000000000000000000000000000000000000000000000000e0``. +<<<<<<< HEAD Notez que les encodages des éléments intégrés des tableaux racines ne sont pas dépendants les uns des autres et ont les mêmes encodages pour une fonction avec une signature ``g(string[],uint[][])``. +======= +Note that the encodings of the embedded elements of the root arrays are not dependent on each other +and have the same encodings for a function with a signature ``g(string[],uint256[][])``. +>>>>>>> english/develop Ensuite, nous encodons la longueur du premier tableau racine : @@ -504,6 +573,7 @@ recherche efficace et la lisibilité arbitraire en définissant des événements indexés, l'autre non - destinés à contenir la même valeur. .. _abi_errors: +.. index:: error, selector; of an error Erreurs ====== @@ -563,7 +633,11 @@ Une description de fonction est un objet JSON avec les champs : état de la blockchain `), ``view`` (:ref:`spécifié pour ne pas modifier l'état de la blockchain state `), `nonpayable`` (la fonction n'accepte pas les Ether - la valeur par défaut) et ``payable`` (la fonction accepte les Ether). +<<<<<<< HEAD Le constructeur et la fonction de repli n'ont jamais de ``name`` ou de ``outputs`'. La fonction de repli n'a pas non plus de ``inputs`'. +======= +Constructor, receive, and fallback never have ``name`` or ``outputs``. Receive and fallback do not have ``inputs`` either. +>>>>>>> english/develop .. note:: Envoyer un Ether non nul à une fonction non payante inversera la transaction. @@ -578,10 +652,17 @@ Une description d'événement est un objet JSON avec des champs assez similaires - ``name`` : le nom de l'événement. - ``inputs`` : un tableau d'objets, chacun d'entre eux contenant : +<<<<<<< HEAD * ``name`` : le nom du paramètre. * ``type`` : le type canonique du paramètre (plus bas). * ``components`` : utilisé pour les types de tuple (plus bas). * ``indexed`` : ``true`` si le champ fait partie des sujets du journal, ``false`` s'il fait partie du segment de données du journal. +======= + * ``name``: the name of the parameter. + * ``type``: the canonical type of the parameter (more below). + * ``components``: used for tuple types (more below). + * ``indexed``: ``true`` if the field is part of the log's topics, ``false`` if it is one of the log's data segments. +>>>>>>> english/develop - ``anonymous`` : ``true`` si l'événement a été déclaré comme ``anonymous`''. @@ -596,11 +677,19 @@ Les erreurs se présentent comme suit : * ``components`` : utilisé pour les types de tuple (plus bas). .. note:: +<<<<<<< HEAD Il peut y avoir plusieurs erreurs avec le même nom et même avec une signature identique signature identique dans le tableau JSON, par exemple si les erreurs proviennent de différents fichiers différents dans le contrat intelligent ou sont référencées à partir d'un autre contrat intelligent. Pour l'ABI, seul le nom de l'erreur elle-même est pertinent et non l'endroit où elle est définie. +======= + There can be multiple errors with the same name and even with identical signature + in the JSON array; for example, if the errors originate from different + files in the smart contract or are referenced from another smart contract. + For the ABI, only the name of the error itself is relevant and not where it is + defined. +>>>>>>> english/develop Par exemple, @@ -646,6 +735,7 @@ donnerait le JSON : Handling tuple types -------------------- +<<<<<<< HEAD Bien que les noms ne fassent intentionnellement pas partie de l'encodage ABI, il est tout à fait logique de les inclure dans le JSON pour pouvoir l'afficher à l'utilisateur final. La structure est imbriquée de la manière suivante : @@ -656,6 +746,18 @@ une séquence de ``[]`` et de ``[k]`` avec des entiers ``k``. Les composants du tuple sont ensuite stockés dans le membre ``components``, qui est de type tableau et a la même structure que l'objet de niveau supérieur, sauf que ``indexed`` n'y est pas autorisé. +======= +Despite the fact that names are intentionally not part of the ABI encoding, they do make a lot of sense to be included +in the JSON to enable displaying it to the end user. The structure is nested in the following way: + +An object with members ``name``, ``type`` and potentially ``components`` describes a typed variable. +The canonical type is determined until a tuple type is reached and the string description up +to that point is stored in ``type`` prefix with the word ``tuple``, i.e. it will be ``tuple`` followed by +a sequence of ``[]`` and ``[k]`` with +integers ``k``. The components of the tuple are then stored in the member ``components``, +which is of an array type and has the same structure as the top-level object except that +``indexed`` is not allowed there. +>>>>>>> english/develop A titre d'exemple, le code @@ -737,6 +839,7 @@ donnerait le JSON : Mode de codage strict ==================== +<<<<<<< HEAD Le mode d'encodage strict est le mode qui conduit exactement au même encodage que celui défini dans la spécification formelle ci-dessus. Cela signifie que les décalages doivent être aussi petits que possible tout en ne créant pas de chevauchements dans les zones de données. autorisés. @@ -744,6 +847,15 @@ autorisés. Habituellement, les décodeurs ABI sont écrits de manière simple en suivant simplement les pointeurs de décalage, mais certains décodeurs peuvent appliquer un mode strict. Le décodeur Solidity ABI n'applique pas actuellement le mode strict, mais l'encodeur crée toujours des données en mode strict. crée toujours les données en mode strict. +======= +Strict encoding mode is the mode that leads to exactly the same encoding as defined in the formal specification above. +This means that offsets have to be as small as possible while still not creating overlaps in the data areas, and thus no gaps are +allowed. + +Usually, ABI decoders are written in a straightforward way by just following offset pointers, but some decoders +might enforce strict mode. The Solidity ABI decoder currently does not enforce strict mode, but the encoder +always creates data in strict mode. +>>>>>>> english/develop Mode Packed non standard ======================== @@ -768,6 +880,7 @@ A titre d'exemple, l'encodage de ``int16(-1), bytes1(0x42), uint16(0x03), string Plus précisément : +<<<<<<< HEAD - Pendant l'encodage, tout est encodé sur place. Cela signifie qu'il n'y a pas de distinction entre la tête et la queue, comme dans l'encodage ABI, et la longueur d'un tableau n'est pas encodée. @@ -780,6 +893,20 @@ Plus précisément : - L'encodage de ``string`` ou ``bytes`` n'applique pas de remplissage à la fin sauf s'il s'agit d'une partie d'un tableau ou d'une structure (dans ce cas, il s'agit d'un multiple de 32 octets). 32 octets). +======= +- During the encoding, everything is encoded in-place. This means that there is + no distinction between head and tail, as in the ABI encoding, and the length + of an array is not encoded. +- The direct arguments of ``abi.encodePacked`` are encoded without padding, + as long as they are not arrays (or ``string`` or ``bytes``). +- The encoding of an array is the concatenation of the + encoding of its elements **with** padding. +- Dynamically-sized types like ``string``, ``bytes`` or ``uint[]`` are encoded + without their length field. +- The encoding of ``string`` or ``bytes`` does not apply padding at the end, + unless it is part of an array or struct (then it is padded to a multiple of + 32 bytes). +>>>>>>> english/develop En général, l'encodage est ambigu dès qu'il y a deux éléments de taille dynamique, à cause du champ de longueur manquant. @@ -804,9 +931,15 @@ pour faire précéder un sélecteur de fonction. Comme l'encodage est ambigu, il Codage des paramètres d'événements indexés ==================================== +<<<<<<< HEAD Les paramètres d'événements indexés qui ne sont pas des types de valeur, c'est-à-dire les tableaux et les stockés directement, mais un keccak256-hash d'un encodage est stocké. Ce codage est défini comme suit : +======= +Indexed event parameters that are not value types, i.e. arrays and structs are not +stored directly but instead a Keccak-256 hash of an encoding is stored. This encoding +is defined as follows: +>>>>>>> english/develop - l'encodage d'une valeur de type ``bytes`` et ``chaîne`'' est juste le contenu de la chaîne de caractères sans aucun padding ou préfixe de longueur. diff --git a/docs/analysing-compilation-output.rst b/docs/analysing-compilation-output.rst index 60fab659cf..cf21a0b4c2 100644 --- a/docs/analysing-compilation-output.rst +++ b/docs/analysing-compilation-output.rst @@ -11,7 +11,7 @@ visuel de l'assemblage avant et après un changement est souvent très instructi Considérons le contrat suivant (nommé, disons ``contract.sol``) : -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.5.0 <0.9.0; diff --git a/docs/assembly.rst b/docs/assembly.rst index deed255bfa..6dd531ca17 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -7,9 +7,15 @@ Assemblage en ligne .. index:: ! assembly, ! asm, ! evmasm +<<<<<<< HEAD Vous pouvez intercaler des instructions Solidity avec de l'assemblage en ligne dans un langage proche de celui de la machine virtuelle Ethereum. de celui de la machine virtuelle Ethereum. Cela vous donne un contrôle plus fin, ce qui est particulièrement utile lorsque vous améliorez le langage en écrivant des bibliothèques. +======= +You can interleave Solidity statements with inline assembly in a language close +to the one of the Ethereum Virtual Machine. This gives you more fine-grained control, +which is especially useful when you are enhancing the language by writing libraries. +>>>>>>> english/develop Le langage utilisé pour l'assemblage en ligne dans Solidity est appelé :ref:`Yul `. et il est documenté dans sa propre section. Cette section couvrira uniquement @@ -45,19 +51,19 @@ langage Solidity sans changer de compilateur. pragma solidity >=0.4.16 <0.9.0; library GetCode { - function at(address _addr) public view returns (bytes memory o_code) { + function at(address addr) public view returns (bytes memory code) { assembly { // retrieve the size of the code, this needs assembly - let size := extcodesize(_addr) + let size := extcodesize(addr) // allocate output byte array - this could also be done without assembly - // by using o_code = new bytes(size) - o_code := mload(0x40) + // by using code = new bytes(size) + code := mload(0x40) // new "memory end" including padding - mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) + mstore(0x40, add(code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) // store length in memory - mstore(o_code, size) + mstore(code, size) // actually retrieve the code, this needs assembly - extcodecopy(_addr, add(o_code, 0x20), 0, size) + extcodecopy(addr, add(code, 0x20), 0, size) } } } @@ -74,49 +80,49 @@ code efficace, par exemple : library VectorSum { // This function is less efficient because the optimizer currently fails to // remove the bounds checks in array access. - function sumSolidity(uint[] memory _data) public pure returns (uint sum) { - for (uint i = 0; i < _data.length; ++i) - sum += _data[i]; + function sumSolidity(uint[] memory data) public pure returns (uint sum) { + for (uint i = 0; i < data.length; ++i) + sum += data[i]; } // We know that we only access the array in bounds, so we can avoid the check. // 0x20 needs to be added to an array because the first slot contains the // array length. - function sumAsm(uint[] memory _data) public pure returns (uint sum) { - for (uint i = 0; i < _data.length; ++i) { + function sumAsm(uint[] memory data) public pure returns (uint sum) { + for (uint i = 0; i < data.length; ++i) { assembly { - sum := add(sum, mload(add(add(_data, 0x20), mul(i, 0x20)))) + sum := add(sum, mload(add(add(data, 0x20), mul(i, 0x20)))) } } } // Same as above, but accomplish the entire code within inline assembly. - function sumPureAsm(uint[] memory _data) public pure returns (uint sum) { + function sumPureAsm(uint[] memory data) public pure returns (uint sum) { assembly { // Load the length (first 32 bytes) - let len := mload(_data) + let len := mload(data) // Skip over the length field. // // Keep temporary variable so it can be incremented in place. // - // NOTE: incrementing _data would result in an unusable - // _data variable after this assembly block - let data := add(_data, 0x20) + // NOTE: incrementing data would result in an unusable + // data variable after this assembly block + let dataElementLocation := add(data, 0x20) // Iterate until the bound is not met. for - { let end := add(data, mul(len, 0x20)) } - lt(data, end) - { data := add(data, 0x20) } + { let end := add(dataElementLocation, mul(len, 0x20)) } + lt(dataElementLocation, end) + { dataElementLocation := add(dataElementLocation, 0x20) } { - sum := add(sum, mload(data)) + sum := add(sum, mload(dataElementLocation)) } } } } - +.. index:: selector; of a function Accès aux variables, fonctions et bibliothèques externes ----------------------------------------------------- @@ -126,6 +132,7 @@ Vous pouvez accéder aux variables Solidity et autres identifiants en utilisant Les variables locales de type valeur sont directement utilisables dans l'assemblage en ligne. Elles peuvent à la fois être lues et assignées. +<<<<<<< HEAD Les variables locales qui font référence à la mémoire sont évaluées à l'adresse de la variable en mémoire et non à la valeur elle-même. Ces variables peuvent également être assignées, mais notez qu'une assignation ne modifie que le pointeur et non les données. et qu'il est de votre responsabilité de respecter la gestion de la mémoire de Solidity. @@ -140,6 +147,22 @@ Pour les pointeurs de fonctions externes, l'adresse et le sélecteur de fonction accessible en utilisant ``x.address`` et ``x.selector``. Le sélecteur est constitué de quatre octets alignés à droite. Les deux valeurs peuvent être assignées. Par exemple : +======= +Local variables that refer to memory evaluate to the address of the variable in memory, not the value itself. +Such variables can also be assigned to, but note that an assignment will only change the pointer and not the data +and that it is your responsibility to respect Solidity's memory management. +See :ref:`Conventions in Solidity `. + +Similarly, local variables that refer to statically-sized calldata arrays or calldata structs +evaluate to the address of the variable in calldata, not the value itself. +The variable can also be assigned a new offset, but note that no validation is performed to ensure that +the variable will not point beyond ``calldatasize()``. + +For external function pointers the address and the function selector can be +accessed using ``x.address`` and ``x.selector``. +The selector consists of four right-aligned bytes. +Both values can be assigned to. For example: +>>>>>>> english/develop .. code-block:: solidity :force: @@ -205,9 +228,15 @@ Les variables locales de Solidity sont disponibles pour les affectations, par ex ``assembly { signextend(, x) }`` +<<<<<<< HEAD Depuis Solidity 0.6.0, le nom d'une variable d'assemblage en ligne ne peut pas suivre aucune déclaration visible dans la portée du bloc d'assemblage en ligne (y compris les déclarations de variables, de contrats et de fonctions). +======= +Since Solidity 0.6.0, the name of a inline assembly variable may not +shadow any declaration visible in the scope of the inline assembly block +(including variable, contract and function declarations). +>>>>>>> english/develop Depuis la version 0.7.0 de Solidity, les variables et les fonctions déclarées à l'intérieur du bloc d'assemblage en ligne ne peuvent pas contenir ``.``, mais l'utilisation de ``.`` est valide @@ -228,6 +257,7 @@ variables locales à l'assemblage lorsque la fin de leur bloc est atteinte. Conventions dans Solidity ----------------------- +<<<<<<< HEAD Contrairement à l'assemblage EVM, Solidity possède des types dont la taille est inférieure à 256 bits, par exemple uint24. Pour des raisons d'efficacité, la plupart des opérations arithmétiques ignorent le fait que les types peuvent @@ -245,6 +275,34 @@ auparavant et vous ne pouvez donc pas supposer que son contenu est de zéro octe Il n'existe pas de mécanisme intégré pour libérer la mémoire allouée. Voici un extrait d'assemblage que vous pouvez utiliser pour allouer de la mémoire qui suit le processus décrit ci-dessus. +======= +.. _assembly-typed-variables: + +Values of Typed Variables +========================= + +In contrast to EVM assembly, Solidity has types which are narrower than 256 bits, +e.g. ``uint24``. For efficiency, most arithmetic operations ignore the fact that +types can be shorter than 256 +bits, and the higher-order bits are cleaned when necessary, +i.e., shortly before they are written to memory or before comparisons are performed. +This means that if you access such a variable +from within inline assembly, you might have to manually clean the higher-order bits +first. + +.. _assembly-memory-management: + +Memory Management +================= + +Solidity manages memory in the following way. There is a "free memory pointer" +at position ``0x40`` in memory. If you want to allocate memory, use the memory +starting from where this pointer points at and update it. +There is no guarantee that the memory has not been used before and thus +you cannot assume that its contents are zero bytes. +There is no built-in mechanism to release or free allocated memory. +Here is an assembly snippet you can use for allocating memory that follows the process outlined above: +>>>>>>> english/develop .. code-block:: yul @@ -265,7 +323,111 @@ Les tableaux de mémoire multidimensionnels sont des pointeurs vers des tableaux La longueur d'un tableau dynamique est stockée dans le premier emplacement du tableau et suivie par les éléments du tableau. .. warning:: +<<<<<<< HEAD Les tableaux de mémoire de taille statique n'ont pas de champ de longueur, mais celui-ci pourrait être ajouté ultérieurement pour permettre une meilleure convertibilité entre les tableaux de taille statique et dynamique. Pour permettre une meilleure convertibilité entre les tableaux de taille statique et dynamique. Donc ne vous y fiez pas. +======= + Statically-sized memory arrays do not have a length field, but it might be added later + to allow better convertibility between statically and dynamically-sized arrays; so, + do not rely on this. + +Memory Safety +============= + +Without the use of inline assembly, the compiler can rely on memory to remain in a well-defined +state at all times. This is especially relevant for :ref:`the new code generation pipeline via Yul IR `: +this code generation path can move local variables from stack to memory to avoid stack-too-deep errors and +perform additional memory optimizations, if it can rely on certain assumptions about memory use. + +While we recommend to always respect Solidity's memory model, inline assembly allows you to use memory +in an incompatible way. Therefore, moving stack variables to memory and additional memory optimizations are, +by default, globally disabled in the presence of any inline assembly block that contains a memory operation +or assigns to Solidity variables in memory. + +However, you can specifically annotate an assembly block to indicate that it in fact respects Solidity's memory +model as follows: + +.. code-block:: solidity + + assembly ("memory-safe") { + ... + } + +In particular, a memory-safe assembly block may only access the following memory ranges: + +- Memory allocated by yourself using a mechanism like the ``allocate`` function described above. +- Memory allocated by Solidity, e.g. memory within the bounds of a memory array you reference. +- The scratch space between memory offset 0 and 64 mentioned above. +- Temporary memory that is located *after* the value of the free memory pointer at the beginning of the assembly block, + i.e. memory that is "allocated" at the free memory pointer without updating the free memory pointer. + +Furthermore, if the assembly block assigns to Solidity variables in memory, you need to assure that accesses to +the Solidity variables only access these memory ranges. + +Since this is mainly about the optimizer, these restrictions still need to be followed, even if the assembly block +reverts or terminates. As an example, the following assembly snippet is not memory safe, because the value of +``returndatasize()`` may exceed the 64 byte scratch space: + +.. code-block:: solidity + + assembly { + returndatacopy(0, 0, returndatasize()) + revert(0, returndatasize()) + } + +On the other hand, the following code *is* memory safe, because memory beyond the location pointed to by the +free memory pointer can safely be used as temporary scratch space: + +.. code-block:: solidity + + assembly ("memory-safe") { + let p := mload(0x40) + returndatacopy(p, 0, returndatasize()) + revert(p, returndatasize()) + } + +Note that you do not need to update the free memory pointer if there is no following allocation, +but you can only use memory starting from the current offset given by the free memory pointer. + +If the memory operations use a length of zero, it is also fine to just use any offset (not only if it falls into the scratch space): + +.. code-block:: solidity + + assembly ("memory-safe") { + revert(0, 0) + } + +Note that not only memory operations in inline assembly itself can be memory-unsafe, but also assignments to +Solidity variables of reference type in memory. For example the following is not memory-safe: + +.. code-block:: solidity + + bytes memory x; + assembly { + x := 0x40 + } + x[0x20] = 0x42; + +Inline assembly that neither involves any operations that access memory nor assigns to any Solidity variables +in memory is automatically considered memory-safe and does not need to be annotated. + +.. warning:: + It is your responsibility to make sure that the assembly actually satisfies the memory model. If you annotate + an assembly block as memory-safe, but violate one of the memory assumptions, this **will** lead to incorrect and + undefined behavior that cannot easily be discovered by testing. + +In case you are developing a library that is meant to be compatible across multiple versions +of Solidity, you can use a special comment to annotate an assembly block as memory-safe: + +.. code-block:: solidity + + /// @solidity memory-safe-assembly + assembly { + ... + } + +Note that we will disallow the annotation via comment in a future breaking release; so, if you are not concerned with +backward-compatibility with older compiler versions, prefer using the dialect string. +>>>>>>> english/develop diff --git a/docs/brand-guide.rst b/docs/brand-guide.rst index 8437607119..cba331c0a6 100644 --- a/docs/brand-guide.rst +++ b/docs/brand-guide.rst @@ -66,7 +66,7 @@ Lorsque vous utilisez le logo Solidity, veuillez respecter les directives relati Directives relatives au logo Solidity ======================== -.. image:: logo.svg +.. image:: solidity_logo.svg :width: 256 *(Cliquez avec le bouton droit de la souris sur le logo pour le télécharger.)* diff --git a/docs/bugs.json b/docs/bugs.json index 0b72c05c7d..c853f95edd 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -1,4 +1,120 @@ [ + { + "uid": "SOL-2023-3", + "name": "VerbatimInvalidDeduplication", + "summary": "All ``verbatim`` blocks are considered identical by deduplicator and can incorrectly be unified when surrounded by identical opcodes.", + "description": "The block deduplicator is a step of the opcode-based optimizer which identifies equivalent assembly blocks and merges them into a single one. However, when blocks contained ``verbatim``, their comparison was performed incorrectly, leading to the collapse of assembly blocks which are identical except for the contents of the ``verbatim`` items. Since ``verbatim`` is only available in Yul, compilation of Solidity sources is not affected.", + "link": "https://blog.soliditylang.org/2023/11/08/verbatim-invalid-deduplication-bug/", + "introduced": "0.8.5", + "fixed": "0.8.23", + "severity": "low" + }, + { + "uid": "SOL-2023-2", + "name": "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "summary": "Optimizer sequences containing FullInliner do not preserve the evaluation order of arguments of inlined function calls in code that is not in expression-split form.", + "description": "Function call arguments in Yul are evaluated right to left. This order matters when the argument expressions have side-effects, and changing it may change contract behavior. FullInliner is an optimizer step that can replace a function call with the body of that function. The transformation involves assigning argument expressions to temporary variables, which imposes an explicit evaluation order. FullInliner was written with the assumption that this order does not necessarily have to match usual argument evaluation order because the argument expressions have no side-effects. In most circumstances this assumption is true because the default optimization step sequence contains the ExpressionSplitter step. ExpressionSplitter ensures that the code is in *expression-split form*, which means that function calls cannot appear nested inside expressions, and all function call arguments have to be variables. The assumption is, however, not guaranteed to be true in general. Version 0.6.7 introduced a setting allowing users to specify an arbitrary optimization step sequence, making it possible for the FullInliner to actually encounter argument expressions with side-effects, which can result in behavior differences between optimized and unoptimized bytecode. Contracts compiled without optimization or with the default optimization sequence are not affected. To trigger the bug the user has to explicitly choose compiler settings that contain a sequence with FullInliner step not preceded by ExpressionSplitter.", + "link": "https://blog.soliditylang.org/2023/07/19/full-inliner-non-expression-split-argument-evaluation-order-bug/", + "introduced": "0.6.7", + "fixed": "0.8.21", + "severity": "low", + "conditions": { + "yulOptimizer": true + } + }, + { + "uid": "SOL-2023-1", + "name": "MissingSideEffectsOnSelectorAccess", + "summary": "Accessing the ``.selector`` member on complex expressions leaves the expression unevaluated in the legacy code generation.", + "description": "When accessing the ``.selector`` member on an expression with side-effects, like an assignment, a function call or a conditional, the expression would not be evaluated in the legacy code generation. This would happen in expressions where the functions used in the expression were all known at compilation time, regardless of whether the whole expression could be evaluated at compilation time or not. Note that the code generated by the IR pipeline was unaffected and would behave as expected.", + "link": "https://blog.soliditylang.org/2023/07/19/missing-side-effects-on-selector-access-bug/", + "introduced": "0.6.2", + "fixed": "0.8.21", + "severity": "low", + "conditions": { + "viaIR": false + } + }, + { + "uid": "SOL-2022-7", + "name": "StorageWriteRemovalBeforeConditionalTermination", + "summary": "Calling functions that conditionally terminate the external EVM call using the assembly statements ``return(...)`` or ``stop()`` may result in incorrect removals of prior storage writes.", + "description": "A call to a Yul function that conditionally terminates the external EVM call could result in prior storage writes being incorrectly removed by the Yul optimizer. This used to happen in cases in which it would have been valid to remove the store, if the Yul function in question never actually terminated the external call, and the control flow always returned back to the caller instead. Conditional termination within the same Yul block instead of within a called function was not affected. In Solidity with optimized via-IR code generation, any storage write before a function conditionally calling ``return(...)`` or ``stop()`` in inline assembly, may have been incorrectly removed, whenever it would have been valid to remove the write without the ``return(...)`` or ``stop()``. In optimized legacy code generation, only inline assembly that did not refer to any Solidity variables and that involved conditionally-terminating user-defined assembly functions could be affected.", + "link": "https://blog.soliditylang.org/2022/09/08/storage-write-removal-before-conditional-termination/", + "introduced": "0.8.13", + "fixed": "0.8.17", + "severity": "medium/high", + "conditions": { + "yulOptimizer": true + } + }, + { + "uid": "SOL-2022-6", + "name": "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "summary": "ABI-encoding a tuple with a statically-sized calldata array in the last component would corrupt 32 leading bytes of its first dynamically encoded component.", + "description": "When ABI-encoding a statically-sized calldata array, the compiler always pads the data area to a multiple of 32-bytes and ensures that the padding bytes are zeroed. In some cases, this cleanup used to be performed by always writing exactly 32 bytes, regardless of how many needed to be zeroed. This was done with the assumption that the data that would eventually occupy the area past the end of the array had not yet been written, because the encoder processes tuple components in the order they were given. While this assumption is mostly true, there is an important corner case: dynamically encoded tuple components are stored separately from the statically-sized ones in an area called the *tail* of the encoding and the tail immediately follows the *head*, which is where the statically-sized components are placed. The aforementioned cleanup, if performed for the last component of the head would cross into the tail and overwrite up to 32 bytes of the first component stored there with zeros. The only array type for which the cleanup could actually result in an overwrite were arrays with ``uint256`` or ``bytes32`` as the base element type and in this case the size of the corrupted area was always exactly 32 bytes. The problem affected tuples at any nesting level. This included also structs, which are encoded as tuples in the ABI. Note also that lists of parameters and return values of functions, events and errors are encoded as tuples.", + "link": "https://blog.soliditylang.org/2022/08/08/calldata-tuple-reencoding-head-overflow-bug/", + "introduced": "0.5.8", + "fixed": "0.8.16", + "severity": "medium", + "conditions": { + "ABIEncoderV2": true + } + }, + { + "uid": "SOL-2022-5", + "name": "DirtyBytesArrayToStorage", + "summary": "Copying ``bytes`` arrays from memory or calldata to storage may result in dirty storage values.", + "description": "Copying ``bytes`` arrays from memory or calldata to storage is done in chunks of 32 bytes even if the length is not a multiple of 32. Thereby, extra bytes past the end of the array may be copied from calldata or memory to storage. These dirty bytes may then become observable after a ``.push()`` without arguments to the bytes array in storage, i.e. such a push will not result in a zero value at the end of the array as expected. This bug only affects the legacy code generation pipeline, the new code generation pipeline via IR is not affected.", + "link": "https://blog.soliditylang.org/2022/06/15/dirty-bytes-array-to-storage-bug/", + "introduced": "0.0.1", + "fixed": "0.8.15", + "severity": "low" + }, + { + "uid": "SOL-2022-4", + "name": "InlineAssemblyMemorySideEffects", + "summary": "The Yul optimizer may incorrectly remove memory writes from inline assembly blocks, that do not access solidity variables.", + "description": "The Yul optimizer considers all memory writes in the outermost Yul block that are never read from as unused and removes them. This is valid when that Yul block is the entire Yul program, which is always the case for the Yul code generated by the new via-IR pipeline. Inline assembly blocks are never optimized in isolation when using that pipeline. Instead they are optimized as a part of the whole Yul input. However, the legacy code generation pipeline (which is still the default) runs the Yul optimizer individually on an inline assembly block if the block does not refer to any local variables defined in the surrounding Solidity code. Consequently, memory writes in such inline assembly blocks are removed as well, if the written memory is never read from in the same assembly block, even if the written memory is accessed later, for example by a subsequent inline assembly block.", + "link": "https://blog.soliditylang.org/2022/06/15/inline-assembly-memory-side-effects-bug/", + "introduced": "0.8.13", + "fixed": "0.8.15", + "severity": "medium", + "conditions": { + "yulOptimizer": true + } + }, + { + "uid": "SOL-2022-3", + "name": "DataLocationChangeInInternalOverride", + "summary": "It was possible to change the data location of the parameters or return variables from ``calldata`` to ``memory`` and vice-versa while overriding internal and public functions. This caused invalid code to be generated when calling such a function internally through virtual function calls.", + "description": "When calling external functions, it is irrelevant if the data location of the parameters is ``calldata`` or ``memory``, the encoding of the data does not change. Because of that, changing the data location when overriding external functions is allowed. The compiler incorrectly also allowed a change in the data location for overriding public and internal functions. Since public functions can be called internally as well as externally, this causes invalid code to be generated when such an incorrectly overridden function is called internally through the base contract. The caller provides a memory pointer, but the called function interprets it as a calldata pointer or vice-versa.", + "link": "https://blog.soliditylang.org/2022/05/17/data-location-inheritance-bug/", + "introduced": "0.6.9", + "fixed": "0.8.14", + "severity": "very low" + }, + { + "uid": "SOL-2022-2", + "name": "NestedCalldataArrayAbiReencodingSizeValidation", + "summary": "ABI-reencoding of nested dynamic calldata arrays did not always perform proper size checks against the size of calldata and could read beyond ``calldatasize()``.", + "description": "Calldata validation for nested dynamic types is deferred until the first access to the nested values. Such an access may for example be a copy to memory or an index or member access to the outer type. While in most such accesses calldata validation correctly checks that the data area of the nested array is completely contained in the passed calldata (i.e. in the range [0, calldatasize()]), this check may not be performed, when ABI encoding such nested types again directly from calldata. For instance, this can happen, if a value in calldata with a nested dynamic array is passed to an external call, used in ``abi.encode`` or emitted as event. In such cases, if the data area of the nested array extends beyond ``calldatasize()``, ABI encoding it did not revert, but continued reading values from beyond ``calldatasize()`` (i.e. zero values).", + "link": "https://blog.soliditylang.org/2022/05/17/calldata-reencode-size-check-bug/", + "introduced": "0.5.8", + "fixed": "0.8.14", + "severity": "very low" + }, + { + "uid": "SOL-2022-1", + "name": "AbiEncodeCallLiteralAsFixedBytesBug", + "summary": "Literals used for a fixed length bytes parameter in ``abi.encodeCall`` were encoded incorrectly.", + "description": "For the encoding, the compiler only considered the types of the expressions in the second argument of ``abi.encodeCall`` itself, but not the parameter types of the function given as first argument. In almost all cases the abi encoding of the type of the expression matches the abi encoding of the parameter type of the given function. This is because the type checker ensures the expression is implicitly convertible to the respective parameter type. However this is not true for number literals used for fixed bytes types shorter than 32 bytes, nor for string literals used for any fixed bytes type. Number literals were encoded as numbers instead of being shifted to become left-aligned. String literals were encoded as dynamically sized memory strings instead of being converted to a left-aligned bytes value.", + "link": "https://blog.soliditylang.org/2022/03/16/encodecall-bug/", + "introduced": "0.8.11", + "fixed": "0.8.13", + "severity": "very low" + + }, { "uid": "SOL-2021-4", "name": "UserDefinedValueTypesBug", @@ -8,7 +124,6 @@ "introduced": "0.8.8", "fixed": "0.8.9", "severity": "very low" - }, { "uid": "SOL-2021-3", diff --git a/docs/bugs.rst b/docs/bugs.rst index 9b9005dc39..f37f4a9011 100644 --- a/docs/bugs.rst +++ b/docs/bugs.rst @@ -66,6 +66,7 @@ conditions ou plus. Si aucune condition n'est donnée, on suppose que le bogue est présent. check +<<<<<<< HEAD Ce champ contient différentes vérifications qui indiquent si le contrat intelligent contient ou non le bogue. Le premier type de vérification est constitué d'expressions régulières Javascript qui doivent être comparées au code source ("source-regex") @@ -78,6 +79,20 @@ check est une expression `JsonPath `_. Si au moins un chemin de l'AST Solidity correspond à la requête, le bogue est probablement présent. +======= + This field contains different checks that report whether the smart contract + contains the bug or not. The first type of check are JavaScript regular + expressions that are to be matched against the source code ("source-regex") + if the bug is present. If there is no match, then the bug is very likely + not present. If there is a match, the bug might be present. For improved + accuracy, the checks should be applied to the source code after stripping + comments. + The second type of check are patterns to be checked on the compact AST of + the Solidity program ("ast-compact-json-path"). The specified search query + is a `JsonPath `_ expression. + If at least one path of the Solidity AST matches the query, the bug is + likely present. +>>>>>>> english/develop .. literalinclude:: bugs.json :language: js diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 608ba3dfda..156b846d01 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1,6 +1,7 @@ { "0.1.0": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -22,6 +23,7 @@ }, "0.1.1": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -43,6 +45,7 @@ }, "0.1.2": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -64,6 +67,7 @@ }, "0.1.3": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -85,6 +89,7 @@ }, "0.1.4": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -107,6 +112,7 @@ }, "0.1.5": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -129,6 +135,7 @@ }, "0.1.6": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -153,6 +160,7 @@ }, "0.1.7": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -177,6 +185,7 @@ }, "0.2.0": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -202,6 +211,7 @@ }, "0.2.1": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -227,6 +237,7 @@ }, "0.2.2": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -252,6 +263,7 @@ }, "0.3.0": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -279,6 +291,7 @@ }, "0.3.1": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -305,6 +318,7 @@ }, "0.3.2": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -331,6 +345,7 @@ }, "0.3.3": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -356,6 +371,7 @@ }, "0.3.4": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -381,6 +397,7 @@ }, "0.3.5": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -406,6 +423,7 @@ }, "0.3.6": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -429,6 +447,7 @@ }, "0.4.0": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -452,6 +471,7 @@ }, "0.4.1": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -475,6 +495,7 @@ }, "0.4.10": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -497,6 +518,7 @@ }, "0.4.11": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -518,6 +540,7 @@ }, "0.4.12": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -538,6 +561,7 @@ }, "0.4.13": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -558,6 +582,7 @@ }, "0.4.14": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -577,6 +602,7 @@ }, "0.4.15": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -595,6 +621,7 @@ }, "0.4.16": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -616,6 +643,7 @@ }, "0.4.17": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -638,6 +666,7 @@ }, "0.4.18": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -659,6 +688,7 @@ }, "0.4.19": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -681,6 +711,7 @@ }, "0.4.2": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -703,6 +734,7 @@ }, "0.4.20": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -725,6 +757,7 @@ }, "0.4.21": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -747,6 +780,7 @@ }, "0.4.22": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -769,6 +803,7 @@ }, "0.4.23": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -790,6 +825,7 @@ }, "0.4.24": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -811,6 +847,7 @@ }, "0.4.25": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -830,6 +867,7 @@ }, "0.4.26": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -846,6 +884,7 @@ }, "0.4.3": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -867,6 +906,7 @@ }, "0.4.4": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -887,6 +927,7 @@ }, "0.4.5": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -910,6 +951,7 @@ }, "0.4.6": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -932,6 +974,7 @@ }, "0.4.7": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -954,6 +997,7 @@ }, "0.4.8": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -976,6 +1020,7 @@ }, "0.4.9": { "bugs": [ + "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", "DynamicArrayCleanup", @@ -998,6 +1043,7 @@ }, "0.5.0": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1017,6 +1063,7 @@ }, "0.5.1": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1036,6 +1083,9 @@ }, "0.5.10": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1051,6 +1101,9 @@ }, "0.5.11": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1065,6 +1118,9 @@ }, "0.5.12": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1079,6 +1135,9 @@ }, "0.5.13": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1093,6 +1152,9 @@ }, "0.5.14": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1109,6 +1171,9 @@ }, "0.5.15": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1124,6 +1189,9 @@ }, "0.5.16": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1138,6 +1206,9 @@ }, "0.5.17": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1151,6 +1222,7 @@ }, "0.5.2": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1170,6 +1242,7 @@ }, "0.5.3": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1189,6 +1262,7 @@ }, "0.5.4": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1208,6 +1282,7 @@ }, "0.5.5": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1229,6 +1304,7 @@ }, "0.5.6": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1250,6 +1326,7 @@ }, "0.5.7": { "bugs": [ + "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1269,6 +1346,9 @@ }, "0.5.8": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1287,6 +1367,9 @@ }, "0.5.9": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1304,6 +1387,9 @@ }, "0.6.0": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1319,6 +1405,9 @@ }, "0.6.1": { "bugs": [ + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1333,6 +1422,12 @@ }, "0.6.10": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1343,6 +1438,12 @@ }, "0.6.11": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1353,6 +1454,12 @@ }, "0.6.12": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1363,6 +1470,10 @@ }, "0.6.2": { "bugs": [ + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1377,6 +1488,10 @@ }, "0.6.3": { "bugs": [ + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1391,6 +1506,10 @@ }, "0.6.4": { "bugs": [ + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", "EmptyByteArrayCopy", @@ -1405,6 +1524,10 @@ }, "0.6.5": { "bugs": [ + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1419,6 +1542,10 @@ }, "0.6.6": { "bugs": [ + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1432,6 +1559,11 @@ }, "0.6.7": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1445,6 +1577,11 @@ }, "0.6.8": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1455,6 +1592,12 @@ }, "0.6.9": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1466,6 +1609,12 @@ }, "0.7.0": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1476,6 +1625,12 @@ }, "0.7.1": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1487,6 +1642,12 @@ }, "0.7.2": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1497,6 +1658,12 @@ }, "0.7.3": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1506,6 +1673,12 @@ }, "0.7.4": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching" @@ -1514,6 +1687,12 @@ }, "0.7.5": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching" @@ -1522,6 +1701,12 @@ }, "0.7.6": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching" @@ -1530,6 +1715,12 @@ }, "0.8.0": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching" @@ -1538,6 +1729,12 @@ }, "0.8.1": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching" @@ -1545,23 +1742,162 @@ "released": "2021-01-27" }, "0.8.10": { - "bugs": [], + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation" + ], "released": "2021-11-09" }, "0.8.11": { - "bugs": [], + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", + "AbiEncodeCallLiteralAsFixedBytesBug" + ], "released": "2021-12-20" }, + "0.8.12": { + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", + "AbiEncodeCallLiteralAsFixedBytesBug" + ], + "released": "2022-02-16" + }, + "0.8.13": { + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "StorageWriteRemovalBeforeConditionalTermination", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "InlineAssemblyMemorySideEffects", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation" + ], + "released": "2022-03-16" + }, + "0.8.14": { + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "StorageWriteRemovalBeforeConditionalTermination", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "InlineAssemblyMemorySideEffects" + ], + "released": "2022-05-17" + }, + "0.8.15": { + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "StorageWriteRemovalBeforeConditionalTermination", + "AbiReencodingHeadOverflowWithStaticArrayCleanup" + ], + "released": "2022-06-15" + }, + "0.8.16": { + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "StorageWriteRemovalBeforeConditionalTermination" + ], + "released": "2022-08-08" + }, + "0.8.17": { + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess" + ], + "released": "2022-09-08" + }, + "0.8.18": { + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess" + ], + "released": "2023-02-01" + }, + "0.8.19": { + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess" + ], + "released": "2023-02-22" + }, "0.8.2": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching" ], "released": "2021-03-02" }, + "0.8.20": { + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess" + ], + "released": "2023-05-10" + }, + "0.8.21": { + "bugs": [ + "VerbatimInvalidDeduplication" + ], + "released": "2023-07-19" + }, + "0.8.22": { + "bugs": [ + "VerbatimInvalidDeduplication" + ], + "released": "2023-10-25" + }, + "0.8.23": { + "bugs": [], + "released": "2023-11-08" + }, + "0.8.24": { + "bugs": [], + "released": "2024-01-25" + }, "0.8.3": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory" ], @@ -1569,37 +1905,79 @@ }, "0.8.4": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables" ], "released": "2021-04-21" }, "0.8.5": { "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables" ], "released": "2021-06-10" }, "0.8.6": { "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables" ], "released": "2021-06-22" }, "0.8.7": { "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables" ], "released": "2021-08-11" }, "0.8.8": { "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "UserDefinedValueTypesBug", "SignedImmutables" ], "released": "2021-09-27" }, "0.8.9": { - "bugs": [], + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation" + ], "released": "2021-09-29" } } \ No newline at end of file diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index 7f2c1bcbcb..15194abb00 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -2,13 +2,12 @@ Aide-mémoire ********** -.. index:: precedence - -.. _order: +.. index:: operator;precedence Ordre de Préséance des Opérateurs ================================ +<<<<<<< HEAD Voici l'ordre de préséance des opérateurs, classés par ordre d'évaluation. +--------------+-------------------------------------+--------------------------------------------+ @@ -72,6 +71,14 @@ Voici l'ordre de préséance des opérateurs, classés par ordre d'évaluation. Variables Globales ================ +======= +.. include:: types/operator-precedence-table.rst + +.. index:: abi;decode, abi;encode, abi;encodePacked, abi;encodeWithSelector, abi;encodeCall, abi;encodeWithSignature + +ABI Encoding and Decoding Functions +=================================== +>>>>>>> english/develop - ``abi.decode(bytes memory encodedData, (...)) returns (...)``: :ref:`ABI `-décode les données fournies. Les types sont donnés entre parenthèses comme deuxième argument. @@ -85,6 +92,7 @@ Variables Globales tuple. Effectue une vérification complète des types, en s'assurant que les types correspondent à la signature de la fonction. Le résultat est égal à ``abi.encodeWithSelector(functionPointer.selector, (...))`` - ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent +<<<<<<< HEAD à ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)`` - ``bytes.concat(...) returns (bytes memory)``: :ref:`Concatène un nombre variable d'arguments d'arguments dans un tableau d'un octet` @@ -164,6 +172,115 @@ Variables Globales ``sha3`` comme alias pour ``keccak256``. .. note:: Dans la version 0.7.0, l'alias ``now`` (pour ``block.timestamp``) a été supprimé. +======= + to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`` + +.. index:: bytes;concat, string;concat + +Members of ``bytes`` and ``string`` +==================================== + +- ``bytes.concat(...) returns (bytes memory)``: :ref:`Concatenates variable number of + arguments to one byte array` + +- ``string.concat(...) returns (string memory)``: :ref:`Concatenates variable number of + arguments to one string array` + +.. index:: address;balance, address;codehash, address;send, address;code, address;transfer + +Members of ``address`` +====================== + +- ``
.balance`` (``uint256``): balance of the :ref:`address` in Wei +- ``
.code`` (``bytes memory``): code at the :ref:`address` (can be empty) +- ``
.codehash`` (``bytes32``): the codehash of the :ref:`address` +- ``
.call(bytes memory) returns (bool, bytes memory)``: issue low-level ``CALL`` with the given payload, + returns success condition and return data +- ``
.delegatecall(bytes memory) returns (bool, bytes memory)``: issue low-level ``DELEGATECALL`` with the given payload, + returns success condition and return data +- ``
.staticcall(bytes memory) returns (bool, bytes memory)``: issue low-level ``STATICCALL`` with the given payload, + returns success condition and return data +- ``
.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`, + returns ``false`` on failure +- ``
.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure + +.. index:: blockhash, blobhash, block, block;basefee, block;blobbasefee, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp +.. index:: gasleft, msg;data, msg;sender, msg;sig, msg;value, tx;gasprice, tx;origin + +Block and Transaction Properties +================================ + +- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks +- ``blobhash(uint index) returns (bytes32)``: versioned hash of the ``index``-th blob associated with the current transaction. + A versioned hash consists of a single byte representing the version (currently ``0x01``), followed by the last 31 bytes + of the SHA256 hash of the KZG commitment (`EIP-4844 `_). +- ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 `_ and `EIP-1559 `_) +- ``block.blobbasefee`` (``uint``): current block's blob base fee (`EIP-7516 `_ and `EIP-4844 `_) +- ``block.chainid`` (``uint``): current chain id +- ``block.coinbase`` (``address payable``): current block miner's address +- ``block.difficulty`` (``uint``): current block difficulty (``EVM < Paris``). For other EVM versions it behaves as a deprecated alias for ``block.prevrandao`` that will be removed in the next breaking release +- ``block.gaslimit`` (``uint``): current block gaslimit +- ``block.number`` (``uint``): current block number +- ``block.prevrandao`` (``uint``): random number provided by the beacon chain (``EVM >= Paris``) (see `EIP-4399 `_ ) +- ``block.timestamp`` (``uint``): current block timestamp in seconds since Unix epoch +- ``gasleft() returns (uint256)``: remaining gas +- ``msg.data`` (``bytes``): complete calldata +- ``msg.sender`` (``address``): sender of the message (current call) +- ``msg.sig`` (``bytes4``): first four bytes of the calldata (i.e. function identifier) +- ``msg.value`` (``uint``): number of wei sent with the message +- ``tx.gasprice`` (``uint``): gas price of the transaction +- ``tx.origin`` (``address``): sender of the transaction (full call chain) + +.. index:: assert, require, revert + +Validations and Assertions +========================== + +- ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error) +- ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use + for malformed input or error in external component) +- ``require(bool condition, string memory message)``: abort execution and revert state changes if + condition is ``false`` (use for malformed input or error in external component). Also provide error message. +- ``revert()``: abort execution and revert state changes +- ``revert(string memory message)``: abort execution and revert state changes providing an explanatory string + +.. index:: cryptography, keccak256, sha256, ripemd160, ecrecover, addmod, mulmod + +Mathematical and Cryptographic Functions +======================================== + +- ``keccak256(bytes memory) returns (bytes32)``: compute the Keccak-256 hash of the input +- ``sha256(bytes memory) returns (bytes32)``: compute the SHA-256 hash of the input +- ``ripemd160(bytes memory) returns (bytes20)``: compute the RIPEMD-160 hash of the input +- ``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``: recover address associated with + the public key from elliptic curve signature, return zero on error +- ``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``. Assert that ``k != 0`` starting from version 0.5.0. +- ``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``. Assert that ``k != 0`` starting from version 0.5.0. + +.. index:: this, super, selfdestruct + +Contract-related +================ + +- ``this`` (current contract's type): the current contract, explicitly convertible to ``address`` or ``address payable`` +- ``super``: a contract one level higher in the inheritance hierarchy +- ``selfdestruct(address payable recipient)``: destroy the current contract, sending its funds to the given address + +.. index:: type;name, type;creationCode, type;runtimeCode, type;interfaceId, type;min, type;max + +Type Information +================ + +- ``type(C).name`` (``string``): the name of the contract +- ``type(C).creationCode`` (``bytes memory``): creation bytecode of the given contract, see :ref:`Type Information`. +- ``type(C).runtimeCode`` (``bytes memory``): runtime bytecode of the given contract, see :ref:`Type Information`. +- ``type(I).interfaceId`` (``bytes4``): value containing the EIP-165 interface identifier of the given interface, see :ref:`Type Information`. +- ``type(T).min`` (``T``): the minimum value representable by the integer type ``T``, see :ref:`Type Information`. +- ``type(T).max`` (``T``): the maximum value representable by the integer type ``T``, see :ref:`Type Information`. + +>>>>>>> english/develop .. index:: visibility, public, private, extern, intern @@ -188,6 +305,7 @@ Spécification de la Visibilité des Fonctions Modificateurs ========= +<<<<<<< HEAD - ``pure`` pour les fonctions : Interdit la modification ou l'accès à l'état. - ``view`` pour les fonctions : Interdit la modification de l'état. - ``payable`` pour les fonctions : Leur permet de recevoir de l'Ether en même temps qu'un appel. @@ -211,3 +329,17 @@ Ces mots-clés sont réservés dans Solidity. Ils pourraient faire partie de la ``mutable``, ``null``, ``of``, ``partial``, ``promise``, ``reference``, ``relocatable``, ``sealed``, ``sizeof``, ``static``, ``supports``, ``switch``, ``typedef``, ``typeof``, ``var``. +======= +- ``pure`` for functions: Disallows modification or access of state. +- ``view`` for functions: Disallows modification of state. +- ``payable`` for functions: Allows them to receive Ether together with a call. +- ``constant`` for state variables: Disallows assignment (except initialisation), does not occupy storage slot. +- ``immutable`` for state variables: Allows assignment at construction time and is constant when deployed. Is stored in code. +- ``anonymous`` for events: Does not store event signature as topic. +- ``indexed`` for event parameters: Stores the parameter as topic. +- ``virtual`` for functions and modifiers: Allows the function's or modifier's + behavior to be changed in derived contracts. +- ``override``: States that this function, modifier or public state variable changes + the behavior of a function or modifier in a base contract. + +>>>>>>> english/develop diff --git a/docs/common-patterns.rst b/docs/common-patterns.rst index 878a2954a3..ee676c9659 100644 --- a/docs/common-patterns.rst +++ b/docs/common-patterns.rst @@ -17,9 +17,15 @@ est un appel direct de "transfert", ce n'est pas recommandé car il introduit un car elle introduit un risque potentiel de sécurité. Vous pouvez lire plus d'informations à ce sujet sur la page :ref:`security_considerations`. +<<<<<<< HEAD Voici un exemple du schéma de retrait en pratique dans un contrat où l'objectif est d'envoyer le plus d'argent vers le contrat afin de devenir le plus "riche", inspiré de +======= +The following is an example of the withdrawal pattern in practice in +a contract where the goal is to send the most of some compensation, e.g. Ether, to the +contract in order to become the "richest", inspired by +>>>>>>> english/develop `King of the Ether `_. Dans le contrat suivant, si vous n'êtes plus le plus riche, @@ -34,7 +40,7 @@ vous recevez les fonds de la personne qui est maintenant la plus riche. address public richest; uint public mostSent; - mapping (address => uint) pendingWithdrawals; + mapping(address => uint) pendingWithdrawals; /// La quantité d'Ether envoyé n'était pas supérieur au /// montant le plus élevé actuellement. @@ -54,8 +60,13 @@ vous recevez les fonds de la personne qui est maintenant la plus riche. function withdraw() public { uint amount = pendingWithdrawals[msg.sender]; +<<<<<<< HEAD // N'oubliez pas de mettre à zéro le remboursement en attente avant // l'envoi pour éviter les attaques de ré-entrance +======= + // Remember to zero the pending refund before + // sending to prevent reentrancy attacks +>>>>>>> english/develop pendingWithdrawals[msg.sender] = 0; payable(msg.sender).transfer(amount); } @@ -157,6 +168,7 @@ restrictions très lisibles. /// Pas assez d'Ether envoyé avec l'appel de fonction. error NotEnoughEther(); +<<<<<<< HEAD // Les modificateurs peuvent être utilisés pour changer // le corps d'une fonction. // Si ce modificateur est utilisé, il @@ -164,8 +176,17 @@ restrictions très lisibles. // que si la fonction est appelée depuis // une certaine adresse. modifier onlyBy(address _account) +======= + // Modifiers can be used to change + // the body of a function. + // If this modifier is used, it will + // prepend a check that only passes + // if the function is called from + // a certain address. + modifier onlyBy(address account) +>>>>>>> english/develop { - if (msg.sender != _account) + if (msg.sender != account) revert Unauthorized(); // N'oubliez pas le "_;"! Il sera // remplacé par le corps de la fonction @@ -173,17 +194,23 @@ restrictions très lisibles. _; } +<<<<<<< HEAD /// Faire de `_newOwner` le nouveau propriétaire de ce /// contrat. function changeOwner(address _newOwner) +======= + /// Make `newOwner` the new owner of this + /// contract. + function changeOwner(address newOwner) +>>>>>>> english/develop public onlyBy(owner) { - owner = _newOwner; + owner = newOwner; } - modifier onlyAfter(uint _time) { - if (block.timestamp < _time) + modifier onlyAfter(uint time) { + if (block.timestamp < time) revert TooEarly(); _; } @@ -199,6 +226,7 @@ restrictions très lisibles. delete owner; } +<<<<<<< HEAD // Ce modificateur exige qu'un certain // frais étant associé à un appel de fonction. // Si l'appelant a envoyé trop de frais, il ou elle est @@ -207,20 +235,35 @@ restrictions très lisibles. // où il était possible de sauter la partie après `_;`. modifier costs(uint _amount) { if (msg.value < _amount) +======= + // This modifier requires a certain + // fee being associated with a function call. + // If the caller sent too much, he or she is + // refunded, but only after the function body. + // This was dangerous before Solidity version 0.4.0, + // where it was possible to skip the part after `_;`. + modifier costs(uint amount) { + if (msg.value < amount) +>>>>>>> english/develop revert NotEnoughEther(); _; - if (msg.value > _amount) - payable(msg.sender).transfer(msg.value - _amount); + if (msg.value > amount) + payable(msg.sender).transfer(msg.value - amount); } - function forceOwnerChange(address _newOwner) + function forceOwnerChange(address newOwner) public payable costs(200 ether) { +<<<<<<< HEAD owner = _newOwner; // juste quelques exemples de conditions +======= + owner = newOwner; + // just some example condition +>>>>>>> english/develop if (uint160(owner) & 0 == 1) // Cela n'a pas remboursé pour Solidity // avant la version 0.4.0. @@ -315,8 +358,8 @@ fonction se termine. uint public creationTime = block.timestamp; - modifier atStage(Stages _stage) { - if (stage != _stage) + modifier atStage(Stages stage_) { + if (stage != stage_) revert FunctionInvalidAtThisStage(); _; } diff --git a/docs/conf.py b/docs/conf.py index 10aa406f28..ddc3ee81bb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -31,7 +31,10 @@ def setup(sphinx): sphinx.add_lexer('Solidity', SolidityLexer) sphinx.add_lexer('Yul', YulLexer) + sphinx.add_css_file('css/fonts.css') sphinx.add_css_file('css/custom.css') + sphinx.add_css_file('css/custom-dark.css') + sphinx.add_css_file('css/pygments.css') # -- General configuration ------------------------------------------------ @@ -45,6 +48,7 @@ def setup(sphinx): 'sphinx_a4doc', 'html_extra_template_renderer', 'remix_code_links', + 'sphinx.ext.imgconverter', ] a4_base_path = os.path.dirname(__file__) + '/grammar' @@ -63,7 +67,7 @@ def setup(sphinx): # General information about the project. project = 'Solidity' -project_copyright = '2016-2021, Ethereum' +project_copyright = '2016-2023, The Solidity Authors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -131,7 +135,6 @@ def setup(sphinx): # documentation. html_theme_options = { 'logo_only': True, - 'style_nav_header_background': '#65afff', 'display_version': True, } @@ -147,12 +150,12 @@ def setup(sphinx): # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = "logo.svg" +# html_logo = "logo.svg" # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +html_favicon = "_static/img/favicon.ico" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -161,7 +164,7 @@ def setup(sphinx): html_css_files = ["css/toggle.css"] -html_js_files = ["js/toggle.js"] +html_js_files = ["js/constants.js", "js/initialize.js", "js/toggle.js"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied @@ -209,7 +212,7 @@ def setup(sphinx): #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +html_show_sphinx = False # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True diff --git a/docs/contracts/abstract-contracts.rst b/docs/contracts/abstract-contracts.rst index a4ee925c37..d04c287a4f 100644 --- a/docs/contracts/abstract-contracts.rst +++ b/docs/contracts/abstract-contracts.rst @@ -6,12 +6,24 @@ Contrats abstraits ****************** +<<<<<<< HEAD Les contrats doivent être marqués comme abstraits lorsqu'au moins une de leurs fonctions n'est pas implémentée. Les contrats peuvent être marqués comme abstraits même si toutes les fonctions sont implémentées. Cela peut être fait en utilisant le mot-clé ``abstract`` comme le montre l'exemple suivant. Notez que ce contrat doit être défini comme abstrait, car la fonction ``utterance()`` a été définie, mais aucune implémentation n'a été fournie (aucun corps d'implémentation ``{ }`` n'a été donné). +======= +Contracts must be marked as abstract when at least one of their functions is not implemented or when +they do not provide arguments for all of their base contract constructors. +Even if this is not the case, a contract may still be marked abstract, such as when you do not intend +for the contract to be created directly. Abstract contracts are similar to :ref:`interfaces` but an +interface is more limited in what it can declare. + +An abstract contract is declared using the ``abstract`` keyword as shown in the following example. +Note that this contract needs to be defined as abstract, because the function ``utterance()`` is declared, +but no implementation was provided (no implementation body ``{ }`` was given). +>>>>>>> english/develop .. code-block:: solidity diff --git a/docs/contracts/constant-state-variables.rst b/docs/contracts/constant-state-variables.rst index 3145abcfd3..e538882d6a 100644 --- a/docs/contracts/constant-state-variables.rst +++ b/docs/contracts/constant-state-variables.rst @@ -30,25 +30,36 @@ Tous les types de constantes et d'immuables ne sont pas encore implémentés. Le .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.7.4; + pragma solidity ^0.8.21; uint constant X = 32**22 + 8; contract C { string constant TEXT = "abc"; bytes32 constant MY_HASH = keccak256("abc"); - uint immutable decimals; + uint immutable decimals = 18; uint immutable maxBalance; address immutable owner = msg.sender; +<<<<<<< HEAD constructor(uint _decimals, address _reference) { decimals = _decimals; // Les affectations aux immuables peuvent même accéder à l'environnement. maxBalance = _reference.balance; +======= + constructor(uint decimals_, address ref) { + if (decimals_ != 0) + // Immutables are only immutable when deployed. + // At construction time they can be assigned to any number of times. + decimals = decimals_; + + // Assignments to immutables can even access the environment. + maxBalance = ref.balance; +>>>>>>> english/develop } - function isBalanceTooHigh(address _other) public view returns (bool) { - return _other.balance > maxBalance; + function isBalanceTooHigh(address other) public view returns (bool) { + return other.balance > maxBalance; } } @@ -72,6 +83,7 @@ Cette fonctionnalité n'est pas encore totalement utilisable. Immutable ========= +<<<<<<< HEAD Les variables déclarées comme ``immutables`` sont un peu moins restreintes que celles déclarées comme ``constant`` : Les variables immuables peuvent se voir attribuer une valeur arbitraire dans le constructeur du contrat ou au moment de leur déclaration. @@ -94,3 +106,37 @@ blockchain. Il s'agit d'une protection contre les différentes interprétations concernant l'ordre de l'initialisation des variables d'état et de l'exécution du constructeur, en particulier en ce qui concerne l'héritage. +======= +Variables declared as ``immutable`` are a bit less restricted than those +declared as ``constant``: Immutable variables can be assigned a +value at construction time. +The value can be changed at any time before deployment and then it becomes permanent. + +One additional restriction is that immutables can only be assigned to inside expressions for which +there is no possibility of being executed after creation. +This excludes all modifier definitions and functions other than constructors. + +There are no restrictions on reading immutable variables. +The read is even allowed to happen before the variable is written to for the first time because variables in +Solidity always have a well-defined initial value. +For this reason it is also allowed to never explicitly assign a value to an immutable. + +.. warning:: + When accessing immutables at construction time, please keep the :ref:`initialization order + ` in mind. + Even if you provide an explicit initializer, some expressions may end up being evaluated before + that initializer, especially when they are at a different level in inheritance hierarchy. + +.. note:: + Before Solidity 0.8.21 initialization of immutable variables was more restrictive. + Such variables had to be initialized exactly once at construction time and could not be read + before then. + +The contract creation code generated by the compiler will modify the +contract's runtime code before it is returned by replacing all references +to immutables with the values assigned to them. This is important if +you are comparing the +runtime code generated by the compiler with the one actually stored in the +blockchain. The compiler outputs where these immutables are located in the deployed bytecode +in the ``immutableReferences`` field of the :ref:`compiler JSON standard output `. +>>>>>>> english/develop diff --git a/docs/contracts/creating-contracts.rst b/docs/contracts/creating-contracts.rst index a4769d852f..b0a779a6e8 100644 --- a/docs/contracts/creating-contracts.rst +++ b/docs/contracts/creating-contracts.rst @@ -8,9 +8,15 @@ Les contrats peuvent être créés "de l'extérieur" via des transactions Ethere Des IDE, tels que `Remix `_, rendent le processus de création transparent à l'aide d'éléments d'interface utilisateur. +<<<<<<< HEAD Une façon de créer des contrats de façon programmatique sur Ethereum est via l'API JavaScript `web3.js `_. Elle dispose d'une fonction appelée `web3.eth.Contract `_ pour faciliter la création de contrats. +======= +One way to create contracts programmatically on Ethereum is via the JavaScript API `web3.js `_. +It has a function called `web3.eth.Contract `_ +to facilitate contract creation. +>>>>>>> english/develop Lorsqu'un contrat est créé, son :ref:`constructeur ` (une fonction déclarée avec la fonction le mot-clé ``constructor``) est exécutée une fois. @@ -46,6 +52,7 @@ Cela signifie que les dépendances cycliques de création sont impossibles. address owner; bytes32 name; +<<<<<<< HEAD // Il s'agit du constructeur qui enregistre le // créateur et le nom attribué. constructor(bytes32 _name) { @@ -57,6 +64,19 @@ Cela signifie que les dépendances cycliques de création sont impossibles. // vous ne devriez pas accéder aux fonctions de manière externe, // car la fonction n'existe pas encore. // Voir la section suivante pour plus de détails. +======= + // This is the constructor which registers the + // creator and the assigned name. + constructor(bytes32 name_) { + // State variables are accessed via their name + // and not via e.g. `this.owner`. Functions can + // be accessed directly or through `this.f`, + // but the latter provides an external view + // to the function. Especially in the constructor, + // you should not access functions externally, + // because the function does not exist yet. + // See the next section for details. +>>>>>>> english/develop owner = msg.sender; // Nous effectuons une conversion de type explicite de `address` @@ -65,7 +85,7 @@ Cela signifie que les dépendances cycliques de création sont impossibles. // aucun moyen réel de le vérifier. // Cette opération ne crée pas de nouveau contrat. creator = TokenCreator(msg.sender); - name = _name; + name = name_; } function changeName(bytes32 newName) public { diff --git a/docs/contracts/errors.rst b/docs/contracts/errors.rst index e4a2feb177..01de49e826 100644 --- a/docs/contracts/errors.rst +++ b/docs/contracts/errors.rst @@ -1,5 +1,4 @@ -.. index:: ! error, revert - +.. index:: ! error, revert, ! selector; of an error .. _errors: ************************************************** @@ -73,9 +72,23 @@ De même, un échec de ``assert`` ou des conditions similaires se retourneront a du type intégré ``Panic(uint256)``. .. note:: +<<<<<<< HEAD Les données d'erreur ne doivent être utilisées que pour donner une indication de l'échec, mais pas comme un moyen pour le flux de contrôle. La raison en est que les données de retour des appels internes sont propagées en retour dans la chaîne des appels externes par défaut. Cela signifie qu'un appel interne peut "forger" des données de retour qui semblent pouvoir provenir du contrat qui l'a appelé. +======= + Error data should only be used to give an indication of failure, but + not as a means for control-flow. The reason is that the revert data + of inner calls is propagated back through the chain of external calls + by default. This means that an inner call + can "forge" revert data that looks like it could have come from the + contract that called it. + +Members of Errors +================= + +- ``error.selector``: A ``bytes4`` value containing the error selector. +>>>>>>> english/develop diff --git a/docs/contracts/events.rst b/docs/contracts/events.rst index 6af33cde83..4d94a0e477 100644 --- a/docs/contracts/events.rst +++ b/docs/contracts/events.rst @@ -1,4 +1,4 @@ -.. index:: ! event +.. index:: ! event, ! event; anonymous, ! event; indexed, ! event; topic .. _events: @@ -9,6 +9,7 @@ Les événements Solidity offrent une abstraction au-dessus de la fonctionnalité de journalisation de l'EVM. Les applications peuvent s'abonner et écouter ces événements via l'interface RPC d'un client Ethereum. +<<<<<<< HEAD Les événements sont des membres héritables des contrats. Lorsque vous les appelez, ils font en sorte que les arguments dans le journal de la transaction, une structure de données spéciale dans la blockchain. Ces journaux sont associés à l'adresse du contrat, @@ -16,6 +17,16 @@ sont incorporés dans la blockchain, et y restent aussi longtemps qu'un bloc est accessible (pour toujours à partir de maintenant, mais cela pourrait changer avec Serenity). Le journal et ses données d'événement ne sont pas accessibles à partir des contrats (même pas depuis le contrat qui les a créés). +======= +Events can be defined at file level or as inheritable members of contracts (including interfaces and libraries). +When you call them, they cause the +arguments to be stored in the transaction's log - a special data structure +in the blockchain. These logs are associated with the address of the contract that emitted them, +are incorporated into the blockchain, and stay there as long as a block is +accessible (forever as of now, but this might +change in the future). The Log and its event data is not accessible from within +contracts (not even from the contract that created them). +>>>>>>> english/develop Il est possible de demander une preuve Merkle pour les journaux. Si une entité externe fournit une telle preuve à un contrat, celui-ci peut vérifier @@ -71,6 +82,18 @@ quatre arguments indexés au lieu de trois. En particulier, il est possible de "falsifier" la signature d'un autre événement en utilisant un événement anonyme. +.. index:: ! selector; of an event + +Members of Events +================= + +- ``event.selector``: For non-anonymous events, this is a ``bytes32`` value + containing the ``keccak256`` hash of the event signature, as used in the default topic. + + +Example +======= + .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 @@ -78,11 +101,12 @@ quatre arguments indexés au lieu de trois. contract ClientReceipt { event Deposit( - address indexed _from, - bytes32 indexed _id, - uint _value + address indexed from, + bytes32 indexed id, + uint value ); +<<<<<<< HEAD function deposit(bytes32 _id) public payable { // Les événements sont émis en utilisant `emit`, suivi par // le nom de l'événement et les arguments @@ -90,6 +114,15 @@ quatre arguments indexés au lieu de trois. // (même profondément imbriquée) peut être détectée à partir de // l'API JavaScript en filtrant pour `Deposit`. emit Deposit(msg.sender, _id, msg.value); +======= + function deposit(bytes32 id) public payable { + // Events are emitted using `emit`, followed by + // the name of the event and the arguments + // (if any) in parentheses. Any such invocation + // (even deeply nested) can be detected from + // the JavaScript API by filtering for `Deposit`. + emit Deposit(msg.sender, id, msg.value); +>>>>>>> english/develop } } @@ -124,9 +157,9 @@ Le résultat de l'opération ci-dessus ressemble à ce qui suit (découpé) : { "returnValues": { - "_from": "0x1111…FFFFCCCC", - "_id": "0x50…sd5adb20", - "_value": "0x420042" + "from": "0x1111…FFFFCCCC", + "id": "0x50…sd5adb20", + "value": "0x420042" }, "raw": { "data": "0x7f…91385", @@ -134,9 +167,18 @@ Le résultat de l'opération ci-dessus ressemble à ce qui suit (découpé) : } } +<<<<<<< HEAD Ressources supplémentaires pour comprendre les événements ========================================================= - `Documentation Javascript `_ - `Exemple d'utilisation des événements `_ - `Comment y accéder en js `_ +======= +Additional Resources for Understanding Events +============================================= + +- `JavaScript documentation `_ +- `Example usage of events `_ +- `How to access them in js `_ +>>>>>>> english/develop diff --git a/docs/contracts/function-modifiers.rst b/docs/contracts/function-modifiers.rst index 17edcf4b34..ac99c48196 100644 --- a/docs/contracts/function-modifiers.rst +++ b/docs/contracts/function-modifiers.rst @@ -6,9 +6,15 @@ Modificateurs de fonction ************************* +<<<<<<< HEAD Les modificateurs peuvent être utilisés pour changer le comportement des fonctions de manière déclarative. Par exemple, vous pouvez utiliser un modificateur pour vérifier automatiquement une condition avant d'exécuter la fonction. +======= +Modifiers can be used to change the behavior of functions in a declarative way. +For example, +you can use a modifier to automatically check a condition prior to executing the function. +>>>>>>> english/develop Les modificateurs sont des propriétés héritables des contrats et peuvent être remplacées par des contrats dérivés, mais uniquement s'ils sont marqués ``virtual``. Pour plus de détails, veuillez consulter @@ -18,6 +24,7 @@ s'ils sont marqués ``virtual``. Pour plus de détails, veuillez consulter // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.1 <0.9.0; + // This will report a warning due to deprecated selfdestruct contract owned { constructor() { owner = payable(msg.sender); } @@ -59,7 +66,7 @@ s'ils sont marqués ``virtual``. Pour plus de détails, veuillez consulter } contract Register is priced, destructible { - mapping (address => bool) registeredAddresses; + mapping(address => bool) registeredAddresses; uint price; constructor(uint initialPrice) { price = initialPrice; } @@ -71,8 +78,8 @@ s'ils sont marqués ``virtual``. Pour plus de détails, veuillez consulter registeredAddresses[msg.sender] = true; } - function changePrice(uint _price) public onlyOwner { - price = _price; + function changePrice(uint price_) public onlyOwner { + price = price_; } } @@ -110,9 +117,21 @@ séparée par des espaces et sont évaluées dans l'ordre présenté. Les modificateurs ne peuvent pas accéder ou modifier implicitement les arguments et les valeurs de retour des fonctions qu'ils modifient. Leurs valeurs ne peuvent leur être transmises que de manière explicite au moment de l'invocation. +<<<<<<< HEAD Les retours explicites d'un modificateur ou d'un corps de fonction ne quittent que le modificateur ou du corps de la fonction actuelle. Les variables de retour sont assignées et le flux de contrôle continue après le ``_`` du modificateur précédent. +======= +In function modifiers, it is necessary to specify when you want the function to which the modifier is +applied to be run. The placeholder statement (denoted by a single underscore character ``_``) is used to +denote where the body of the function being modified should be inserted. Note that the +placeholder operator is different from using underscores as leading or trailing characters in variable +names, which is a stylistic choice. + +Explicit returns from a modifier or function body only leave the current +modifier or function body. Return variables are assigned and +control flow continues after the ``_`` in the preceding modifier. +>>>>>>> english/develop .. warning:: Dans une version antérieure de Solidity, les instructions ``return`` dans les fonctions @@ -122,8 +141,13 @@ Un retour explicite d'un modificateur avec ``return;`` n'affecte pas les valeurs Le modificateur peut toutefois choisir de ne pas exécuter du tout le corps de la fonction et, dans ce cas, les variables ``return`` sont placées à leur :ref:`valeur par défaut` comme si la fonction avait un corps vide. +<<<<<<< HEAD Le symbole ``_`` peut apparaître plusieurs fois dans le modificateur. Chaque occurrence est remplacée par le corps de la fonction. +======= +The ``_`` symbol can appear in the modifier multiple times. Each occurrence is replaced with +the function body, and the function returns the return value of the final occurrence. +>>>>>>> english/develop Les expressions arbitraires sont autorisées pour les arguments du modificateur et dans ce contexte, tous les symboles visibles de la fonction sont visibles dans le modificateur. Les symboles diff --git a/docs/contracts/functions.rst b/docs/contracts/functions.rst index 98aeea89c1..4568c8a81e 100644 --- a/docs/contracts/functions.rst +++ b/docs/contracts/functions.rst @@ -1,4 +1,4 @@ -.. index:: ! functions +.. index:: ! functions, ! function;free .. _functions: @@ -17,29 +17,45 @@ qui les appellent, comme pour les fonctions internes des bibliothèques. // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.1 <0.9.0; - function sum(uint[] memory _arr) pure returns (uint s) { - for (uint i = 0; i < _arr.length; i++) - s += _arr[i]; + function sum(uint[] memory arr) pure returns (uint s) { + for (uint i = 0; i < arr.length; i++) + s += arr[i]; } contract ArrayExample { bool found; +<<<<<<< HEAD function f(uint[] memory _arr) public { // Cela appelle la fonction free en interne. // Le compilateur ajoutera son code au contrat. uint s = sum(_arr); +======= + function f(uint[] memory arr) public { + // This calls the free function internally. + // The compiler will add its code to the contract. + uint s = sum(arr); +>>>>>>> english/develop require(s >= 10); found = true; } } .. note:: +<<<<<<< HEAD Les fonctions définies en dehors d'un contrat sont toujours exécutées dans le contexte d'un contrat. Elles ont toujours accès à la variable ``this``, peuvent appeler d'autres contrats, leur envoyer de l'Ether et détruire le contrat qui les a appelées, entre autres choses. La principale différence avec les fonctions définies à l'intérieur d'un contrat est que les fonctions libres n'ont pas d'accès direct aux variables de stockage et aux fonctions qui ne sont pas dans leur portée. +======= + Functions defined outside a contract are still always executed + in the context of a contract. + They still can call other contracts, send them Ether and destroy the contract that called them, + among other things. The main difference to functions defined inside a contract + is that free functions do not have direct access to the variable ``this``, storage variables and functions + not in their scope. +>>>>>>> english/develop .. _function-parameters-return-variables: @@ -65,14 +81,15 @@ avec deux entiers, vous utiliserez quelque chose comme ce qui suit : contract Simple { uint sum; - function taker(uint _a, uint _b) public { - sum = _a + _b; + function taker(uint a, uint b) public { + sum = a + b; } } Les paramètres de fonction peuvent être utilisés comme n'importe quelle autre variable locale et ils peuvent également être affectés. +<<<<<<< HEAD .. note:: Une :ref:`fonction externe` ne peut pas accepter un @@ -83,6 +100,8 @@ variable locale et ils peuvent également être affectés. Une :ref:`fonction interne` peut accepter un tableau multidimensionnel sans activer la fonction. +======= +>>>>>>> english/develop .. index:: return array, return string, array, string, array of strings, dynamic array, variably sized array, return struct, struct Variables de retour @@ -100,13 +119,13 @@ deux entiers passés comme paramètres de la fonction, vous utiliserez quelque c pragma solidity >=0.4.16 <0.9.0; contract Simple { - function arithmetic(uint _a, uint _b) + function arithmetic(uint a, uint b) public pure - returns (uint o_sum, uint o_product) + returns (uint sum, uint product) { - o_sum = _a + _b; - o_product = _a * _b; + sum = a + b; + product = a * b; } } @@ -126,12 +145,12 @@ ou vous pouvez fournir des valeurs de retour pragma solidity >=0.4.16 <0.9.0; contract Simple { - function arithmetic(uint _a, uint _b) + function arithmetic(uint a, uint b) public pure - returns (uint o_sum, uint o_product) + returns (uint sum, uint product) { - return (_a + _b, _a * _b); + return (a + b, a * b); } } @@ -139,12 +158,25 @@ Si vous utilisez un ``return`` précoce pour quitter une fonction qui a des vari vous devez fournir des valeurs de retour avec l'instruction return. .. note:: +<<<<<<< HEAD Vous ne pouvez pas retourner certains types à partir de fonctions non internes, notamment les tableaux dynamiques multidimensionnels et les structs. Si vous activez le ABI coder v2 en ajoutant ``pragma abicoder v2;`` à votre fichier source, alors plus de types sont disponibles, mais les types ``mapping`` sont toujours limités à l'intérieur d'un seul contrat et vous ne pouvez pas les transférer. +======= + You cannot return some types from non-internal functions. + This includes the types listed below and any composite types that recursively contain them: + + - mappings, + - internal function types, + - reference types with location set to ``storage``, + - multi-dimensional arrays (applies only to :ref:`ABI coder v1 `), + - structs (applies only to :ref:`ABI coder v1 `). + + This restriction does not apply to library functions because of their different :ref:`internal ABI `. +>>>>>>> english/develop .. _multi-return: @@ -256,7 +288,11 @@ Revenir en arrière sur un changement d'état n'est pas considéré comme une "m d'état effectuées précédemment dans du code qui n'avait pas la restriction ``view`` ou ``pure`` sont inversées et ce code a la possibilité d'attraper le ``revert`` et de ne pas le transmettre. +<<<<<<< HEAD Ce comportement est également en accord avec l'opcode ``STATICCALL``. +======= +This behavior is also in line with the ``STATICCALL`` opcode. +>>>>>>> english/develop .. warning:: Il est impossible d'empêcher les fonctions de lire l'état au niveau @@ -282,7 +318,7 @@ Ce comportement est également en accord avec l'opcode ``STATICCALL``. Fonctions spéciales =================== -.. index:: ! receive ether function, function;receive ! receive +.. index:: ! receive ether function, function;receive, ! receive .. _receive-ether-function: @@ -295,6 +331,7 @@ Cette fonction ne peut pas avoir d'arguments, ne peut rien retourner et doit avo une visibilité ``external`` et une mutabilité de l'état ``payable``. Elle peut être virtuelle, peut être surchargée et peut avoir des modificateurs. +<<<<<<< HEAD La fonction de réception est exécutée lors d'un appel au contrat avec des données d'appel vides. C'est la fonction qui est exécutée lors des transferts d'Ether (par exemple via ``.send()`` ou ``.transfer()``). Si cette @@ -302,6 +339,15 @@ fonction n'existe pas, mais qu'une fonction payable :ref:`de repli ` +exists, the fallback function will be called on a plain Ether transfer. If +neither a receive Ether nor a payable fallback function is present, the +contract cannot receive Ether through a transaction that does not represent a payable function call and throws an +>>>>>>> english/develop exception. Dans le pire des cas, la fonction ``receive`` ne peut compter que sur le fait que 2300 gaz soient @@ -315,12 +361,22 @@ consommeront plus de gaz que l'allocation de 2300 gaz : - Envoi d'éther .. warning:: +<<<<<<< HEAD Les contrats qui reçoivent de l'Ether directement (sans appel de fonction, c'est-à-dire en utilisant ``send`` ou ``transfer``) mais qui ne définissent pas de fonction de réception d'Ether ou de fonction de repli payable, lancer une exception en renvoyant l'Ether (ceci était différent avant Solidity v0.4.0). Donc si vous voulez que votre contrat reçoive de l'Ether, vous devez implémenter une fonction de réception d'Ether (l'utilisation de fonctions de repli payantes pour recevoir de l'éther n'est pas recommandée, car elle n'échouerait pas en cas de confusion d'interface). +======= + When Ether is sent directly to a contract (without a function call, i.e. sender uses ``send`` or ``transfer``) + but the receiving contract does not define a receive Ether function or a payable fallback function, + an exception will be thrown, sending back the Ether (this was different + before Solidity v0.4.0). If you want your contract to receive Ether, + you have to implement a receive Ether function (using payable fallback functions for receiving Ether is + not recommended, since the fallback is invoked and would not fail for interface confusions + on the part of the sender). +>>>>>>> english/develop .. warning:: @@ -359,11 +415,19 @@ Ci-dessous vous pouvez voir un exemple d'un contrat Sink qui utilise la fonction Fonction de repli ----------------- +<<<<<<< HEAD Un contrat peut avoir au maximum une fonction ``fallback``, déclarée en utilisant soit ``fallback () external [payable]``, soit ``fallback (bytes calldata _input) external [payable] returns (bytes memory _output)`` (dans les deux cas sans le mot-clé ``function``). Cette fonction doit avoir une visibilité ``external``. Une fonction de repli peut être virtuelle, peut remplacer et peut avoir des modificateurs. +======= +A contract can have at most one ``fallback`` function, declared using either ``fallback () external [payable]`` +or ``fallback (bytes calldata input) external [payable] returns (bytes memory output)`` +(both without the ``function`` keyword). +This function must have ``external`` visibility. A fallback function can be virtual, can override +and can have modifiers. +>>>>>>> english/develop La fonction de repli est exécutée lors d'un appel au contrat si aucune des autres fonction ne correspond à la signature de la fonction donnée, ou si aucune donnée n'est fournie @@ -371,9 +435,15 @@ et qu'il n'existe pas de :ref:`fonction de réception d'éther >>>>>> english/develop Dans le pire des cas, si une fonction de repli payable est également utilisée à la place d'une fonction de réception, elle ne peut compter que sur le gaz 2300 @@ -391,6 +461,7 @@ complexes tant qu'il y a suffisamment de gaz qui lui est transmis. afin de distinguer les transferts Ether des confusions d'interface. .. note:: +<<<<<<< HEAD Si vous voulez décoder les données d'entrée, vous pouvez vérifier les quatre premiers octets pour le sélecteur de fonction et ensuite vous pouvez utiliser ``abi.decode`` avec la syntaxe array slice pour @@ -398,6 +469,15 @@ complexes tant qu'il y a suffisamment de gaz qui lui est transmis. ``(c, d) = abi.decode(_input[4 :], (uint256, uint256));`` Notez que cette méthode ne doit être utilisée qu'en dernier recours, et que les fonctions appropriées doivent être utilisées à la place. +======= + If you want to decode the input data, you can check the first four bytes + for the function selector and then + you can use ``abi.decode`` together with the array slice syntax to + decode ABI-encoded data: + ``(c, d) = abi.decode(input[4:], (uint256, uint256));`` + Note that this should only be used as a last resort and + proper functions should be used instead. +>>>>>>> english/develop .. code-block:: solidity @@ -481,13 +561,13 @@ L'exemple suivant montre la surcharge de la fonction ``f`` dans la portée du co pragma solidity >=0.4.16 <0.9.0; contract A { - function f(uint _in) public pure returns (uint out) { - out = _in; + function f(uint value) public pure returns (uint out) { + out = value; } - function f(uint _in, bool _really) public pure returns (uint out) { - if (_really) - out = _in; + function f(uint value, bool really) public pure returns (uint out) { + if (really) + out = value; } } @@ -501,12 +581,12 @@ fonctions visibles de l'extérieur diffèrent par leurs types Solidity mais pas // This will not compile contract A { - function f(B _in) public pure returns (B out) { - out = _in; + function f(B value) public pure returns (B out) { + out = value; } - function f(address _in) public pure returns (address out) { - out = _in; + function f(address value) public pure returns (address out) { + out = value; } } @@ -534,12 +614,12 @@ candidat, la résolution échoue. pragma solidity >=0.4.16 <0.9.0; contract A { - function f(uint8 _in) public pure returns (uint8 out) { - out = _in; + function f(uint8 val) public pure returns (uint8 out) { + out = val; } - function f(uint256 _in) public pure returns (uint256 out) { - out = _in; + function f(uint256 val) public pure returns (uint256 out) { + out = val; } } diff --git a/docs/contracts/inheritance.rst b/docs/contracts/inheritance.rst index b18e21d7db..47a227bc9c 100644 --- a/docs/contracts/inheritance.rst +++ b/docs/contracts/inheritance.rst @@ -40,7 +40,7 @@ Les détails sont donnés dans l'exemple suivant. // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; - + // This will report a warning due to deprecated selfdestruct contract Owned { constructor() { owner = payable(msg.sender); } @@ -53,8 +53,13 @@ Les détails sont donnés dans l'exemple suivant. // les fonctions internes et les variables d'état. Ceux-ci ne peuvent pas être // accessibles en externe via `this`. contract Destructible is Owned { +<<<<<<< HEAD // Le mot clé `virtual` signifie que la fonction peut modifier // son comportement dans les classes dérivées ("overriding"). +======= + // The keyword `virtual` means that the function can change + // its behavior in derived classes ("overriding"). +>>>>>>> english/develop function destroy() virtual public { if (msg.sender == owner) selfdestruct(owner); } @@ -76,9 +81,15 @@ Les détails sont donnés dans l'exemple suivant. } +<<<<<<< HEAD // L'héritage multiple est possible. Notez que `owned` // est aussi une classe de base de `Destructible`, mais il n'y a qu'une seule instance de `owned`. // Pourtant, il n'existe qu'une seule instance de `owned` (comme pour l'héritage virtuel en C++). +======= + // Multiple inheritance is possible. Note that `Owned` is + // also a base class of `Destructible`, yet there is only a single + // instance of `Owned` (as for virtual inheritance in C++). +>>>>>>> english/develop contract Named is Owned, Destructible { constructor(bytes32 name) { Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970); @@ -112,9 +123,15 @@ Les détails sont donnés dans l'exemple suivant. if (msg.sender == owner) info = newInfo; } +<<<<<<< HEAD // Ici, nous ne spécifions que `override` et non `virtual`. // Cela signifie que les contrats dérivant de `PriceFeed` // ne peuvent plus modifier le comportement de `destroy`. +======= + // Here, we only specify `override` and not `virtual`. + // This means that contracts deriving from `PriceFeed` + // cannot change the behavior of `destroy` anymore. +>>>>>>> english/develop function destroy() public override(Destructible, Named) { Named.destroy(); } function get() public view returns(uint r) { return info; } @@ -129,6 +146,7 @@ comme le montre l'exemple suivant : // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; + // This will report a warning due to deprecated selfdestruct contract owned { constructor() { owner = payable(msg.sender); } @@ -161,6 +179,7 @@ explicitement dans la surcharge finale, mais cette fonction contournera // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; + // This will report a warning due to deprecated selfdestruct contract owned { constructor() { owner = payable(msg.sender); } @@ -289,8 +308,13 @@ le graphe d'héritage qui commence au contrat considéré et se termine par un contrat mentionnant une fonction avec cette signature qui n'est pas surchargée. +<<<<<<< HEAD Si vous n'indiquez pas qu'une fonction qui surcharge est ``virtual``, les contrats dérivés ne peuvent plus modifier le comportement de cette fonction. +======= +If you do not mark a function that overrides as ``virtual``, derived +contracts can no longer change the behavior of that function. +>>>>>>> english/develop .. note:: @@ -419,8 +443,8 @@ S'il n'y a pas de constructeur, le contrat prendra en charge le constructeur par abstract contract A { uint public a; - constructor(uint _a) { - a = _a; + constructor(uint a_) { + a = a_; } } @@ -433,15 +457,24 @@ le contrat doit être marqué :ref:`abstract `, parce que ces pas se voir attribuer de valeurs valides de l'extérieur, mais uniquement par le biais des constructeurs des contrats dérivés. .. warning:: +<<<<<<< HEAD Avant la version 0.4.22, les constructeurs étaient définis comme des fonctions portant le même nom que le contrat. Cette syntaxe a été dépréciée et n'est plus autorisée dans la version 0.5.0. .. warning:: Avant la version 0.7.0, vous deviez spécifier la visibilité des constructeurs comme étant soit ``internal`` ou ``public``. +======= + Prior to version 0.4.22, constructors were defined as functions with the same name as the contract. + This syntax was deprecated and is not allowed anymore in version 0.5.0. + +.. warning:: + Prior to version 0.7.0, you had to specify the visibility of constructors as either + ``internal`` or ``public``. +>>>>>>> english/develop -.. index:: ! base;constructor +.. index:: ! base;constructor, inheritance list, contract;abstract, abstract contract Arguments pour les constructeurs de base ======================================== @@ -457,7 +490,7 @@ les contrats dérivés doivent tous les spécifier. Ceci peut être fait de deux contract Base { uint x; - constructor(uint _x) { x = _x; } + constructor(uint x_) { x = x_; } } // Soit spécifier directement dans la liste d'héritage... @@ -465,11 +498,25 @@ les contrats dérivés doivent tous les spécifier. Ceci peut être fait de deux constructor() {} } +<<<<<<< HEAD // ou par un "modificateur" du constructeur dérivé. +======= + // or through a "modifier" of the derived constructor... +>>>>>>> english/develop contract Derived2 is Base { - constructor(uint _y) Base(_y * _y) {} + constructor(uint y) Base(y * y) {} + } + + // or declare abstract... + abstract contract Derived3 is Base { + } + + // and have the next concrete derived contract initialize it. + contract DerivedFromDerived is Derived3 { + constructor() Base(10 + 10) {} } +<<<<<<< HEAD L'une des façons est directement dans la liste d'héritage (``est Base(7)``). L'autre est dans la façon dont un modificateur est invoqué dans le cadre du constructeur dérivé (``Base(_y * _y)``). La première façon @@ -483,6 +530,26 @@ Spécifier les arguments aux deux endroits est une erreur. Si un contrat dérivé ne spécifie pas les arguments de tous les constructeurs de ses contrats de base, il sera considéré comme un contrat abstrait. +======= +One way is directly in the inheritance list (``is Base(7)``). The other is in +the way a modifier is invoked as part of +the derived constructor (``Base(y * y)``). The first way to +do it is more convenient if the constructor argument is a +constant and defines the behavior of the contract or +describes it. The second way has to be used if the +constructor arguments of the base depend on those of the +derived contract. Arguments have to be given either in the +inheritance list or in modifier-style in the derived constructor. +Specifying arguments in both places is an error. + +If a derived contract does not specify the arguments to all of its base +contracts' constructors, it must be declared abstract. In that case, when +another contract derives from it, that other contract's inheritance list +or constructor must provide the necessary parameters +for all base classes that haven't had their parameters specified (otherwise, +that other contract must be declared abstract as well). For example, in the above +code snippet, see ``Derived3`` and ``DerivedFromDerived``. +>>>>>>> english/develop .. index:: ! inheritance;multiple, ! linearization, ! C3 linearization @@ -572,9 +639,20 @@ Un domaine où la linéarisation de l'héritage est particulièrement importante Hériter de différents types de membres portant le même nom ========================================================== +<<<<<<< HEAD C'est une erreur lorsque l'une des paires suivantes dans un contrat porte le même nom en raison de l'héritage : - une fonction et un modificateur - une fonction et un événement - un événement et un modificateur À titre d'exception, un getter de variable d'état peut remplacer une fonction externe. +======= +The only situations where, due to inheritance, a contract may contain multiple definitions sharing +the same name are: + +- Overloading of functions. +- Overriding of virtual functions. +- Overriding of external virtual functions by state variable getters. +- Overriding of virtual modifiers. +- Overloading of events. +>>>>>>> english/develop diff --git a/docs/contracts/interfaces.rst b/docs/contracts/interfaces.rst index 6d9a8aa912..bfbe1277b1 100644 --- a/docs/contracts/interfaces.rst +++ b/docs/contracts/interfaces.rst @@ -9,11 +9,19 @@ Interfaces Les interfaces sont similaires aux contrats abstraits, mais aucune fonction ne peut y être implémentée. Il existe d'autres restrictions : +<<<<<<< HEAD - Elles ne peuvent pas hériter d'autres contrats, mais elles peuvent hériter d'autres interfaces. - Toutes les fonctions déclarées doivent être externes. - Elles ne peuvent pas déclarer de constructeur. - Elles ne peuvent pas déclarer de variables d'état. - Elles ne peuvent pas déclarer de modificateurs. +======= +- They cannot inherit from other contracts, but they can inherit from other interfaces. +- All declared functions must be external in the interface, even if they are public in the contract. +- They cannot declare a constructor. +- They cannot declare state variables. +- They cannot declare modifiers. +>>>>>>> english/develop Certaines de ces restrictions peuvent être levées à l'avenir. diff --git a/docs/contracts/libraries.rst b/docs/contracts/libraries.rst index 893ba5d406..a83379174f 100644 --- a/docs/contracts/libraries.rst +++ b/docs/contracts/libraries.rst @@ -144,16 +144,16 @@ personnalisés sans la surcharge des appels de fonctions externes : r.limbs[0] = x; } - function add(bigint memory _a, bigint memory _b) internal pure returns (bigint memory r) { - r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length)); + function add(bigint memory a, bigint memory b) internal pure returns (bigint memory r) { + r.limbs = new uint[](max(a.limbs.length, b.limbs.length)); uint carry = 0; for (uint i = 0; i < r.limbs.length; ++i) { - uint a = limb(_a, i); - uint b = limb(_b, i); + uint limbA = limb(a, i); + uint limbB = limb(b, i); unchecked { - r.limbs[i] = a + b + carry; + r.limbs[i] = limbA + limbB + carry; - if (a + b < a || (a + b == type(uint).max && carry > 0)) + if (limbA + limbB < limbA || (limbA + limbB == type(uint).max && carry > 0)) carry = 1; else carry = 0; @@ -170,8 +170,8 @@ personnalisés sans la surcharge des appels de fonctions externes : } } - function limb(bigint memory _a, uint _limb) internal pure returns (uint) { - return _limb < _a.limbs.length ? _a.limbs[_limb] : 0; + function limb(bigint memory a, uint index) internal pure returns (uint) { + return index < a.limbs.length ? a.limbs[index] : 0; } function max(uint a, uint b) private pure returns (uint) { @@ -213,7 +213,7 @@ Par rapport aux contrats, les bibliothèques sont limitées de la manière suiva (Ces restrictions pourraient être levées ultérieurement). .. _library-selectors: -.. index:: selector +.. index:: ! selector; of a library function Signatures de fonction et sélecteurs dans les bibliothèques =========================================================== diff --git a/docs/contracts/using-for.rst b/docs/contracts/using-for.rst index f81f721590..25037d1678 100644 --- a/docs/contracts/using-for.rst +++ b/docs/contracts/using-for.rst @@ -1,4 +1,4 @@ -.. index:: ! using for, library +.. index:: ! using for, library, ! operator;user-defined, function;free .. _using-for: @@ -6,6 +6,7 @@ Utiliser For ************ +<<<<<<< HEAD La directive ``using A for B;`` peut être utilisée pour attacher des fonctions (de la bibliothèque ``A``) à n'importe quel type (``B``) dans le contexte d'un contrat. @@ -28,16 +29,127 @@ ne peut être utilisée qu'à l'intérieur d'un contrat, et non à l'intérieur Réécrivons l'exemple de l'ensemble à partir de la directive :ref:`libraries` de cette manière : +======= +The directive ``using A for B`` can be used to attach +functions (``A``) as operators to user-defined value types +or as member functions to any type (``B``). +The member functions receive the object they are called on +as their first parameter (like the ``self`` variable in Python). +The operator functions receive operands as parameters. + +It is valid either at file level or inside a contract, +at contract level. + +The first part, ``A``, can be one of: + +- A list of functions, optionally with an operator name assigned (e.g. + ``using {f, g as +, h, L.t} for uint``). + If no operator is specified, the function can be either a library function or a free function and + is attached to the type as a member function. + Otherwise it must be a free function and it becomes the definition of that operator on the type. +- The name of a library (e.g. ``using L for uint``) - + all non-private functions of the library are attached to the type + as member functions + +At file level, the second part, ``B``, has to be an explicit type (without data location specifier). +Inside contracts, you can also use ``*`` in place of the type (e.g. ``using L for *;``), +which has the effect that all functions of the library ``L`` +are attached to *all* types. + +If you specify a library, *all* non-private functions in the library get attached, +even those where the type of the first parameter does not +match the type of the object. The type is checked at the +point the function is called and function overload +resolution is performed. + +If you use a list of functions (e.g. ``using {f, g, h, L.t} for uint``), +then the type (``uint``) has to be implicitly convertible to the +first parameter of each of these functions. This check is +performed even if none of these functions are called. +Note that private library functions can only be specified when ``using for`` is inside a library. + +If you define an operator (e.g. ``using {f as +} for T``), then the type (``T``) must be a +:ref:`user-defined value type ` and the definition must be a ``pure`` function. +Operator definitions must be global. +The following operators can be defined this way: + ++------------+----------+---------------------------------------------+ +| Category | Operator | Possible signatures | ++============+==========+=============================================+ +| Bitwise | ``&`` | ``function (T, T) pure returns (T)`` | +| +----------+---------------------------------------------+ +| | ``|`` | ``function (T, T) pure returns (T)`` | +| +----------+---------------------------------------------+ +| | ``^`` | ``function (T, T) pure returns (T)`` | +| +----------+---------------------------------------------+ +| | ``~`` | ``function (T) pure returns (T)`` | ++------------+----------+---------------------------------------------+ +| Arithmetic | ``+`` | ``function (T, T) pure returns (T)`` | +| +----------+---------------------------------------------+ +| | ``-`` | ``function (T, T) pure returns (T)`` | +| + +---------------------------------------------+ +| | | ``function (T) pure returns (T)`` | +| +----------+---------------------------------------------+ +| | ``*`` | ``function (T, T) pure returns (T)`` | +| +----------+---------------------------------------------+ +| | ``/`` | ``function (T, T) pure returns (T)`` | +| +----------+---------------------------------------------+ +| | ``%`` | ``function (T, T) pure returns (T)`` | ++------------+----------+---------------------------------------------+ +| Comparison | ``==`` | ``function (T, T) pure returns (bool)`` | +| +----------+---------------------------------------------+ +| | ``!=`` | ``function (T, T) pure returns (bool)`` | +| +----------+---------------------------------------------+ +| | ``<`` | ``function (T, T) pure returns (bool)`` | +| +----------+---------------------------------------------+ +| | ``<=`` | ``function (T, T) pure returns (bool)`` | +| +----------+---------------------------------------------+ +| | ``>`` | ``function (T, T) pure returns (bool)`` | +| +----------+---------------------------------------------+ +| | ``>=`` | ``function (T, T) pure returns (bool)`` | ++------------+----------+---------------------------------------------+ + +Note that unary and binary ``-`` need separate definitions. +The compiler will choose the right definition based on how the operator is invoked. + +The ``using A for B;`` directive is active only within the current +scope (either the contract or the current module/source unit), +including within all of its functions, and has no effect +outside of the contract or module in which it is used. + +When the directive is used at file level and applied to a +user-defined type which was defined at file level in the same file, +the word ``global`` can be added at the end. This will have the +effect that the functions and operators are attached to the type everywhere +the type is available (including other files), not only in the +scope of the using statement. + +Let us rewrite the set example from the +:ref:`libraries` section in this way, using file-level functions +instead of library functions. +>>>>>>> english/develop .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.6.0 <0.9.0; + pragma solidity ^0.8.13; +<<<<<<< HEAD // Il s'agit du même code que précédemment, mais sans commentaires. +======= +>>>>>>> english/develop struct Data { mapping(uint => bool) flags; } + // Now we attach functions to the type. + // The attached functions can be used throughout the rest of the module. + // If you import the module, you have to + // repeat the using directive there, for example as + // import "flags.sol" as Flags; + // using {Flags.insert, Flags.remove, Flags.contains} + // for Flags.Data; + using {insert, remove, contains} for Data; +<<<<<<< HEAD library Set { function insert(Data storage self, uint value) public @@ -58,19 +170,39 @@ Réécrivons l'exemple de l'ensemble à partir de la directive self.flags[value] = false; return true; } +======= + function insert(Data storage self, uint value) + returns (bool) + { + if (self.flags[value]) + return false; // already there + self.flags[value] = true; + return true; + } - function contains(Data storage self, uint value) - public - view - returns (bool) - { - return self.flags[value]; - } + function remove(Data storage self, uint value) + returns (bool) + { + if (!self.flags[value]) + return false; // not there + self.flags[value] = false; + return true; + } +>>>>>>> english/develop + + function contains(Data storage self, uint value) + view + returns (bool) + { + return self.flags[value]; } contract C { +<<<<<<< HEAD using Set for Data; // c'est le changement crucial +======= +>>>>>>> english/develop Data knownValues; function register(uint value) public { @@ -82,12 +214,17 @@ Réécrivons l'exemple de l'ensemble à partir de la directive } } +<<<<<<< HEAD Il est également possible d'étendre les types élémentaires de cette manière : +======= +It is also possible to extend built-in types in that way. +In this example, we will use a library. +>>>>>>> english/develop .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.6.8 <0.9.0; + pragma solidity ^0.8.13; library Search { function indexOf(uint[] storage self, uint value) @@ -100,27 +237,75 @@ Il est également possible d'étendre les types élémentaires de cette manière return type(uint).max; } } + using Search for uint[]; contract C { - using Search for uint[]; uint[] data; function append(uint value) public { data.push(value); } +<<<<<<< HEAD function replace(uint _old, uint _new) public { // Cette opération effectue l'appel de la fonction de bibliothèque uint index = data.indexOf(_old); +======= + function replace(uint from, uint to) public { + // This performs the library function call + uint index = data.indexOf(from); +>>>>>>> english/develop if (index == type(uint).max) - data.push(_new); + data.push(to); else - data[index] = _new; + data[index] = to; } } +<<<<<<< HEAD Notez que tous les appels de bibliothèque externes sont des appels de fonction EVM réels. Cela signifie que si vous passez des types de mémoire ou de valeur, une copie sera effectuée, même de la variable ``self``. La seule situation où aucune copie ne sera effectuée est l'utilisation de variables de référence de stockage ou l'appel de fonctions de bibliothèque internes sont appelées. +======= +Note that all external library calls are actual EVM function calls. This means that +if you pass memory or value types, a copy will be performed, even in case of the +``self`` variable. The only situation where no copy will be performed +is when storage reference variables are used or when internal library +functions are called. + +Another example shows how to define a custom operator for a user-defined type: + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity ^0.8.19; + + type UFixed16x2 is uint16; + + using { + add as +, + div as / + } for UFixed16x2 global; + + uint32 constant SCALE = 100; + + function add(UFixed16x2 a, UFixed16x2 b) pure returns (UFixed16x2) { + return UFixed16x2.wrap(UFixed16x2.unwrap(a) + UFixed16x2.unwrap(b)); + } + + function div(UFixed16x2 a, UFixed16x2 b) pure returns (UFixed16x2) { + uint32 a32 = UFixed16x2.unwrap(a); + uint32 b32 = UFixed16x2.unwrap(b); + uint32 result32 = a32 * SCALE / b32; + require(result32 <= type(uint16).max, "Divide overflow"); + return UFixed16x2.wrap(uint16(a32 * SCALE / b32)); + } + + contract Math { + function avg(UFixed16x2 a, UFixed16x2 b) public pure returns (UFixed16x2) { + return (a + b) / UFixed16x2.wrap(200); + } + } +>>>>>>> english/develop diff --git a/docs/contracts/visibility-and-getters.rst b/docs/contracts/visibility-and-getters.rst index 2c10ff1fc3..21c09e259d 100644 --- a/docs/contracts/visibility-and-getters.rst +++ b/docs/contracts/visibility-and-getters.rst @@ -187,12 +187,12 @@ L'exemple suivant est plus complexe : struct Data { uint a; bytes3 b; - mapping (uint => uint) map; + mapping(uint => uint) map; uint[3] c; uint[] d; bytes e; } - mapping (uint => mapping(bool => Data[])) public data; + mapping(uint => mapping(bool => Data[])) public data; } Il génère une fonction de la forme suivante. Le mappage et les tableaux (à diff --git a/docs/contributing.rst b/docs/contributing.rst index 9eec402594..296a34b698 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -2,10 +2,15 @@ Contribution ############ +<<<<<<< HEAD L'aide est toujours la bienvenue et il existe de nombreuses possibilités de contribuer à Solidity. +======= +Help is always welcome and there are plenty of options to contribute to Solidity. +>>>>>>> english/develop En particulier, nous apprécions le soutien dans les domaines suivants : +<<<<<<< HEAD * Signaler les problèmes. * Corriger et répondre aux problèmes de `Solidity's GitHub issues. `_, en particulier ceux marqués comme @@ -15,6 +20,17 @@ En particulier, nous apprécions le soutien dans les domaines suivants : * Traduire la documentation dans plus de langues. * Répondre aux questions des autres utilisateurs sur `StackExchange `_ et le `Solidity Gitter Chat +======= +* Reporting issues. +* Fixing and responding to `Solidity's GitHub issues + `_, especially those tagged as + `"good first issue" `_ which are + meant as introductory issues for external contributors. +* Improving the documentation. +* `Translating `_ the documentation into more languages. +* Responding to questions from other users on `StackExchange + `_ and the `Solidity Gitter Chat +>>>>>>> english/develop `_. * S'impliquer dans le processus de conception du langage en proposant des changements de langage ou de nouvelles fonctionnalités sur le forum `Solidity `_ et en fournissant des commentaires. @@ -22,11 +38,16 @@ Pour commencer, vous pouvez essayer :ref:`building-from-source` afin de vous familiariser avec les composants de Solidity et le processus de construction. En outre, il peut être utile de vous familiariser avec l'écriture de contrats intelligents dans Solidity. +<<<<<<< HEAD Veuillez noter que ce projet est publié avec un `Code de conduite du contributeur `_. En participant à ce projet - dans les problèmes, les demandes de pull, ou les canaux Gitter - vous acceptez de respecter ses termes. +======= +Please note that this project is released with a `Contributor Code of Conduct `_. By participating in this project — in the issues, pull requests, or Gitter channels — you agree to abide by its terms. +>>>>>>> english/develop Appels de l'équipe ========== +<<<<<<< HEAD Si vous avez des problèmes ou des demandes de pull à discuter, ou si vous êtes intéressé à entendre ce sur quoi l'équipe et les contributeurs travaillent, vous pouvez rejoindre nos appels d'équipe publics : @@ -34,6 +55,14 @@ l'équipe et les contributeurs travaillent, vous pouvez rejoindre nos appels d' - Les mercredis à 14h CET/CEST. Les deux appels ont lieu sur `Jitsi `_. +======= +If you have issues or pull requests to discuss, or are interested in hearing what +the team and contributors are working on, you can join our public team call: + +- Wednesdays at 3PM CET/CEST. + +The call takes place on `Jitsi `_. +>>>>>>> english/develop Comment signaler des problèmes ==================== @@ -42,6 +71,7 @@ Pour signaler un problème, veuillez utiliser le `GitHub issues tracker `_. Lorsque rapportant des problèmes, veuillez mentionner les détails suivants : +<<<<<<< HEAD * Version de Solidity. * Code source (le cas échéant). * Système d'exploitation. @@ -50,6 +80,19 @@ rapportant des problèmes, veuillez mentionner les détails suivants : Il est toujours très utile de réduire au strict minimum le code source à l'origine du problème. Très utile et permet même parfois de clarifier un malentendu. +======= +* Solidity version. +* Source code (if applicable). +* Operating system. +* Steps to reproduce the issue. +* Actual vs. expected behavior. + +Reducing the source code that caused the issue to a bare minimum is always +very helpful, and sometimes even clarifies a misunderstanding. + +For technical discussions about language design, a post in the +`Solidity forum `_ is the correct place (see :ref:`solidity_language_design`). +>>>>>>> english/develop Flux de travail pour les demandes de Pull ========================== @@ -66,9 +109,15 @@ plus facilement. De plus, si vous écrivez une nouvelle fonctionnalité, veuillez vous assurer que vous ajoutez des tests appropriés sous ``test/`` (voir ci-dessous). +<<<<<<< HEAD Cependant, si vous effectuez un changement plus important, veuillez consulter le `canal Gitter du développement de Solidity `_ (différent de celui mentionné ci-dessus, celui-ci est axé sur le développement du compilateur et du langage plutôt que sur l'utilisation du langage) en premier lieu. +======= +However, if you are making a larger change, please consult with the `Solidity Development Gitter channel +`_ (different from the one mentioned above — this one is +focused on compiler and language development instead of language usage) first. +>>>>>>> english/develop Les nouvelles fonctionnalités et les corrections de bogues doivent être ajoutées au fichier ``Changelog.md`` : veuillez suivre le style des entrées précédentes, le cas échéant. @@ -78,7 +127,14 @@ Enfin, veillez à respecter le ``style de codage pour ce projet. De plus, même si nous effectuons des tests CI, veuillez tester votre code et assurez-vous qu'il se construit localement avant de soumettre une demande de pull. +<<<<<<< HEAD Merci pour votre aide ! +======= +We highly recommend going through our `review checklist `_ before submitting the pull request. +We thoroughly review every PR and will help you get it right, but there are many common problems that can be easily avoided, making the review much smoother. + +Thank you for your help! +>>>>>>> english/develop Exécution des tests du compilateur ========================== @@ -86,6 +142,7 @@ Exécution des tests du compilateur Conditions préalables ------------- +<<<<<<< HEAD Pour exécuter tous les tests du compilateur, vous pouvez vouloir installer facultativement quelques dépendances (`evmone `_, `libz3 `_, et @@ -95,28 +152,59 @@ Sur macOS, certains des scripts de test attendent que GNU coreutils soit install Ceci peut être accompli plus facilement en utilisant Homebrew : ``brew install coreutils``. Exécution des tests +======= +For running all compiler tests you may want to optionally install a few +dependencies (`evmone `_, +`libz3 `_). + +On macOS systems, some of the testing scripts expect GNU coreutils to be installed. +This can be easiest accomplished using Homebrew: ``brew install coreutils``. + +On Windows systems, make sure that you have a privilege to create symlinks, +otherwise several tests may fail. +Administrators should have that privilege, but you may also +`grant it to other users `_ +or +`enable Developer Mode `_. + +Running the Tests +>>>>>>> english/develop ----------------- Solidity inclut différents types de tests, la plupart d'entre eux étant regroupés dans l'application ``Boost C++ Test Framework``. `Boost C++ Test Framework `_ application ``soltest``. Exécuter ``build/test/soltest`` ou son wrapper ``scripts/soltest.sh`` est suffisant pour la plupart des modifications. +<<<<<<< HEAD Le script `./scripts/tests.sh`` exécute automatiquement la plupart des tests Solidity, y compris ceux inclus dans le `Boost C++ Test Framework `_ l'application ``soltest`` (ou son enveloppe ``scripts/soltest.sh``), ainsi que les tests en ligne de commande et les tests de compilation. +======= +The ``./scripts/tests.sh`` script executes most Solidity tests automatically, +including those bundled into the `Boost C++ Test Framework `_ +application ``soltest`` (or its wrapper ``scripts/soltest.sh``), as well as command-line tests and +compilation tests. +>>>>>>> english/develop Le système de test essaie automatiquement de découvrir l'emplacement du `evmone `_ pour exécuter les tests sémantiques. +<<<<<<< HEAD La bibliothèque ``evmone`` doit être située dans le répertoire ``deps`` ou ``deps/lib`` relativement au répertoire de travail actuel, à son parent ou au parent de son parent. Alternativement, un emplacement explicite pour l'objet partagé ``evmone`` peut être spécifié via la variable d'environnement ``ETH_EVMONE``. +======= +The ``evmone`` library must be located in the ``deps`` or ``deps/lib`` directory relative to the +current working directory, to its parent or its parent's parent. Alternatively, an explicit location +for the ``evmone`` shared object can be specified via the ``ETH_EVMONE`` environment variable. +>>>>>>> english/develop ``evmone`` est principalement nécessaire pour l'exécution de tests sémantiques et de gaz. Si vous ne l'avez pas installé, vous pouvez ignorer ces tests en passant l'option ``--no-semantic-tests`` à ``scripts/soltest.sh``. +<<<<<<< HEAD L'exécution des tests Ewasm est désactivée par défaut et peut être explicitement activée via ``./scripts/soltest.sh --ewasm`` et nécessite que `hera `_ soit trouvé par ``soltest.sh``. Pour être trouvé par ``soltest``. @@ -125,6 +213,10 @@ variable permettant de spécifier un emplacement explicite est appelée ``ETH_HE Les bibliothèques ``evmone`` et ``hera`' doivent toutes deux se terminer par l'extension de fichier avec l'extension ``.so`` sur Linux, ``.dll`` sur les systèmes Windows et ``.dylib`` sur macOS. +======= +The ``evmone`` library should both end with the file name +extension ``.so`` on Linux, ``.dll`` on Windows systems and ``.dylib`` on macOS. +>>>>>>> english/develop Pour exécuter les tests SMT, la bibliothèque ``libz3`` doit être installée et localisable par ``cmake`` pendant l'étape de configuration du compilateur. @@ -161,8 +253,14 @@ Voir en particulier : sans libz3. En utilisant Git Bash, vous utilisez : ``./build/test/Release/soltest.exe -- --no-smt``. Si vous exécutez ceci dans une Invite de Commande simple, utilisez : ``./build/test/Release/soltest.exe -- --no-smt``. +<<<<<<< HEAD Si vous voulez déboguer à l'aide de GDB, assurez-vous que vous construisez différemment de ce qui est "habituel". Par exemple, vous pouvez exécuter la commande suivante dans votre dossier ``build`` : +======= +If you want to debug using GDB, make sure you build differently than the "usual". +For example, you could run the following command in your ``build`` folder: + +>>>>>>> english/develop .. code-block:: bash cmake -DCMAKE_BUILD_TYPE=Debug .. @@ -233,12 +331,21 @@ un moyen de modifier, de mettre à jour ou d'ignorer le fichier de contrat actue Il offre plusieurs options pour les tests qui échouent : +<<<<<<< HEAD - ``edit`` : ``isoltest`` essaie d'ouvrir le contrat dans un éditeur pour que vous puissiez l'ajuster. Il utilise soit l'éditeur donné sur la ligne de commande (comme ``isoltest --editor /path/to/editor``), dans la variable d'environnement ``EDITOR`` ou juste ``/usr/bin/editor`` (dans cet ordre). - ``update`` : Met à jour les attentes pour le contrat en cours de test. Cela met à jour les annotations en supprimant les attentes non satisfaites et en ajoutant les attentes manquantes. Le test est ensuite exécuté à nouveau. - ``skip`` : Ignore l'exécution de ce test particulier. - ``quit'' : Quitte ``isoltest``. Toutes ces options s'appliquent au contrat en cours, à l'exception de ``quit`` qui arrête l'ensemble du processus de test. +======= +- ``edit``: ``isoltest`` tries to open the contract in an editor so you can adjust it. It either uses the editor given on the command-line (as ``isoltest --editor /path/to/editor``), in the environment variable ``EDITOR`` or just ``/usr/bin/editor`` (in that order). +- ``update``: Updates the expectations for contract under test. This updates the annotations by removing unmet expectations and adding missing expectations. The test is then run again. +- ``skip``: Skips the execution of this particular test. +- ``quit``: Quits ``isoltest``. + +All of these options apply to the current contract, except ``quit`` which stops the entire testing process. +>>>>>>> english/develop La mise à jour automatique du test ci-dessus le change en @@ -263,6 +370,62 @@ et relancez le test. Il passe à nouveau : Ne mettez pas plus d'un contrat dans un seul fichier, sauf si vous testez l'héritage ou les appels croisés de contrats. Chaque fichier doit tester un aspect de votre nouvelle fonctionnalité. +Command-line Tests +------------------ + +Our suite of end-to-end command-line tests checks the behaviour of the compiler binary as a whole +in various scenarios. +These tests are located in `test/cmdlineTests/ `_, +one per subdirectory, and can be executed using the ``cmdlineTests.sh`` script. + +By default the script runs all available tests. +You can also provide one or more `file name patterns `_, +in which case only the tests matching at least one pattern will be executed. +It is also possible to exclude files matching a specific pattern by prefixing it with ``--exclude``. + +By default the script assumes that a ``solc`` binary is available inside the ``build/`` subdirectory +inside the working copy. +If you build the compiler outside of the source tree, you can use the ``SOLIDITY_BUILD_DIR`` environment +variable to specify a different location for the build directory. + +Example: + +.. code-block:: bash + + export SOLIDITY_BUILD_DIR=~/solidity/build/ + test/cmdlineTests.sh "standard_*" "*_yul_*" --exclude "standard_yul_*" + +The commands above will run tests from directories starting with ``test/cmdlineTests/standard_`` and +subdirectories of ``test/cmdlineTests/`` that have ``_yul_`` somewhere in the name, +but no test whose name starts with ``standard_yul_`` will be executed. +It will also assume that the file ``solidity/build/solc/solc`` inside your home directory is the +compiler binary (unless you are on Windows -- then ``solidity/build/solc/Release/solc.exe``). + +There are several kinds of command-line tests: + +- *Standard JSON test*: contains at least an ``input.json`` file. + In general may contain: + + - ``input.json``: input file to be passed to the ``--standard-json`` option on the command line. + - ``output.json``: expected Standard JSON output. + - ``args``: extra command-line arguments passed to ``solc``. + +- *CLI test*: contains at least an ``input.*`` file (other than ``input.json``). + In general may contain: + + - ``input.*``: a single input file, whose name will be supplied to ``solc`` on the command line. + Usually ``input.sol`` or ``input.yul``. + - ``args``: extra command-line arguments passed to ``solc``. + - ``stdin``: content to be passed to ``solc`` via standard input. + - ``output``: expected content of the standard output. + - ``err``: expected content of the standard error output. + - ``exit``: expected exit code. If not provided, zero is expected. + +- *Script test*: contains a ``test.*`` file. + In general may contain: + + - ``test.*``: a single script to run, usually ``test.sh`` or ``test.py``. + The script must be executable. Exécution du Fuzzer via AFL ========================== @@ -285,7 +448,11 @@ Ensuite, construisez Solidity (ou juste le binaire ``solfuzzer``) avec AFL comme cmake .. -DCMAKE_C_COMPILER=path/to/afl-gcc -DCMAKE_CXX_COMPILER=path/to/afl-g++ make solfuzzer +<<<<<<< HEAD À ce stade, vous devriez pouvoir voir un message similaire à celui qui suit : +======= +At this stage, you should be able to see a message similar to the following: +>>>>>>> english/develop .. code-block:: text @@ -340,11 +507,19 @@ de la documentation ou des autres tests : # extract from documentation: path/to/solidity/scripts/isolate_tests.py path/to/solidity/docs +<<<<<<< HEAD La documentation de l'AFL indique que le corpus (les fichiers d'entrée initiaux) ne doit pas être trop volumineux. Les fichiers eux-mêmes ne devraient pas être plus grands que 1 kB et il devrait y avoir au maximum un fichier d'entrée par fonctionnalité, donc mieux vaut commencer avec un petit nombre de fichiers. Il existe également un outil appelé ``afl-cmin`` qui peut couper les fichiers d'entrée qui ont pour résultat un comportement similaire du binaire. +======= +The AFL documentation states that the corpus (the initial input files) should not be +too large. The files themselves should not be larger than 1 kB and there should be +at most one input file per functionality, so better start with a small number of. +There is also a tool called ``afl-cmin`` that can trim input files +that result in similar behavior of the binary. +>>>>>>> english/develop Maintenant, lancez le fuzzer (le ``-m`` étend la taille de la mémoire à 60 Mo) : @@ -391,6 +566,7 @@ des contributions à Solidity. Langue anglaise ---------------- +<<<<<<< HEAD Utilisez l'anglais, avec une préférence pour l'orthographe anglaise britannique, sauf si vous utilisez des noms de projets ou de marques. Essayez de réduire l'utilisation de l'argot et les références locales, en rendant votre langage aussi clair que possible pour tous les lecteurs. Vous trouverez ci-dessous quelques références pour vous aider : @@ -405,6 +581,20 @@ Vous trouverez ci-dessous quelques références pour vous aider : Bien que la documentation officielle de Solidity soit écrite en anglais, il existe des :ref:`traductions` contribuées par la communauté dans d'autres langues. dans d'autres langues sont disponibles. Veuillez vous référer au `guide de traduction `_ pour savoir comment contribuer aux traductions de la communauté. +======= +Use International English, unless using project or brand names. Try to reduce the usage of +local slang and references, making your language as clear to all readers as possible. +Below are some references to help: + +* `Simplified technical English `_ +* `International English `_ + +.. note:: + + While the official Solidity documentation is written in English, there are community contributed :ref:`translations` + in other languages available. Please refer to the `translation guide `_ + for information on how to contribute to the community translations. +>>>>>>> english/develop Cas de titre pour les en-têtes ----------------------- @@ -469,6 +659,7 @@ Par exemple, ``pragma solidity >=0.4.0 <0.9.0;``. Exécution des Tests de Documentation --------------------------- +<<<<<<< HEAD Assurez-vous que vos contributions passent nos tests de documentation en exécutant ``./scripts/docs.sh`` qui installe les dépendances nécessaires à la documentation et vérifie les problèmes éventuels. Nécessaires à la documentation et vérifie l'absence de problèmes tels que des liens brisés ou des problèmes de syntaxe. @@ -477,6 +668,18 @@ Conception du langage Solidity Pour vous impliquer activement dans le processus de conception du langage et partager vos idées concernant l'avenir de Solidity, veuillez rejoindre le `forum Solidity `_. +======= +Make sure your contributions pass our documentation tests by running ``./docs/docs.sh`` that installs dependencies +needed for documentation and checks for any problems such as broken links or syntax issues. + +.. _solidity_language_design: + +Solidity Language Design +======================== + +To actively get involved in the language design process and to share your ideas concerning the future of Solidity, +please join the `Solidity forum `_. +>>>>>>> english/develop Le forum Solidity sert de lieu pour proposer et discuter de nouvelles fonctionnalités du langage et de leur mise en œuvre dans les premiers stades de l'idéation ou des modifications de fonctionnalités existantes. @@ -494,7 +697,12 @@ Si vous voulez savoir où en est l'équipe en termes d'implémentation de nouvel Les questions dans le backlog de conception nécessitent une spécification plus approfondie et seront soit discutées dans un appel de conception de langue ou dans un appel d'équipe régulier. Vous pouvez voir les changements à venir pour la prochaine version de rupture en passant de la branche par défaut (`develop`) à la `breaking branch `_. +<<<<<<< HEAD Pour les cas particuliers et les questions, vous pouvez nous contacter via le canal `Solidity-dev Gitter `_, un chatroom dédié aux conversations autour du compilateur Solidity et du développement du langage. +======= +For ad-hoc cases and questions, you can reach out to us via the `Solidity-dev Gitter channel `_ — a +dedicated chatroom for conversations around the Solidity compiler and language development. +>>>>>>> english/develop Nous sommes heureux d'entendre vos réflexions sur la façon dont nous pouvons améliorer le processus de conception du langage pour qu'il soit encore plus collaboratif et transparent. diff --git a/docs/control-structures.rst b/docs/control-structures.rst index b7af62251a..590ec2a537 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -150,8 +150,13 @@ lève une exception ou tombe en panne. utiliser "f.value(x).gas(g)()``. Cette méthode a été dépréciée dans Solidity 0.6.2 et n'est plus possible depuis Solidity 0.7.0. +<<<<<<< HEAD Appels nominatifs et paramètres de fonctions anonymes --------------------------------------------- +======= +Function Calls with Named Parameters +------------------------------------ +>>>>>>> english/develop Les arguments d'un appel de fonction peuvent être donnés par leur nom, dans n'importe quel ordre, s'ils sont entourés de ``{ }`` comme on peut le voir dans @@ -173,14 +178,23 @@ paramètres de la déclaration de la fonction, mais peut être dans un ordre arb function set(uint key, uint value) public { data[key] = value; } - } +<<<<<<< HEAD Noms des paramètres de la fonction omise -------------------------------- Les noms des paramètres non utilisés (en particulier les paramètres de retour) peuvent être omis. Ces paramètres seront toujours présents sur la pile, mais ils seront inaccessibles. +======= +Omitted Names in Function Definitions +------------------------------------- + +The names of parameters and return values in the function declaration can be omitted. +Those items with omitted names will still be present on the stack, but they are +inaccessible by name. An omitted return value name +can still return a value to the caller by use of the ``return`` statement. +>>>>>>> english/develop .. code-block:: solidity @@ -284,7 +298,7 @@ qui n'ont besoin d'être créés que s'il y a un différend. salt, keccak256(abi.encodePacked( type(D).creationCode, - arg + abi.encode(arg) )) ))))); @@ -363,16 +377,27 @@ Par exemple, l'exemple suivant n'est pas valide : ``(x, uint y) = (1, 2);`` maintenant interdit, donc les deux côtés doivent avoir le même nombre de composants. .. warning:: +<<<<<<< HEAD Soyez prudent lorsque vous assignez à plusieurs variables en même temps lorsque des types de référence sont impliqués, car cela pourrait conduire à un comportement de copie inattendu. +======= + Be careful when assigning to multiple variables at the same time when + reference types are involved, because it could lead to unexpected + copying behavior. +>>>>>>> english/develop Complications pour les tableaux et les structures ------------------------------------ +<<<<<<< HEAD La sémantique des affectations est plus compliquée pour les types non-valeurs comme les tableaux et les structs, y compris les ``octets`` et les ``chaînes``, voir :ref:`L'emplacement des données et le comportement d'affectation ` pour plus de détails. +======= +The semantics of assignments are more complicated for non-value types like arrays and structs, +including ``bytes`` and ``string``, see :ref:`Data location and assignment behavior ` for details. +>>>>>>> english/develop Dans l'exemple ci-dessous, l'appel à ``g(x)`` n'a aucun effet sur ``x`` parce qu'il crée une copie indépendante de la valeur de stockage en mémoire. Cependant, ``h(x)`` modifie avec succès ``x`` @@ -510,7 +535,11 @@ vérifications supplémentaires. Depuis la version 0.8.0 de Solidity, toutes les opérations arithmétiques s'inversent par défaut en cas de dépassement inférieur ou supérieur, rendant ainsi inutile l'utilisation de ces bibliothèques. +<<<<<<< HEAD Pour obtenir le comportement précédent, un bloc ``unchecked`` peut être utilisé : +======= +To obtain the previous behavior, an ``unchecked`` block can be used: +>>>>>>> english/develop .. code-block:: solidity @@ -647,9 +676,15 @@ par le compilateur dans les situations suivantes : modificateur ``payable`` (y compris le constructeur et la fonction de repli). #. Si votre contrat reçoit de l'Ether via une fonction publique getter. +<<<<<<< HEAD Dans les cas suivants, les données d'erreur de l'appel externe (s'il est fourni) sont transférées. Cela signifie qu'il peut soit causer une `Error` ou une `Panic` (ou toute autre donnée) : +======= +For the following cases, the error data from the external call +(if provided) is forwarded. This means that it can either cause +an ``Error`` or a ``Panic`` (or whatever else was given): +>>>>>>> english/develop #. Si un ``.transfer()`` échoue. #. Si vous appelez une fonction via un appel de message mais qu'elle @@ -682,9 +717,15 @@ et ``assert`` pour vérifier les erreurs internes. require(msg.value % 2 == 0, "Even value required."); uint balanceBeforeTransfer = address(this).balance; addr.transfer(msg.value / 2); +<<<<<<< HEAD // Puisque le transfert lève une exception en cas d'échec et que // ne peut pas rappeler ici, il ne devrait pas y avoir de moyen pour nous // d'avoir encore la moitié de l'argent. +======= + // Since transfer throws an exception on failure and + // cannot call back here, there should be no way for us to + // still have half of the Ether. +>>>>>>> english/develop assert(address(this).balance == balanceBeforeTransfer - msg.value / 2); return address(this).balance; } @@ -717,8 +758,13 @@ L'instruction ``revert`` prend une erreur personnalisée comme argument direct s revert CustomError(arg1, arg2) ; +<<<<<<< HEAD Pour des raisons de rétrocompatibilité, il existe également la fonction ``revert()``, qui utilise des parenthèses et accepte une chaîne de caractères : +======= +For backward-compatibility reasons, there is also the ``revert()`` function, which uses parentheses +and accepts a string: +>>>>>>> english/develop revert() ; revert("description") ; diff --git a/docs/docs.sh b/docs/docs.sh new file mode 100755 index 0000000000..f2c5667612 --- /dev/null +++ b/docs/docs.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +#------------------------------------------------------------------------------ +# Bash script to build the Solidity Sphinx documentation locally. +# +# The documentation for solidity is hosted at: +# +# https://docs.soliditylang.org +# +# ------------------------------------------------------------------------------ +# This file is part of solidity. +# +# solidity is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# solidity is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with solidity. If not, see +# +# (c) 2016 solidity contributors. +#------------------------------------------------------------------------------ + +set -euo pipefail + +script_dir="$(dirname "$0")" + +cd "${script_dir}" +pip3 install -r requirements.txt --upgrade --upgrade-strategy eager +sphinx-build -nW -b html -d _build/doctrees . _build/html diff --git a/docs/examples/blind-auction.rst b/docs/examples/blind-auction.rst index ffe596d6b2..ab2a46e65e 100644 --- a/docs/examples/blind-auction.rst +++ b/docs/examples/blind-auction.rst @@ -15,10 +15,19 @@ où il n'est pas possible de voir l'offre réelle jusqu'à la fin de la période Simple Enchères =================== +<<<<<<< HEAD L'idée générale d'une enchères est que chacun peut envoyer ses offres pendant une période d'enchères. Les offres doivent comprendre avec l'envoi un certain nombre Ether pour valider leur enchère. Si l'offre la plus élevée est augmentée, le précédent enchérisseur le plus élevé récupère son argent. Après la fin de la période d'enchères, le contrat doit être appelé manuellement pour que le bénéficiaire reçoive son argent - les contrats ne peuvent pas s'activer eux-mêmes. +======= +The general idea of the following simple auction contract is that everyone can +send their bids during a bidding period. The bids already include sending some compensation, +e.g. Ether, in order to bind the bidders to their bid. If the highest bid is +raised, the previous highest bidder gets their Ether back. After the end of +the bidding period, the contract has to be called manually for the beneficiary +to receive their Ether - contracts cannot activate themselves. +>>>>>>> english/develop .. code-block:: solidity @@ -89,19 +98,35 @@ Après la fin de la période d'enchères, le contrat doit être appelé manuelle if (block.timestamp > auctionEndTime) revert AuctionAlreadyEnded(); +<<<<<<< HEAD // Si l'enchère n'est pas plus élevée, le // remboursement est envoyé // ("revert" annulera tous les changements incluant // l'argent reçu, qui sera automatiquement renvoyer au propriétaire). +======= + // If the bid is not higher, send the + // Ether back (the revert statement + // will revert all changes in this + // function execution including + // it having received the Ether). +>>>>>>> english/develop if (msg.value <= highestBid) revert BidNotHighEnough(highestBid); if (highestBid != 0) { +<<<<<<< HEAD // Renvoyer l'argent en utilisant simplement // "mostbidder.send(highestBid)" est un risque de sécurité // car il ça pourrait exécuter un contrat non fiable. // Il est toujours plus sûr de laisser les destinataires // retirer leur argent eux-mêmes. +======= + // Sending back the Ether by simply using + // highestBidder.send(highestBid) is a security risk + // because it could execute an untrusted contract. + // It is always safer to let the recipients + // withdraw their Ether themselves. +>>>>>>> english/develop pendingReturns[highestBidder] += highestBid; } highestBidder = msg.sender; @@ -172,6 +197,7 @@ Nous allons maintenant étendre ce contract à une enchère à l'aveugle. L'avantage d'une enchère à l'aveugle c'est qu'il n'y a pas de pression temporelle vers la fin de la période d'enchère. La création d'une enchère à l'aveugle sur une plateforme transparente peut sembler contradictoire, mais la cryptographie vient à la rescousse. +<<<<<<< HEAD Pendant la **période d'enchère**, un enchérisseur n'envoie pas réellement son offre, mais seulement une version hachée de celle-ci. Étant donné qu'il est actuellement considéré comme pratiquement impossible de trouver deux valeurs (suffisamment longues) dont les hash sont égales, l'enchérisseur s'engage à faire son offre par ce biais. À la fin de la période d'enchères, les enchérisseurs doivent révéler leurs offres : Ils envoient leurs valeurs non cryptées et le contrat vérifie que le hash est le même que celui fournie pendant la période d'enchères. @@ -179,6 +205,27 @@ Pendant la **période d'enchère**, un enchérisseur n'envoie pas réellement so Un autre défi est de savoir comment rendre l'enchère **liante et aveugle** en même temps. La seule façon d'empêcher l'enchérisseur de ne pas envoyer l'argent après avoir remporté l'enchère après avoir remporté l'enchère est de l'obliger à l'envoyer en même temps que l'offre. Puisque les transferts de valeur ne peuvent pas être censurée dans Ethereum, tout le monde peut voir leur valeur. +======= +During the **bidding period**, a bidder does not actually send their bid, but +only a hashed version of it. Since it is currently considered practically +impossible to find two (sufficiently long) values whose hash values are equal, +the bidder commits to the bid by that. After the end of the bidding period, +the bidders have to reveal their bids: They send their values unencrypted, and +the contract checks that the hash value is the same as the one provided during +the bidding period. + +Another challenge is how to make the auction **binding and blind** at the same +time: The only way to prevent the bidder from just not sending the Ether after +they won the auction is to make them send it together with the bid. Since value +transfers cannot be blinded in Ethereum, anyone can see the value. + +The following contract solves this problem by accepting any value that is +larger than the highest bid. Since this can of course only be checked during +the reveal phase, some bids might be **invalid**, and this is on purpose (it +even provides an explicit flag to place invalid bids with high-value +transfers): Bidders can confuse competition by placing several high or low +invalid bids. +>>>>>>> english/develop Le contrat suivant résout ce problème en acceptant toute valeur qui est supérieure à l'offre la plus élevée. Puisque cela ne peut bien sûr être vérifié que pendant la phase de révélation, certaines offres peuvent être **invalides**, diff --git a/docs/examples/micropayment.rst b/docs/examples/micropayment.rst index 0c702970ef..5dbd67f54d 100644 --- a/docs/examples/micropayment.rst +++ b/docs/examples/micropayment.rst @@ -2,11 +2,19 @@ Canal de micropaiement ******************** +<<<<<<< HEAD Dans cette section, nous allons apprendre à construire un exemple d'implémentation d'un canal de paiement. Il utilisera des signatures cryptographiques pour faire des transferts répétés d'Ether entre les mêmes parties sécurisés, instantanés et sans frais de transaction. Pour l'exemple, nous devons comprendre comment signer et vérifier les signatures, et configurer le canal de paiement. +======= +In this section, we will learn how to build an example implementation +of a payment channel. It uses cryptographic signatures to make +repeated transfers of Ether between the same parties secure, instantaneous, and +without transaction fees. For the example, we need to understand how to +sign and verify signatures, and setup the payment channel. +>>>>>>> english/develop Création et vérification de signatures ================================= @@ -17,28 +25,52 @@ Alice est l'expéditeur et Bob est le destinataire. Alice n'a besoin que d'envoyer des messages signés cryptographiquement off-chain (exemple: par e-mail) à Bob et c'est similaire à la rédaction de chèques. +<<<<<<< HEAD Alice et Bob utilisent des signatures pour autoriser les transactions, ce qui est possible avec les Smart Contract d'Ethereum. Alice construira un simple Smart Contract qui lui permettra de transmettre Ether, mais au lieu d'appeler elle-même une fonction pour initier un paiement, elle laissera Bob le faire, qui paiera donc les frais de transaction. +======= +Alice and Bob use signatures to authorize transactions, which is possible with smart contracts on Ethereum. +Alice will build a simple smart contract that lets her transmit Ether, but instead of calling a function herself +to initiate a payment, she will let Bob do that, and therefore pay the transaction fee. +>>>>>>> english/develop Le contrat fonctionnera comme ça: +<<<<<<< HEAD 1. Alice déploie le contrat ``ReceiverPays``, avec suffisamment d'Ether pour couvrir les paiements qui seront effectués. 2. Alice autorise un paiement en signant un message avec sa clé privée. 3. Alice envoie le message signé cryptographiquement à Bob. Le message n'a pas besoin d'être gardé secret (expliqué plus loin), et le mécanisme pour l'envoyer n'a pas d'importance. 4. Bob réclame son paiement en présentant le message signé au smart contract, celui-ci vérifie le l'authenticité du message, puis débloque les fonds. +======= + 1. Alice deploys the ``ReceiverPays`` contract, attaching enough Ether to cover the payments that will be made. + 2. Alice authorizes a payment by signing a message with her private key. + 3. Alice sends the cryptographically signed message to Bob. The message does not need to be kept secret + (explained later), and the mechanism for sending it does not matter. + 4. Bob claims his payment by presenting the signed message to the smart contract, it verifies the + authenticity of the message and then releases the funds. +>>>>>>> english/develop Création de la signature: ---------------------- +<<<<<<< HEAD Alice n'a pas besoin d'interagir avec le réseau Ethereum pour signer la transaction, le processus est complètement hors ligne. Dans ce tutoriel, nous allons signer des messages dans le navigateur en utilisant `web3.js `_ et `MetaMask `_, avec la methode decrite dans l'`EIP-712 `_, car il offre un certain nombre d'autres avantages en matière de sécurité. +======= +Alice does not need to interact with the Ethereum network +to sign the transaction, the process is completely offline. +In this tutorial, we will sign messages in the browser +using `web3.js `_ and +`MetaMask `_, using the method described in `EIP-712 `_, +as it provides a number of other security benefits. +>>>>>>> english/develop .. code-block:: javascript @@ -83,12 +115,21 @@ du contrat complet à la fin de cette section. Packing arguments ----------------- +<<<<<<< HEAD Maintenant que nous avons identifié les informations à inclure dans le message signé, nous sommes prêts à construire le message, à le hacher et à le signer. Par question de simplicité, nous concaténons les données. Le `ethereumjs-abi `_ fournit une fonction appelée ``soliditySHA3`` qui imite le comportement de la fonction ``keccak256`` de Solidity en appliquant aux arguments encodés la fonction ``abi.encodePacked``. Voici une fonction JavaScript qui crée la bonne signature pour l'exemple ``ReceiverPays`` : +======= +Now that we have identified what information to include in the signed message, +we are ready to put the message together, hash it, and sign it. For simplicity, +we concatenate the data. The `ethereumjs-abi `_ +library provides a function called ``soliditySHA3`` that mimics the behavior of +Solidity's ``keccak256`` function applied to arguments encoded using ``abi.encodePacked``. +Here is a JavaScript function that creates the proper signature for the ``ReceiverPays`` example: +>>>>>>> english/develop .. code-block:: javascript @@ -144,6 +185,7 @@ Le contrat complet // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; + // This will report a warning due to deprecated selfdestruct contract ReceiverPays { address owner = msg.sender; @@ -258,8 +300,13 @@ Les messages sont signés cryptographiquement par l'expéditeur, puis transmis d Chaque message comprend les informations suivantes : +<<<<<<< HEAD * L'adresse du Smart Contract, utilisée pour empêcher les attaques de relecture de contrats croisés. * Le montant total d'Ether qui est dû au destinataire jusqu'à présent. +======= + * The smart contract's address, used to prevent cross-contract replay attacks. + * The total amount of Ether that is owed to the recipient so far. +>>>>>>> english/develop Un canal de paiement n'est fermé qu'une seule fois, à la fin d'une série de virements. Pour cette raison, seul un des messages envoyés est racheté. C'est pourquoi @@ -341,6 +388,7 @@ Le contrat complet // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; + // This will report a warning due to deprecated selfdestruct contract SimplePaymentChannel { address payable public sender; // The account sending payments. address payable public recipient; // The account receiving the payments. diff --git a/docs/examples/modular.rst b/docs/examples/modular.rst index 8b5ad227c8..24efdc2f81 100644 --- a/docs/examples/modular.rst +++ b/docs/examples/modular.rst @@ -4,6 +4,7 @@ Contrats modulaires (Librairie) ***************** +<<<<<<< HEAD Une approche modulaire de la construction de vos contrats vous aide à réduire la complexité et améliorer la lisibilité ce qui aidera à identifier les bugs et les vulnérabilités pendant le développement et la relecture de code. @@ -16,6 +17,20 @@ les adresses correspondent à ce que vous attendez. Ainsi, la `library` ``Balanc fournit un composant isolé des contrats qui suit correctement les soldes des comptes. Il est facile de vérifier que la `library` ``Balances`` ne produise jamais de soldes négatifs ou de débordements grâce au terme ``require()`` De ce faites, la somme de tous les soldes est un invariant sur la durée de vie du contrat. +======= +A modular approach to building your contracts helps you reduce the complexity +and improve the readability which will help to identify bugs and vulnerabilities +during development and code review. +If you specify and control the behavior of each module in isolation, the +interactions you have to consider are only those between the module specifications +and not every other moving part of the contract. +In the example below, the contract uses the ``move`` method +of the ``Balances`` :ref:`library ` to check that balances sent between +addresses match what you expect. In this way, the ``Balances`` library +provides an isolated component that properly tracks balances of accounts. +It is easy to verify that the ``Balances`` library never produces negative balances or overflows +and the sum of all balances is an invariant across the lifetime of the contract. +>>>>>>> english/develop .. code-block:: solidity @@ -34,7 +49,7 @@ De ce faites, la somme de tous les soldes est un invariant sur la durée de vie contract Token { mapping(address => uint256) balances; using Balances for *; - mapping(address => mapping (address => uint256)) allowed; + mapping(address => mapping(address => uint256)) allowed; event Transfer(address from, address to, uint amount); event Approval(address owner, address spender, uint amount); diff --git a/docs/examples/safe-remote.rst b/docs/examples/safe-remote.rst index 8c9030b49f..f53580c1a8 100644 --- a/docs/examples/safe-remote.rst +++ b/docs/examples/safe-remote.rst @@ -4,6 +4,7 @@ Achat à distance sécurisé ******************** +<<<<<<< HEAD L'achat de biens à distance nécessite actuellement plusieurs parties qui doivent se faire confiance. La configuration la plus simple implique un vendeur et un acheteur. L'acheteur souhaite recevoir un article du vendeur et le vendeur souhaite obtenir de l'argent (ou un équivalent) @@ -18,6 +19,22 @@ l'acheteur reçoit la valeur (la moitié de son acompte) et le vendeur reçoit t fois la valeur (leur dépôt plus la valeur). L'idée derrière c'est que les deux parties ont une incitation à résoudre la situation ou autrement leur argent est verrouillé pour toujours. +======= +Purchasing goods remotely currently requires multiple parties that need to trust each other. +The simplest configuration involves a seller and a buyer. The buyer would like to receive +an item from the seller and the seller would like to get some compensation, e.g. Ether, +in return. The problematic part is the shipment here: There is no way to determine for +sure that the item arrived at the buyer. + +There are multiple ways to solve this problem, but all fall short in one or the other way. +In the following example, both parties have to put twice the value of the item into the +contract as escrow. As soon as this happened, the Ether will stay locked inside +the contract until the buyer confirms that they received the item. After that, +the buyer is returned the value (half of their deposit) and the seller gets three +times the value (their deposit plus the value). The idea behind +this is that both parties have an incentive to resolve the situation or otherwise +their Ether is locked forever. +>>>>>>> english/develop Bien entendu, ce contrat ne résout pas le problème, mais donne un aperçu de la manière dont vous pouvez utiliser des constructions de type machine d'état dans un contrat. diff --git a/docs/examples/voting.rst b/docs/examples/voting.rst index 2adb6b1351..5c29228bee 100644 --- a/docs/examples/voting.rst +++ b/docs/examples/voting.rst @@ -108,9 +108,14 @@ de suffrages. function delegate(address to) external { // attribue une référence Voter storage sender = voters[msg.sender]; +<<<<<<< HEAD require(!sender.voted, "Vous avez déjà voté."); require(to != msg.sender, "L'autodélégation est interdite."); +======= + require(sender.weight != 0, "You have no right to vote"); + require(!sender.voted, "You already voted."); +>>>>>>> english/develop // Transférer la délégation tant que // `to` également délégué. @@ -127,11 +132,21 @@ de suffrages. require(to != msg.sender, "Found loop in delegation."); } +<<<<<<< HEAD // Puisque `sender` est une référence, cela // modifie `voters[msg.sender].voted` +======= + Voter storage delegate_ = voters[to]; + + // Voters cannot delegate to accounts that cannot vote. + require(delegate_.weight >= 1); + + // Since `sender` is a reference, this + // modifies `voters[msg.sender]`. +>>>>>>> english/develop sender.voted = true; sender.delegate = to; - Voter storage delegate_ = voters[to]; + if (delegate_.voted) { // Si le délégué a déjà voté, // ajouter directement au nombre de votes @@ -188,5 +203,13 @@ de suffrages. Améliorations possibles ===================== +<<<<<<< HEAD Actuellement, de nombreuses transactions sont nécessaires pour céder les droits de voter à tous les participants. Pouvez-vous penser à une meilleure façon? +======= +Currently, many transactions are needed to +assign the rights to vote to all participants. +Moreover, if two or more proposals have the same +number of votes, ``winningProposal()`` is not able +to register a tie. Can you think of a way to fix these issues? +>>>>>>> english/develop diff --git a/docs/ext/remix_code_links.py b/docs/ext/remix_code_links.py index 11ce63a9fd..6c56e8db70 100644 --- a/docs/ext/remix_code_links.py +++ b/docs/ext/remix_code_links.py @@ -21,23 +21,16 @@ def insert_node_before(child, new_sibling): def remix_code_url(source_code, language, solidity_version): # NOTE: Les données encodées en base64 peuvent contenir les caractères +, = et /. Remix semble bien les gérer sans erreurs base64_encoded_source = base64.b64encode(source_code.encode('utf-8')).decode('ascii') - return f"https://remix.ethereum.org/?language={language}&version={solidity_version}&code={base64_encoded_source}" + return f"https://remix.ethereum.org/?#language={language}&version={solidity_version}&code={base64_encoded_source}" def build_remix_link_node(url): - link_icon_node = docutils.nodes.inline() - link_icon_node.set_class('link-icon') - - link_text_node = docutils.nodes.inline(text="open in Remix") - link_text_node.set_class('link-text') - - reference_node = docutils.nodes.reference('', '', internal=False, refuri=url) - reference_node.set_class('remix-link') - reference_node += [link_icon_node, link_text_node] + reference_node = docutils.nodes.reference('', 'open in Remix', internal=False, refuri=url, target='_blank') + reference_node['classes'].append('remix-link') paragraph_node = docutils.nodes.paragraph() - paragraph_node.set_class('remix-link-container') - paragraph_node += reference_node + paragraph_node['classes'].append('remix-link-container') + paragraph_node.append(reference_node) return paragraph_node @@ -48,22 +41,24 @@ def insert_remix_link(app, doctree, solidity_version): for literal_block_node in doctree.traverse(docutils.nodes.literal_block): assert 'language' in literal_block_node.attributes language = literal_block_node.attributes['language'].lower() - if language in ['solidity', 'yul']: - text_nodes = list(literal_block_node.traverse(docutils.nodes.Text)) - assert len(text_nodes) == 1 - - remix_url = remix_code_url(text_nodes[0], language, solidity_version) - url_length = len(remix_url.encode('utf-8')) - if url_length > MAX_SAFE_URL_LENGTH: - logger.warning( - "Remix URL generated from the code snippet exceeds the maximum safe URL length " - " (%d > %d bytes).", - url_length, - MAX_SAFE_URL_LENGTH, - location=(literal_block_node.source, literal_block_node.line), - ) - - insert_node_before(literal_block_node, build_remix_link_node(remix_url)) + if language not in ['solidity', 'yul']: + continue + + text_nodes = list(literal_block_node.traverse(docutils.nodes.Text)) + assert len(text_nodes) == 1 + + remix_url = remix_code_url(text_nodes[0], language, solidity_version) + url_length = len(remix_url.encode('utf-8')) + if url_length > MAX_SAFE_URL_LENGTH: + logger.warning( + "Remix URL generated from the code snippet exceeds the maximum safe URL length " + " (%d > %d bytes).", + url_length, + MAX_SAFE_URL_LENGTH, + location=(literal_block_node.source, literal_block_node.line), + ) + + insert_node_before(literal_block_node, build_remix_link_node(remix_url)) def setup(app): diff --git a/docs/grammar/SolidityLexer.g4 b/docs/grammar/SolidityLexer.g4 index c872f4d216..fbd4e5d164 100644 --- a/docs/grammar/SolidityLexer.g4 +++ b/docs/grammar/SolidityLexer.g4 @@ -9,10 +9,9 @@ ReservedKeywords: | 'partial' | 'promise' | 'reference' | 'relocatable' | 'sealed' | 'sizeof' | 'static' | 'supports' | 'switch' | 'typedef' | 'typeof' | 'var'; -Pragma: 'pragma' -> pushMode(PragmaMode); Abstract: 'abstract'; -Anonymous: 'anonymous'; Address: 'address'; +Anonymous: 'anonymous'; As: 'as'; Assembly: 'assembly' -> pushMode(AssemblyBlockMode); Bool: 'bool'; @@ -29,14 +28,21 @@ Do: 'do'; Else: 'else'; Emit: 'emit'; Enum: 'enum'; +<<<<<<< HEAD Error: 'error'; // pas un vrai mot-clé Revert: 'revert'; // pas un vrai mot-clé +======= +Error: 'error'; // not a real keyword +>>>>>>> english/develop Event: 'event'; External: 'external'; Fallback: 'fallback'; False: 'false'; Fixed: 'fixed' | ('fixed' [1-9][0-9]* 'x' [1-9][0-9]*); +<<<<<<< HEAD From: 'from'; // pas un vrai mot-clé +======= +>>>>>>> english/develop /** * Types d'octets de longueur fixe. */ @@ -46,7 +52,9 @@ FixedBytes: 'bytes17' | 'bytes18' | 'bytes19' | 'bytes20' | 'bytes21' | 'bytes22' | 'bytes23' | 'bytes24' | 'bytes25' | 'bytes26' | 'bytes27' | 'bytes28' | 'bytes29' | 'bytes30' | 'bytes31' | 'bytes32'; For: 'for'; +From: 'from'; // not a real keyword Function: 'function'; +Global: 'global'; // not a real keyword Hex: 'hex'; If: 'if'; Immutable: 'immutable'; @@ -63,15 +71,17 @@ New: 'new'; /** * Dénomination unitaire pour les nombres. */ -NumberUnit: 'wei' | 'gwei' | 'ether' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years'; +SubDenomination: 'wei' | 'gwei' | 'ether' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years'; Override: 'override'; Payable: 'payable'; +Pragma: 'pragma' -> pushMode(PragmaMode); Private: 'private'; Public: 'public'; Pure: 'pure'; Receive: 'receive'; Return: 'return'; Returns: 'returns'; +Revert: 'revert'; // not a real keyword /** * Types d'entiers signés dimensionnés. * int est un alias de int256. @@ -89,6 +99,7 @@ Try: 'try'; Type: 'type'; Ufixed: 'ufixed' | ('ufixed' [1-9][0-9]+ 'x' [1-9][0-9]+); Unchecked: 'unchecked'; +Unicode: 'unicode'; /** * Types d'entiers non signés dimensionnés. * uint est un alias de uint256. @@ -198,9 +209,7 @@ fragment EscapeSequence: /** * Un littéral de chaîne de caractères entre guillemets permettant des caractères unicodes arbitraires. */ -UnicodeStringLiteral: - 'unicode"' DoubleQuotedUnicodeStringCharacter* '"' - | 'unicode\'' SingleQuotedUnicodeStringCharacter* '\''; +UnicodeStringLiteral: 'unicode' (('"' DoubleQuotedUnicodeStringCharacter* '"') | ('\'' SingleQuotedUnicodeStringCharacter* '\'')); //@doc:inline fragment DoubleQuotedUnicodeStringCharacter: ~["\r\n\\] | EscapeSequence; //@doc:inline @@ -225,9 +234,23 @@ fragment EvenHexDigits: HexCharacter HexCharacter ('_'? HexCharacter HexCharacte fragment HexCharacter: [0-9A-Fa-f]; /** +<<<<<<< HEAD * Un littéral de nombre décimal est constitué de chiffres décimaux qui peuvent être délimités par des traits de soulignement et * un exposant positif ou négatif facultatif. * Si les chiffres contiennent un point décimal, le littéral est de type à virgule fixe. +======= + * Scanned but not used by any rule, i.e, disallowed. + * solc parser considers number starting with '0', not immediately followed by '.' or 'x' as + * octal, even if non octal digits '8' and '9' are present. + */ +OctalNumber: '0' DecimalDigits ('.' DecimalDigits)?; + + +/** + * A decimal number literal consists of decimal digits that may be delimited by underscores and + * an optional positive or negative exponent. + * If the digits contain a decimal point, the literal has fixed point type. +>>>>>>> english/develop */ DecimalNumber: (DecimalDigits | (DecimalDigits? '.' DecimalDigits)) ([eE] '-'? DecimalDigits)?; //@doc:inline @@ -235,8 +258,19 @@ fragment DecimalDigits: [0-9] ('_'? [0-9])* ; /** +<<<<<<< HEAD * Un identifiant dans solidity doit commencer par une lettre, un symbole dollar ou un trait de soulignement et * peut en outre contenir des chiffres après le premier symbole. +======= + * This is needed to avoid successfully parsing a number followed by a string with no whitespace between. + */ +DecimalNumberFollowedByIdentifier: DecimalNumber Identifier; + + +/** + * An identifier in solidity has to start with a letter, a dollar-sign or an underscore and + * may additionally contain numbers after the first symbol. +>>>>>>> english/develop */ Identifier: IdentifierStart IdentifierPart*; //@doc:inline @@ -254,6 +288,12 @@ mode AssemblyBlockMode; AssemblyDialect: '"evmasm"'; AssemblyLBrace: '{' -> popMode, pushMode(YulMode); +AssemblyFlagString: '"' DoubleQuotedStringCharacter+ '"'; + +AssemblyBlockLParen: '('; +AssemblyBlockRParen: ')'; +AssemblyBlockComma: ','; + AssemblyBlockWS: [ \t\r\n\u000C]+ -> skip ; AssemblyBlockCOMMENT: '/*' .*? '*/' -> channel(HIDDEN) ; AssemblyBlockLINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN) ; @@ -281,14 +321,14 @@ YulEVMBuiltin: 'stop' | 'add' | 'sub' | 'mul' | 'div' | 'sdiv' | 'mod' | 'smod' | 'exp' | 'not' | 'lt' | 'gt' | 'slt' | 'sgt' | 'eq' | 'iszero' | 'and' | 'or' | 'xor' | 'byte' | 'shl' | 'shr' | 'sar' | 'addmod' | 'mulmod' | 'signextend' | 'keccak256' - | 'pop' | 'mload' | 'mstore' | 'mstore8' | 'sload' | 'sstore' | 'msize' | 'gas' + | 'pop' | 'mload' | 'mstore' | 'mstore8' | 'sload' | 'sstore' | 'tload' | 'tstore'| 'msize' | 'gas' | 'address' | 'balance' | 'selfbalance' | 'caller' | 'callvalue' | 'calldataload' | 'calldatasize' | 'calldatacopy' | 'extcodesize' | 'extcodecopy' | 'returndatasize' - | 'returndatacopy' | 'extcodehash' | 'create' | 'create2' | 'call' | 'callcode' + | 'returndatacopy' | 'mcopy' | 'extcodehash' | 'create' | 'create2' | 'call' | 'callcode' | 'delegatecall' | 'staticcall' | 'return' | 'revert' | 'selfdestruct' | 'invalid' | 'log0' | 'log1' | 'log2' | 'log3' | 'log4' | 'chainid' | 'origin' | 'gasprice' - | 'blockhash' | 'coinbase' | 'timestamp' | 'number' | 'difficulty' | 'gaslimit' - | 'basefee'; + | 'blockhash' | 'blobhash' | 'coinbase' | 'timestamp' | 'number' | 'difficulty' + | 'prevrandao' | 'gaslimit' | 'basefee' | 'blobbasefee'; YulLBrace: '{' -> pushMode(YulMode); YulRBrace: '}' -> popMode; diff --git a/docs/grammar/SolidityParser.g4 b/docs/grammar/SolidityParser.g4 index 4070fab75a..605bc0c538 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -13,6 +13,7 @@ options { tokenVocab=SolidityLexer; } sourceUnit: ( pragmaDirective | importDirective + | usingDirective | contractDefinition | interfaceDefinition | libraryDefinition @@ -22,6 +23,7 @@ sourceUnit: ( | enumDefinition | userDefinedValueTypeDefinition | errorDefinition + | eventDefinition )* EOF; //@doc: inline @@ -152,16 +154,22 @@ stateMutability: Pure | View | Payable; */ overrideSpecifier: Override (LParen overrides+=identifierPath (Comma overrides+=identifierPath)* RParen)?; /** +<<<<<<< HEAD * La définition des fonctions de contrat, de bibliothèque et d'interface. * Selon le contexte dans lequel la fonction est définie, d'autres restrictions peuvent s'appliquer. * Par exemple, les fonctions des interfaces doivent être non implémentées, c'est-à-dire qu'elles ne peuvent pas contenir de bloc de corps. +======= + * The definition of contract, library, interface or free functions. + * Depending on the context in which the function is defined, further restrictions may apply, + * e.g. functions in interfaces have to be unimplemented, i.e. may not contain a body block. +>>>>>>> english/develop */ functionDefinition locals[ boolean visibilitySet = false, boolean mutabilitySet = false, boolean virtualSet = false, - boolean overrideSpecifierSet = false + boolean overrideSpecifierSet = false, ] : Function (identifier | Fallback | Receive) @@ -175,6 +183,7 @@ locals[ )* (Returns LParen returnParameters=parameterList RParen)? (Semicolon | body=block); + /** * La définition d'un modificateur. * Notez que dans le corps d'un modificateur, l'underscore ne peut pas être utilisé comme identifiant, @@ -313,10 +322,42 @@ errorDefinition: Semicolon; /** +<<<<<<< HEAD * Utilisation de directives pour lier des fonctions de bibliothèques à des types. * Peut se produire dans les contrats et les bibliothèques. - */ -usingDirective: Using identifierPath For (Mul | typeName) Semicolon; +======= + * Operators that users are allowed to implement for some types with `using for`. +>>>>>>> english/develop + */ +userDefinableOperator: + BitAnd + | BitNot + | BitOr + | BitXor + | Add + | Div + | Mod + | Mul + | Sub + | Equal + | GreaterThan + | GreaterThanOrEqual + | LessThan + | LessThanOrEqual + | NotEqual; + +/** + * Using directive to attach library functions and free functions to types. + * Can occur within contracts and libraries and at the file level. + */ +usingDirective: + Using ( + identifierPath + | (LBrace usingAliases (Comma usingAliases)* RBrace) + ) For (Mul | typeName) Global? Semicolon; + +usingAliases: identifierPath (As userDefinableOperator)?; + /** * Un nom de type peut être un type élémentaire, un type de fonction, un type de mappage, un type défini par l'utilisateur * (par exemple, un contrat ou un struct) ou un type de tableau. @@ -348,7 +389,7 @@ dataLocation: Memory | Storage | Calldata; */ expression: expression LBrack index=expression? RBrack # IndexAccess - | expression LBrack start=expression? Colon end=expression? RBrack # IndexRangeAccess + | expression LBrack startIndex=expression? Colon endIndex=expression? RBrack # IndexRangeAccess | expression Period (identifier | Address) # MemberAccess | expression LBrace (namedArgument (Comma namedArgument)*)? RBrace # FunctionCallOptions | expression callArgumentList # FunctionCall @@ -369,12 +410,13 @@ expression: | expression Or expression # OrOperation | expression Conditional expression Colon expression # Conditional | expression assignOp expression # Assignment - | New typeName # NewExpression + | New typeName # NewExpr | tupleExpression # Tuple | inlineArrayExpression # InlineArray | ( identifier | literal + | literalWithSubDenomination | elementaryTypeName[false] ) # PrimaryExpression ; @@ -390,9 +432,12 @@ inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack; /** * Outre les identificateurs ordinaires sans mot-clé, certains mots-clés comme "from" et "error" peuvent également être utilisés comme identificateurs. */ -identifier: Identifier | From | Error | Revert; +identifier: Identifier | From | Error | Revert | Global; literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral; + +literalWithSubDenomination: numberLiteral SubDenomination; + booleanLiteral: True | False; /** * Une chaîne de caractères complète est constituée d'une ou plusieurs chaînes de caractères consécutives entre guillemets. @@ -410,7 +455,8 @@ unicodeStringLiteral: UnicodeStringLiteral+; /** * Les littéraux numériques peuvent être des nombres décimaux ou hexadécimaux avec une unité optionnelle. */ -numberLiteral: (DecimalNumber | HexNumber) NumberUnit?; +numberLiteral: DecimalNumber | HexNumber; + /** * Un bloc d'instructions avec des accolades. Ouvre sa propre portée. */ @@ -478,7 +524,13 @@ revertStatement: Revert expression callArgumentList Semicolon; * Le contenu d'un bloc d'assemblage en ligne utilise un analyseur/lexeur séparé, c'est-à-dire que l'ensemble des mots-clés et * d'identificateurs autorisés est différent à l'intérieur d'un bloc d'assemblage en ligne. */ -assemblyStatement: Assembly AssemblyDialect? AssemblyLBrace yulStatement* YulRBrace; +assemblyStatement: Assembly AssemblyDialect? assemblyFlags? AssemblyLBrace yulStatement* YulRBrace; + +/** + * Assembly flags. + * Comma-separated list of double-quoted strings as flags. + */ +assemblyFlags: AssemblyBlockLParen AssemblyFlagString (AssemblyBlockComma AssemblyFlagString)* AssemblyBlockRParen; //@doc:inline variableDeclarationList: variableDeclarations+=variableDeclaration (Comma variableDeclarations+=variableDeclaration)*; @@ -499,7 +551,7 @@ variableDeclarationTuple: variableDeclarationStatement: ((variableDeclaration (Assign expression)?) | (variableDeclarationTuple Assign expression)) Semicolon; expressionStatement: expression Semicolon; -mappingType: Mapping LParen key=mappingKeyType DoubleArrow value=typeName RParen; +mappingType: Mapping LParen key=mappingKeyType name=identifier? DoubleArrow value=typeName name=identifier? RParen; /** * Seuls les types élémentaires ou les types définis par l'utilisateur sont viables comme clés de mappage. */ diff --git a/docs/index.rst b/docs/index.rst index ebb6607802..27dff59c4c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,6 +1,7 @@ Solidity ======== +<<<<<<< HEAD .. warning:: You are reading a community translation of the Solidity documentation. The Solidity team @@ -35,15 +36,43 @@ un numéro de version 0.y.z `pour indiquer ce rythme rapide de changement `. +======= +Solidity is an object-oriented, high-level language for implementing smart contracts. +Smart contracts are programs that govern the behavior of accounts within the Ethereum state. + +Solidity is a `curly-bracket language `_ designed to target the Ethereum Virtual Machine (EVM). +It is influenced by C++, Python, and JavaScript. +You can find more details about which languages Solidity has been inspired by in the :doc:`language influences ` section. + +Solidity is statically typed, supports inheritance, libraries, and complex user-defined types, among other features. + +With Solidity, you can create contracts for uses such as voting, crowdfunding, blind auctions, and multi-signature wallets. + +When deploying contracts, you should use the latest released version of Solidity. +Apart from exceptional cases, only the latest version receives +`security fixes `_. +Furthermore, breaking changes, as well as new features, are introduced regularly. +We currently use a 0.y.z version number `to indicate this fast pace of change `_. + +.. warning:: + + Solidity recently released the 0.8.x version that introduced a lot of breaking changes. + Make sure you read :doc:`the full list <080-breaking-changes>`. +>>>>>>> english/develop Les idées pour améliorer Solidity ou cette documentation sont toujours les bienvenues, lisez notre :doc:`guide des contributeurs ` pour plus de détails. .. Astuce:: +<<<<<<< HEAD Vous pouvez télécharger cette documentation au format PDF, HTML ou Epub en cliquant sur le menu déroulant des versions dans le coin inférieur gauche et en sélectionnant le format de téléchargement préféré. +======= + You can download this documentation as PDF, HTML or Epub + by clicking on the versions flyout menu in the bottom-left corner and selecting the preferred download format. +>>>>>>> english/develop Pour commencer @@ -51,9 +80,13 @@ Pour commencer **1. Comprendre les bases des contrats intelligents** +<<<<<<< HEAD Si le concept des contrats intelligents est nouveau pour vous, nous vous recommandons de commencer par vous plonger dans la section "Introduction aux contrats intelligents". dans la section "Introduction aux contrats intelligents", qui couvre : +======= +If you are new to the concept of smart contracts, we recommend you to get started by digging into the "Introduction to Smart Contracts" section, which covers the following: +>>>>>>> english/develop * :ref:`Un exemple simple de smart contract ` écrit sous Solidity. * :ref:`Les bases de la blockchain `. @@ -70,6 +103,7 @@ Il existe plusieurs façons d'installer le compilateur Solidity. Il vous suffit de choisir votre option préférée et de suivre les étapes décrites sur la :ref:`installation page `. .. hint:: +<<<<<<< HEAD Vous pouvez essayer des exemples de code directement dans votre navigateur grâce à la fonction `Remix IDE `_. Remix est un IDE basé sur un navigateur web qui vous permet d'écrire, de déployer et d'administrer les smart contracts Solidity, @@ -83,9 +117,24 @@ Il vous suffit de choisir votre option préférée et de suivre les étapes déc de contrats intelligents sont parfois plus confiants dans le code que ses auteurs, et les blockchains et les contrats intelligents ont leurs propres problèmes à surveiller. Avant de travailler sur le code de production, assurez-vous de lire la section :ref:`security_considerations`. +======= + You can try out code examples directly in your browser with the + `Remix IDE `_. + Remix is a web browser-based IDE that allows you to write, deploy and administer Solidity smart contracts, + without the need to install Solidity locally. + +.. warning:: + As humans write software, it can have bugs. + Therefore, you should follow established software development best practices when writing your smart contracts. + This includes code review, testing, audits, and correctness proofs. + Smart contract users are sometimes more confident with code than their authors, + and blockchains and smart contracts have their own unique issues to watch out for, + so before working on production code, make sure you read the :ref:`security_considerations` section. +>>>>>>> english/develop **4. En savoir plus** +<<<<<<< HEAD Si vous souhaitez en savoir plus sur la création d'applications décentralisées sur Ethereum, le programme `Ethereum Developer Resources `_ peut vous aider à trouver de la documentation générale sur Ethereum, ainsi qu'une large sélection de tutoriels, @@ -94,12 +143,22 @@ d'outils et de cadres de développement. Si vous avez des questions, vous pouvez essayer de chercher des réponses ou de les poser sur `Ethereum StackExchange `_, ou sur notre `salon Gitter `_. +======= +If you want to learn more about building decentralized applications on Ethereum, +the `Ethereum Developer Resources `_ can help you with further general documentation around Ethereum, +and a wide selection of tutorials, tools, and development frameworks. + +If you have any questions, you can try searching for answers or asking on the +`Ethereum StackExchange `_, +or our `Gitter channel `_. +>>>>>>> english/develop .. _translations: Traductions ------------ +<<<<<<< HEAD Des bénévoles de la communauté aident à traduire cette documentation en plusieurs langues. Leur degré d'exhaustivité et de mise à jour varie. La version anglaise est une référence. @@ -119,6 +178,30 @@ La version anglaise est une référence. * `Chinois simplifié `_ (en cours) * `Espagnol `_ * `Turc `_ (partiel) +======= +Community contributors help translate this documentation into several languages. +Note that they have varying degrees of completeness and up-to-dateness. +The English version stands as a reference. + +You can switch between languages by clicking on the flyout menu in the bottom-left corner +and selecting the preferred language. + +* `Chinese `_ +* `French `_ +* `Indonesian `_ +* `Japanese `_ +* `Korean `_ +* `Persian `_ +* `Russian `_ +* `Spanish `_ +* `Turkish `_ + +.. note:: + + We set up a GitHub organization and translation workflow to help streamline the community efforts. + Please refer to the translation guide in the `solidity-docs org `_ + for information on how to start a new language or contribute to the community translations. +>>>>>>> english/develop Contenu ======== @@ -130,8 +213,8 @@ Contenu :caption: Principes de base introduction-to-smart-contracts.rst - installing-solidity.rst solidity-by-example.rst + installing-solidity.rst .. toctree:: :maxdepth: 2 @@ -170,21 +253,35 @@ Contenu .. toctree:: :maxdepth: 2 +<<<<<<< HEAD :caption: Matériel supplémentaire +======= + :caption: Advisory content +>>>>>>> english/develop + security-considerations.rst + bugs.rst 050-breaking-changes.rst 060-breaking-changes.rst 070-breaking-changes.rst 080-breaking-changes.rst + +.. toctree:: + :maxdepth: 2 + :caption: Additional Material + natspec-format.rst - security-considerations.rst smtchecker.rst - resources.rst - path-resolution.rst yul.rst + path-resolution.rst + +.. toctree:: + :maxdepth: 2 + :caption: Resources + style-guide.rst common-patterns.rst - bugs.rst + resources.rst contributing.rst - brand-guide.rst language-influences.rst + brand-guide.rst diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index b35843b2df..a634d9e413 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -9,17 +9,37 @@ Installation du compilateur Solidity Versionnage ========== +<<<<<<< HEAD Les versions de Solidity suivent le `versionnement sémantique `_ et en plus des versions, **des builds de développement nocturnes** sont également mis à disposition. Les nightly builds ne sont pas garanties et, malgré tous les efforts, elles peuvent contenir et/ou des changements non documentés. Nous recommandons d'utiliser la dernière version. Les installateurs de paquets ci-dessous utiliseront la dernière version. +======= +Solidity versions follow `Semantic Versioning `_. In +addition, patch-level releases with major release 0 (i.e. 0.x.y) will not +contain breaking changes. That means code that compiles with version 0.x.y +can be expected to compile with 0.x.z where z > y. + +In addition to releases, we provide **nightly development builds** to make +it easy for developers to try out upcoming features and +provide early feedback. Note, however, that while the nightly builds are usually +very stable, they contain bleeding-edge code from the development branch and are +not guaranteed to be always working. Despite our best efforts, they might +contain undocumented and/or broken changes that will not become a part of an +actual release. They are not meant for production use. + +When deploying contracts, you should use the latest released version of Solidity. This +is because breaking changes, as well as new features and bug fixes are introduced regularly. +We currently use a 0.x version number `to indicate this fast pace of change `_. +>>>>>>> english/develop Remix ===== *Nous recommandons Remix pour les petits contrats et pour apprendre rapidement Solidity.* +<<<<<<< HEAD `Access Remix en ligne `_, vous n'avez pas besoin d'installer quoi que ce soit. Si vous voulez l'utiliser sans connexion à l'Internet, allez sur https://github.com/ethereum/remix-live/tree/gh-pages et téléchargez le fichier ``.zip`` comme @@ -29,6 +49,17 @@ sans installer plusieurs versions de Solidity. D'autres options sur cette page détaillent l'installation du compilateur Solidity en ligne de commande sur votre ordinateur. Choisissez un compilateur en ligne de commande si vous travaillez sur un contrat plus important ou si vous avez besoin de plus d'options de compilation. +======= +`Access Remix online `_, you do not need to install anything. +If you want to use it without connection to the Internet, go to +https://github.com/ethereum/remix-live/tree/gh-pages#readme and follow the instructions on that page. +Remix is also a convenient option for testing nightly builds +without installing multiple Solidity versions. + +Further options on this page detail installing command-line Solidity compiler software +on your computer. Choose a command-line compiler if you are working on a larger contract +or if you require more compilation options. +>>>>>>> english/develop .. _solcjs: @@ -41,10 +72,17 @@ La documentation :ref:`commandline-compiler` suppose que vous utilisez le compilateur complet, ``solc``. L'utilisation de ``solcjs`` est documentée à l'intérieur de son propre `repository `_. +<<<<<<< HEAD Note : Le projet solc-js est dérivé du projet C++ `solc`. `solc` en utilisant Emscripten ce qui signifie que les deux utilisent le même code source du compilateur. `solc-js` peut être utilisé directement dans des projets JavaScript (comme Remix). Veuillez vous référer au dépôt solc-js pour les instructions. +======= +Note: The solc-js project is derived from the C++ +`solc` by using Emscripten, which means that both use the same compiler source code. +`solc-js` can be used in JavaScript projects directly (such as Remix). +Please refer to the solc-js repository for instructions. +>>>>>>> english/develop .. code-block:: bash @@ -52,42 +90,74 @@ Veuillez vous référer au dépôt solc-js pour les instructions. .. note:: +<<<<<<< HEAD L'exécutable en ligne de commande est nommé ``solcjs``. Les options en ligne de commande de ``solcjs`` ne sont pas compatibles avec ``solc`` et les outils (tels que ``geth``) qui attendent le comportement de ``solc`` ne fonctionneront pas avec ``solcjs``. +======= + The command-line executable is named ``solcjs``. + + The command-line options of ``solcjs`` are not compatible with ``solc`` and tools (such as ``geth``) + expecting the behavior of ``solc`` will not work with ``solcjs``. +>>>>>>> english/develop Docker ====== +<<<<<<< HEAD Les images Docker des constructions Solidity sont disponibles en utilisant l'image ``solc`` de l'organisation ``ethereum``. Utilisez la balise ``stable`` pour la dernière version publiée, et ``nightly`` pour les changements potentiellement instables dans la branche de développement. L'image Docker exécute l'exécutable du compilateur, vous pouvez donc lui passer tous les arguments du compilateur. Par exemple, la commande ci-dessous récupère la version stable de l'image ``solc`` (si vous ne l'avez pas déjà), et l'exécute dans un nouveau conteneur, en passant l'argument ``--help``. +======= +Docker images of Solidity builds are available using the ``solc`` image from the ``ethereum`` organization. +Use the ``stable`` tag for the latest released version, and ``nightly`` for potentially unstable changes in the ``develop`` branch. + +The Docker image runs the compiler executable so that you can pass all compiler arguments to it. +For example, the command below pulls the stable version of the ``solc`` image (if you do not have it already), +and runs it in a new container, passing the ``--help`` argument. +>>>>>>> english/develop .. code-block:: bash docker run ethereum/solc:stable --help +<<<<<<< HEAD Vous pouvez également spécifier les versions de build de la version dans la balise, par exemple, pour la version 0.5.4. +======= +For example, You can specify release build versions in the tag for the 0.5.4 release. +>>>>>>> english/develop .. code-block:: bash docker run ethereum/solc:0.5.4 --help +<<<<<<< HEAD Pour utiliser l'image Docker afin de compiler les fichiers Solidity sur la machine hôte, montez un dossier local pour l'entrée et la sortie, et spécifier le contrat à compiler. Par exemple. +======= +To use the Docker image to compile Solidity files on the host machine, mount a +local folder for input and output, and specify the contract to compile. For example. +>>>>>>> english/develop .. code-block:: bash docker run -v /local/path:/sources ethereum/solc:stable -o /sources/output --abi --bin /sources/Contract.sol +<<<<<<< HEAD Vous pouvez également utiliser l'interface JSON standard (ce qui est recommandé lorsque vous utilisez le compilateur avec des outils). Lors de l'utilisation de cette interface, il n'est pas nécessaire de monter des répertoires tant que l'entrée JSON est autonome (c'est-à-dire qu'il ne fait pas référence à des fichiers externes qui devraient être :ref:`chargés par la callback d'importation `). +======= +You can also use the standard JSON interface (which is recommended when using the compiler with tooling). +When using this interface, it is not necessary to mount any directories as long as the JSON input is +self-contained (i.e. it does not refer to any external files that would have to be +:ref:`loaded by the import callback `). +>>>>>>> english/develop .. code-block:: bash @@ -117,9 +187,26 @@ La version nocturne peut être installée en utilisant ces commandes : sudo apt-get update sudo apt-get install solc +<<<<<<< HEAD Nous publions également un paquet `snap `_, qui est installable dans toutes les `distros Linux supportées `_. Pour installer la dernière version stable de solc : +======= +Furthermore, some Linux distributions provide their own packages. These packages are not directly +maintained by us but usually kept up-to-date by the respective package maintainers. + +For example, Arch Linux has packages for the latest development version as AUR packages: `solidity `_ +and `solidity-bin `_. + +.. note:: + + Please be aware that `AUR `_ packages + are user-produced content and unofficial packages. Exercise caution when using them. + +There is also a `snap package `_, however, it is **currently unmaintained**. +It is installable in all the `supported Linux distros `_. To +install the latest stable version of solc: +>>>>>>> english/develop .. code-block:: bash @@ -198,6 +285,7 @@ plates-formes supportées à `solc-bin`_. C'est aussi l'endroit où vous pouvez Le dépôt n'est pas seulement un moyen rapide et facile pour les utilisateurs finaux d'obtenir des binaires prêts à l'emploi, mais il est également conçu pour être convivial pour les outils tiers : +<<<<<<< HEAD - Le contenu est mis en miroir sur https://binaries.soliditylang.org, où il peut être facilement téléchargé via HTTPS sans authentification, ni contrôle. HTTPS sans authentification, limitation de débit ou nécessité d'utiliser git. - Le contenu est servi avec des en-têtes `Content-Type` corrects et une configuration CORS indulgente @@ -211,15 +299,36 @@ prêts à l'emploi, mais il est également conçu pour être convivial pour les - Les fichiers sont servis à la fois par HTTP et HTTPS. Tant que vous obtenez la liste des fichiers d'une manière sécurisée (via git, HTTPS, IPFS ou simplement en la mettant en cache localement) et que vous vérifiez les hachages des binaires après les avoir téléchargés, vous n'avez pas besoin d'utiliser HTTPS pour les binaires eux-mêmes. +======= +- The content is mirrored to https://binaries.soliditylang.org where it can be easily downloaded over + HTTPS without any authentication, rate limiting or the need to use git. +- Content is served with correct `Content-Type` headers and lenient CORS configuration so that it + can be directly loaded by tools running in the browser. +- Binaries do not require installation or unpacking (exception for older Windows builds + bundled with necessary DLLs). +- We strive for a high level of backward-compatibility. Files, once added, are not removed or moved + without providing a symlink/redirect at the old location. They are also never modified + in place and should always match the original checksum. The only exception would be broken or + unusable files with the potential to cause more harm than good if left as is. +- Files are served over both HTTP and HTTPS. As long as you obtain the file list in a secure way + (via git, HTTPS, IPFS or just have it cached locally) and verify hashes of the binaries + after downloading them, you do not have to use HTTPS for the binaries themselves. +>>>>>>> english/develop Les mêmes binaires sont dans la plupart des cas disponibles sur la page `Solidity release page on Github`_. La différence est que nous ne mettons généralement pas à jour les anciennes versions sur la page Github. Cela signifie que que nous ne les renommons pas si la convention de nommage change et que nous n'ajoutons pas de builds pour les plates-formes qui n'étaient pas supportées au moment de la publication. Ceci n'arrive que dans ``solc-bin``. +<<<<<<< HEAD Le dépôt ``solc-bin`` contient plusieurs répertoires de haut niveau, chacun représentant une seule plate-forme. Chacun contient un fichier ``list.json`` listant les binaires disponibles. Par exemple dans ``emscripten-wasm32/list.json``, vous trouverez les informations suivantes sur la version 0.7.4 : +======= +The ``solc-bin`` repository contains several top-level directories, each representing a single platform. +Each one includes a ``list.json`` file listing the available binaries. For example in +``emscripten-wasm32/list.json`` you will find the following information about version 0.7.4: +>>>>>>> english/develop .. code-block:: json @@ -240,6 +349,7 @@ Cela signifie que : - Vous pouvez trouver le binaire dans le même répertoire sous le nom de `solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js `_. +<<<<<<< HEAD Notez que le fichier pourrait être un lien symbolique, et vous devrez le résoudre vous-même si vous n'utilisez pas git pour le télécharger ou si votre système de fichiers ne supporte pas les liens symboliques. - Le binaire est également mis en miroir à https://binaries.soliditylang.org/emscripten-wasm32/solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js. @@ -252,6 +362,20 @@ Cela signifie que : en ligne de commande à l'aide de l'utilitaire ``keccak256sum`` fourni par `sha3sum`_ ou de la fonction `keccak256()` de ethereumjs-util`_ en JavaScript. - Vous pouvez également vérifier l'intégrité du binaire en comparant son hachage sha256 à +======= + Note that the file might be a symlink, and you will need to resolve it yourself if you are not using + git to download it or your file system does not support symlinks. +- The binary is also mirrored at https://binaries.soliditylang.org/emscripten-wasm32/solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js. + In this case git is not necessary and symlinks are resolved transparently, either by serving a copy + of the file or returning a HTTP redirect. +- The file is also available on IPFS at `QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS`_. +- The file might in future be available on Swarm at `16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1`_. +- You can verify the integrity of the binary by comparing its keccak256 hash to + ``0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3``. The hash can be computed + on the command-line using ``keccak256sum`` utility provided by `sha3sum`_ or `keccak256() function + from ethereumjs-util`_ in JavaScript. +- You can also verify the integrity of the binary by comparing its sha256 hash to +>>>>>>> english/develop ``0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2``. .. warning:: @@ -300,12 +424,17 @@ Cela signifie que : Construire à partir de la source ==================== +<<<<<<< HEAD Conditions préalables - Tous les systèmes d'exploitation +======= +Prerequisites - All Operating Systems +>>>>>>> english/develop ------------------------------------- Les éléments suivants sont des dépendances pour toutes les versions de Solidity : +<<<<<<< HEAD +-----------------------------------+----------------------------------------------------------------+ | Logiciel | Notes | +===================================+================================================================+ @@ -320,6 +449,23 @@ Les éléments suivants sont des dépendances pour toutes les versions de Solidi +-----------------------------------+----------------------------------------------------------------+ | `cvc4`_ (Optionnel) | À utiliser avec le vérificateur SMT. | +-----------------------------------+----------------------------------------------------------------+ +======= ++-----------------------------------+-------------------------------------------------------+ +| Software | Notes | ++===================================+=======================================================+ +| `CMake`_ (version 3.21.3+ on | Cross-platform build file generator. | +| Windows, 3.13+ otherwise) | | ++-----------------------------------+-------------------------------------------------------+ +| `Boost`_ (version 1.77+ on | C++ libraries. | +| Windows, 1.65+ otherwise) | | ++-----------------------------------+-------------------------------------------------------+ +| `Git`_ | Command-line tool for retrieving source code. | ++-----------------------------------+-------------------------------------------------------+ +| `z3`_ (version 4.8.16+, Optional) | For use with SMT checker. | ++-----------------------------------+-------------------------------------------------------+ +| `cvc4`_ (Optional) | For use with SMT checker. | ++-----------------------------------+-------------------------------------------------------+ +>>>>>>> english/develop .. _cvc4: https://cvc4.cs.stanford.edu/web/ .. _Git: https://git-scm.com/download @@ -328,9 +474,15 @@ Les éléments suivants sont des dépendances pour toutes les versions de Solidi .. _z3: https://github.com/Z3Prover/z3 .. note:: +<<<<<<< HEAD Les versions de Solidity antérieures à 0.5.10 ne parviennent pas à se lier correctement avec les versions Boost 1.70+. Une solution possible est de renommer temporairement le répertoire ``/lib/cmake/Boost-1.70.0`` avant d'exécuter la commande cmake pour configurer solidity. +======= + Solidity versions prior to 0.5.10 can fail to correctly link against Boost versions 1.70+. + A possible workaround is to temporarily rename ``/lib/cmake/Boost-1.70.0`` + prior to running the cmake command to configure Solidity. +>>>>>>> english/develop A partir de la 0.5.10, la liaison avec Boost 1.70+ devrait fonctionner sans intervention manuelle. @@ -344,7 +496,22 @@ Les éléments suivants sont des dépendances pour toutes les versions de Solidi Si vous faites cela, cependant, n'oubliez pas de passer l'option ``--no-smt`` à ``scripts/tests.sh`` pour sauter les tests SMT. +<<<<<<< HEAD Versions minimales du compilateur +======= +.. note:: + By default the build is performed in *pedantic mode*, which enables extra warnings and tells the + compiler to treat all warnings as errors. + This forces developers to fix warnings as they arise, so they do not accumulate "to be fixed later". + If you are only interested in creating a release build and do not intend to modify the source code + to deal with such warnings, you can pass ``-DPEDANTIC=OFF`` option to CMake to disable this mode. + Doing this is not recommended for general use but may be necessary when using a toolchain we are + not testing with or trying to build an older version with newer tools. + If you encounter such warnings, please consider + `reporting them `_. + +Minimum Compiler Versions +>>>>>>> english/develop ^^^^^^^^^^^^^^^^^^^^^^^^^ Les compilateurs C++ suivants et leurs versions minimales peuvent construire la base de code Solidity : @@ -356,6 +523,7 @@ Les compilateurs C++ suivants et leurs versions minimales peuvent construire la Conditions préalables - macOS --------------------- +<<<<<<< HEAD Pour les builds macOS, assurez-vous que vous avez la dernière version de `Xcode installée `_. Cela contient le compilateur `Clang C++ `_, l' @@ -364,6 +532,16 @@ outils qui sont nécessaires à la création d'applications C++ sous OS X. Si vous installez Xcode pour la première fois, ou si vous venez d'installer une nouvelle nouvelle version, vous devrez accepter la licence avant de pouvoir effectuer des des constructions en ligne de commande : +======= +For macOS builds, ensure that you have the latest version of +`Xcode installed `_. +This contains the `Clang C++ compiler `_, the +`Xcode IDE `_ and other Apple development +tools that are required for building C++ applications on OS X. +If you are installing Xcode for the first time, or have just installed a new +version then you will need to agree to the license before you can do +command-line builds: +>>>>>>> english/develop .. code-block:: bash @@ -407,7 +585,11 @@ dans Visual Studio 2019 Build Tools ou Visual Studio 2019 : * Support C++/CLI .. _Visual Studio 2019: https://www.visualstudio.com/vs/ +<<<<<<< HEAD .. _Visual Studio 2019 Outils de construction: https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2019 +======= +.. _Visual Studio 2019 Build Tools: https://visualstudio.microsoft.com/vs/older-downloads/#visual-studio-2019-and-other-products +>>>>>>> english/develop Nous avons un script d'aide que vous pouvez utiliser pour installer toutes les dépendances externes requises : @@ -427,18 +609,30 @@ Pour cloner le code source, exécutez la commande suivante : git clone --recursive https://github.com/ethereum/solidity.git cd solidity +<<<<<<< HEAD Si vous voulez aider à développer Solidity, vous devez forker Solidity et ajouter votre fork personnel en tant que second remote : +======= +If you want to help develop Solidity, +you should fork Solidity and add your personal fork as a second remote: +>>>>>>> english/develop .. code-block:: bash git remote add personal git@github.com:[username]/solidity.git .. note:: +<<<<<<< HEAD Cette méthode aboutira à une construction preerelease conduisant par exemple à ce qu'un drapeau dans chaque bytecode produit par un tel compilateur. Si vous souhaitez recompiler un compilateur Solidity déjà publié, alors veuillez utiliser le tarball source sur la page de publication github : +======= + This method will result in a pre-release build leading to e.g. a flag + being set in each bytecode produced by such a compiler. + If you want to re-build a released Solidity compiler, then + please use the source tarball on the github release page: +>>>>>>> english/develop https://github.com/ethereum/solidity/releases/download/v0.X.Y/solidity_0.X.Y.tar.gz @@ -504,8 +698,13 @@ Si vous êtes intéressé par les options CMake disponibles, lancez ``cmake .. - Solveurs SMT ----------- +<<<<<<< HEAD Solidity peut être construit avec des solveurs SMT et le fera par défaut s'ils sont trouvés dans le système. Chaque solveur peut être désactivé par une option `cmake`. +======= +Solidity can be built against SMT solvers and will do so by default if +they are found in the system. Each solver can be disabled by a ``cmake`` option. +>>>>>>> english/develop *Note : Dans certains cas, cela peut également être une solution de contournement potentielle pour les échecs de construction.* @@ -558,4 +757,8 @@ Exemple : 3. Un changement de rupture est introduit --> la version passe à 0.5.0. 4. La version 0.5.0 est publiée. +<<<<<<< HEAD Ce comportement fonctionne bien avec la version :ref:`pragma `. +======= +This behavior works well with the :ref:`version pragma `. +>>>>>>> english/develop diff --git a/docs/internals/layout_in_storage.rst b/docs/internals/layout_in_storage.rst index 91686514f5..c4a1c9a0b0 100644 --- a/docs/internals/layout_in_storage.rst +++ b/docs/internals/layout_in_storage.rst @@ -53,11 +53,20 @@ comme des valeurs individuelles. l'autre en occupera trois. .. note:: +<<<<<<< HEAD La disposition des variables d'état dans le stockage est considérée comme faisant partie de l'interface externe de Solidity, en raison du fait que les pointeurs de stockage peuvent être transmis aux bibliothèques. Cela signifie que tout changement des règles décrites dans cette section est considéré comme un changement de rupture du langage et, en raison de sa nature critique, doit être considéré très attentivement avant d'être exécutée. +======= + The layout of state variables in storage is considered to be part of the external interface + of Solidity due to the fact that storage pointers can be passed to libraries. This means that + any change to the rules outlined in this section is considered a breaking change + of the language and due to its critical nature should be considered very carefully before + being executed. In the event of such a breaking change, we would want to release a + compatibility mode in which the compiler would generate bytecode supporting the old layout. +>>>>>>> english/develop Mappings et tableaux dynamiques @@ -89,8 +98,13 @@ l'élément peut être obtenu à partir des données de l'emplacement ``v`` en u La valeur correspondant à une clé de mappage ``k`` est située à ``keccak256(h(k) . p)`` où ``.`` est la concaténation et ``h`` est une fonction qui est appliquée à la clé en fonction de son type : +<<<<<<< HEAD - pour les types de valeurs, ``h`` compacte la valeur à 32 octets de la même manière que lors du stockage de la valeur en mémoire. - pour les chaînes de caractères et les tableaux d'octets, ``h`` calcule le hachage ``keccak256`` des données non paginées. +======= +- for value types, ``h`` pads the value to 32 bytes in the same way as when storing the value in memory. +- for strings and byte arrays, ``h(k)`` is just the unpadded data. +>>>>>>> english/develop Si la valeur du mappage est un type non-valeur, l'emplacement calculé marque le début des données. Si la valeur est de type struct, @@ -138,9 +152,14 @@ et les données sont stockées comme d'habitude dans ``keccak256(p)``. Cela sign en vérifiant si le bit le plus bas est activé : court (non activé) et long (activé). .. note:: +<<<<<<< HEAD La gestion des slots codés de manière invalide n'est actuellement pas prise en charge mais pourrait être ajoutée à l'avenir. Si vous compilez via le pipeline expérimental du compilateur basé sur l'IR, la lecture d'un slot non codé invalide entraîne une erreur ``Panic(0x22)``. +======= + Handling invalidly encoded slots is currently not supported but may be added in the future. + If you are compiling via IR, reading an invalidly encoded slot results in a ``Panic(0x22)`` error. +>>>>>>> english/develop Sortie JSON =========== @@ -153,7 +172,7 @@ l'interface :ref:`standard JSON `. La sortie est un objet JSON con élément a la forme suivante : -.. code:: +.. code-block:: json { @@ -180,7 +199,7 @@ Le ``type`` donné, dans ce cas ``t_uint256``, représente un élément de la li ``types``, qui a la forme : -.. code:: +.. code-block:: json { "encoding": "inplace", @@ -207,8 +226,13 @@ des types), les tableaux ont leur type ``base``, et les structures listent leurs le même format que le ``stockage`` de premier niveau (voir :ref:`ci-dessus `). .. note:: +<<<<<<< HEAD Le format de sortie JSON de la disposition de stockage d'un contrat est encore considéré comme expérimental, et est susceptible d'être modifié dans les versions de Solidity qui ne sont pas en rupture. +======= + The JSON output format of a contract's storage layout is still considered experimental + and is subject to change in non-breaking releases of Solidity. +>>>>>>> english/develop L'exemple suivant montre un contrat et sa disposition de stockage, contenant des types de valeur et de référence, des types codés emballés et des types imbriqués. @@ -230,13 +254,13 @@ des types de valeur et de référence, des types codés emballés et des types i uint y; S s; address addr; - mapping (uint => mapping (address => bool)) map; + mapping(uint => mapping(address => bool)) map; uint[] array; string s1; bytes b1; } -.. code:: json +.. code-block:: json { "storage": [ diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index 5451d453bf..09c3fee080 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -5,8 +5,16 @@ L'optimiseur ************ +<<<<<<< HEAD Le compilateur Solidity utilise deux modules d'optimisation différents : L'"ancien" optimiseur qui opère au niveau de l'opcode et le "nouvel" optimiseur qui opère sur le code Yul IR. +======= +The Solidity compiler involves optimizations at three different levels (in order of execution): + +- Optimizations during code generation based on a direct analysis of Solidity code. +- Optimizing transformations on the Yul IR code. +- Optimizations at the opcode level. +>>>>>>> english/develop L'optimiseur basé sur les opcodes applique un ensemble de `règles de simplification `_ aux opcodes. Il combine également des ensembles de codes égaux et supprime le code inutilisé. @@ -19,6 +27,7 @@ Si leurs arguments et valeurs de retour ne dépendent pas les uns des autres, no les appels de fonction. De même, si une fonction est sans effet secondaire et que son résultat est multiplié par zéro, on peut supprimer complètement l'appel de fonction. +<<<<<<< HEAD Actuellement, le paramètre ``--optimize`` active l'optimiseur basé sur le code optique pour le bytecode généré et l'optimiseur Yul pour le code Yul généré en interne, par exemple pour ABI coder v2. On peut utiliser ``solc --ir-optimized --optimize`` pour produire un @@ -26,6 +35,36 @@ Yul expérimental optimisé pour une source Solidity. De même, on peut utiliser pour un mode Yul autonome. Vous pouvez trouver plus de détails sur les deux modules d'optimisation et leurs étapes d'optimisation ci-dessous. +======= +The codegen-based optimizer affects the initial low-level code produced from the Solidity input. +In the legacy pipeline, the bytecode is generated immediately and most of the optimizations of this +kind are implicit and not configurable, the only exception being an optimization which changes the +order of literals in binary operations. +The IR-based pipeline takes a different approach and produces Yul IR closely matching the structure +of the Solidity code, with nearly all optimizations deferred to the Yul optimizer module. +In that case codegen-level optimization is done only in very limited cases which are difficult to +handle in Yul IR, but are straightforward with the high-level information from analysis phase at hand. +An example of such an optimization is the bypass of checked arithmetic when incrementing the counter +in certain idiomatic ``for`` loops. + +Currently, the parameter ``--optimize`` activates the opcode-based optimizer for the +generated bytecode and the Yul optimizer for the Yul code generated internally, for example for ABI coder v2. +One can use ``solc --ir-optimized --optimize`` to produce an +optimized Yul IR for a Solidity source. Similarly, one can use ``solc --strict-assembly --optimize`` +for a stand-alone Yul mode. + +.. note:: + Some optimizer steps, such as, for example, the `peephole optimizer `_ + and the :ref:`unchecked loop increment optimizer ` are always + enabled by default and can only be turned off via the :ref:`Standard JSON `. + +.. note:: + An empty optimizer sequence is accepted even without ``--optimize`` in order to fully disable + the user-supplied portion of the Yul :ref:`optimizer sequence `, as by default, + even when the optimizer is not turned on, the :ref:`unused pruner ` step will be run. + +You can find more details on both optimizer modules and their optimization steps below. +>>>>>>> english/develop Avantages de l'optimisation du code Solidity ============================================ @@ -275,60 +314,100 @@ Les étapes de transformation suivantes sont les principaux composants : - Eliminateur d'assignation redondante - Inliner complet +<<<<<<< HEAD Étapes de l'optimiseur ---------------------- +======= +.. _optimizer-steps: + +Optimizer Steps +--------------- +>>>>>>> english/develop Il s'agit d'une liste de toutes les étapes de l'optimiseur basé sur Yul, classées par ordre alphabétique. Vous pouvez trouver plus d'informations sur les étapes individuelles et leur séquence ci-dessous. -- :ref:`block-flattener`. -- :ref:`circular-reference-pruner`. -- :ref:`common-subexpression-eliminator`. -- :ref:`conditional-simplifier`. -- :ref:`conditional-unsimplifier`. -- :ref:`control-flow-simplifier`. -- :ref:`dead-code-eliminator`. -- :ref:`equal-store-eliminator`. -- :ref:`equivalent-function-combiner`. -- :ref:`expression-joiner`. -- :ref:`expression-simplifier`. -- :ref:`expression-splitter`. -- :ref:`for-loop-condition-into-body`. -- :ref:`for-loop-condition-out-of-body`. -- :ref:`for-loop-init-rewriter`. -- :ref:`expression-inliner`. -- :ref:`full-inliner`. -- :ref:`function-grouper`. -- :ref:`function-hoister`. -- :ref:`function-specializer`. -- :ref:`literal-rematerialiser`. -- :ref:`load-resolver`. -- :ref:`loop-invariant-code-motion`. -- :ref:`redundant-assign-eliminator`. -- :ref:`reasoning-based-simplifier`. -- :ref:`rematerialiser`. -- :ref:`SSA-reverser`. -- :ref:`SSA-transform`. -- :ref:`structural-simplifier`. -- :ref:`unused-function-parameter-pruner`. -- :ref:`unused-pruner`. -- :ref:`var-decl-initializer`. +============ =============================== +Abbreviation Full name +============ =============================== +``f`` :ref:`block-flattener` +``l`` :ref:`circular-reference-pruner` +``c`` :ref:`common-subexpression-eliminator` +``C`` :ref:`conditional-simplifier` +``U`` :ref:`conditional-unsimplifier` +``n`` :ref:`control-flow-simplifier` +``D`` :ref:`dead-code-eliminator` +``E`` :ref:`equal-store-eliminator` +``v`` :ref:`equivalent-function-combiner` +``e`` :ref:`expression-inliner` +``j`` :ref:`expression-joiner` +``s`` :ref:`expression-simplifier` +``x`` :ref:`expression-splitter` +``I`` :ref:`for-loop-condition-into-body` +``O`` :ref:`for-loop-condition-out-of-body` +``o`` :ref:`for-loop-init-rewriter` +``i`` :ref:`full-inliner` +``g`` :ref:`function-grouper` +``h`` :ref:`function-hoister` +``F`` :ref:`function-specializer` +``T`` :ref:`literal-rematerialiser` +``L`` :ref:`load-resolver` +``M`` :ref:`loop-invariant-code-motion` +``r`` :ref:`redundant-assign-eliminator` +``m`` :ref:`rematerialiser` +``V`` :ref:`SSA-reverser` +``a`` :ref:`SSA-transform` +``t`` :ref:`structural-simplifier` +``p`` :ref:`unused-function-parameter-pruner` +``S`` :ref:`unused-store-eliminator` +``u`` :ref:`unused-pruner` +``d`` :ref:`var-decl-initializer` +============ =============================== + +Some steps depend on properties ensured by ``BlockFlattener``, ``FunctionGrouper``, ``ForLoopInitRewriter``. +For this reason the Yul optimizer always applies them before applying any steps supplied by the user. + +.. _selecting-optimizations: Sélection des optimisations --------------------------- +<<<<<<< HEAD Par défaut, l'optimiseur applique sa séquence prédéfinie d'étapes d'optimisation à l'assemblage généré. Vous pouvez remplacer cette séquence et fournir la vôtre en utilisant l'option ``--yul-optimizations`` : +======= +By default the optimizer applies its predefined sequence of optimization steps to the generated assembly. +You can override this sequence and supply your own using the ``--yul-optimizations`` option: +>>>>>>> english/develop .. code-block:: bash - solc --optimize --ir-optimized --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul' + solc --optimize --ir-optimized --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul:fDnTOcmu' + +The order of steps is significant and affects the quality of the output. +Moreover, applying a step may uncover new optimization opportunities for others that were already applied, +so repeating steps is often beneficial. +<<<<<<< HEAD La séquence à l'intérieur de ``[...]`` sera appliquée plusieurs fois dans une boucle jusqu'à ce que le code Yul reste inchangé ou jusqu'à ce que le nombre maximum de tours (actuellement 12) ait été atteint. Les abréviations disponibles sont listées dans les docs `Yul optimizer `_. +======= +The sequence inside ``[...]`` will be applied multiple times in a loop until the Yul code +remains unchanged or until the maximum number of rounds (currently 12) has been reached. +Brackets (``[]``) may be used multiple times in a sequence, but can not be nested. + +An important thing to note, is that there are some hardcoded steps that are always run before and after the +user-supplied sequence, or the default sequence if one was not supplied by the user. + +The cleanup sequence delimiter ``:`` is optional, and is used to supply a custom cleanup sequence +in order to replace the default one. If omitted, the optimizer will simply apply the default cleanup +sequence. In addition, the delimiter may be placed at the beginning of the user-supplied sequence, +which will result in the optimization sequence being empty, whereas conversely, if placed at the end of +the sequence, will be treated as an empty cleanup sequence. +>>>>>>> english/develop Prétraitement ------------- @@ -543,9 +622,15 @@ Elle n'est pas appliquée à la condition d'itération de la boucle, car le flux ce "contournement" des expressions internes dans tous les cas. Nous pouvons contourner cette limitation en appliquant la :ref:`condition-boucle-for-dans-corps` pour déplacer la condition d'itération dans le corps de la boucle. +<<<<<<< HEAD Le programme final doit être sous une forme telle que (à l'exception des conditions de boucle) les appels de fonction ne peuvent pas être imbriqués dans des expressions et tous les arguments des appels de fonction doivent être des variables. +======= +The final program should be in an *expression-split form*, where (with the exception of loop conditions) +function calls cannot appear nested inside expressions +and all function call arguments have to be variables. +>>>>>>> english/develop Les avantages de cette forme sont qu'il est beaucoup plus facile de réorganiser la séquence des opcodes et il est également plus facile d'effectuer l'inlining des appels de fonction. En outre, il est plus simple @@ -680,7 +765,7 @@ Les valeurs conflictuelles sont résolues de la manière suivante : - "unused", "undecided" -> "undecided" - "unused", "used" -> "used" -- "undecided, "used" -> "used" +- "undecided", "used" -> "used" Pour les boucles for, la condition, le corps et la partie post sont visités deux fois, en tenant compte du flux de contrôle de jonction à la condition. @@ -793,12 +878,18 @@ si l'éliminateur de sous-expressions communes a été exécuté juste avant lui .. _expression-simplifier: -Expression Simplifier -^^^^^^^^^^^^^^^^^^^^^ +ExpressionSimplifier +^^^^^^^^^^^^^^^^^^^^ +<<<<<<< HEAD Le simplificateur d'expression utilise l'analyseur de flux de données et utilise d'une liste de transformations d'équivalence sur des expressions comme ``X + 0 -> X`` pour simplifier le code. +======= +The ExpressionSimplifier uses the Dataflow Analyzer and makes use +of a list of equivalence transforms on expressions like ``X + 0 -> X`` +to simplify the code. +>>>>>>> english/develop Il essaie de faire correspondre des motifs comme ``X + 0`` sur chaque sous-expression. Au cours de la procédure de correspondance, il résout les variables en fonction de leur @@ -830,6 +921,7 @@ Fonctionne mieux si le code est sous forme SSA. Prérequis : Disambiguator, ForLoopInitRewriter. +<<<<<<< HEAD .. _reasoning-based-simplifier: ReasoningBasedSimplifier @@ -848,6 +940,10 @@ Prérequis : Disambiguator, SSATransform. Simplifications à l'échelle de la déclaration --------------------------------------------- +======= +Statement-Scale Simplifications +------------------------------- +>>>>>>> english/develop .. _circular-reference-pruner: @@ -925,8 +1021,13 @@ DeadCodeEliminator Cette étape d'optimisation supprime le code inaccessible. +<<<<<<< HEAD Le code inaccessible est tout code à l'intérieur d'un bloc qui est précédé d'une commande leave, return, invalid, break, continue, selfdestruct ou revert. +======= +Unreachable code is any code within a block which is preceded by a +leave, return, invalid, break, continue, selfdestruct, revert or by a call to a user-defined function that recurses infinitely. +>>>>>>> english/develop Les définitions de fonctions sont conservées car elles peuvent être appelées par du code précédent et sont donc considérées comme accessibles. @@ -1089,6 +1190,52 @@ L'étape LiteralRematerialiser n'est pas nécessaire pour l'exactitude. Elle per ``fonction f(x) -> y { revert(y, y} }`` où le littéral ``y`` sera remplacé par sa valeur ``0``, ce qui nous permet de réécrire la fonction. +.. index:: ! unused store eliminator +.. _unused-store-eliminator: + +UnusedStoreEliminator +^^^^^^^^^^^^^^^^^^^^^ + +Optimizer component that removes redundant ``sstore`` and memory store statements. +In case of an ``sstore``, if all outgoing code paths revert (due to an explicit ``revert()``, ``invalid()``, or infinite recursion) or +lead to another ``sstore`` for which the optimizer can tell that it will overwrite the first store, the statement will be removed. +However, if there is a read operation between the initial ``sstore`` and the revert, or the overwriting ``sstore``, the statement +will not be removed. +Such read operations include: external calls, user-defined functions with any storage access, and ``sload`` of a slot that cannot be +proven to differ from the slot written by the initial ``sstore``. + +For example, the following code + +.. code-block:: yul + + { + let c := calldataload(0) + sstore(c, 1) + if c { + sstore(c, 2) + } + sstore(c, 3) + } + +will be transformed into the code below after the Unused Store Eliminator step is run + +.. code-block:: yul + + { + let c := calldataload(0) + if c { } + sstore(c, 3) + } + +For memory store operations, things are generally simpler, at least in the outermost yul block as all such +statements will be removed if they are never read from in any code path. +At function analysis level, however, the approach is similar to ``sstore``, as we do not know whether the memory location will +be read once we leave the function's scope, so the statement will be removed only if all code paths lead to a memory overwrite. + +Best run in SSA form. + +Prerequisites: Disambiguator, ForLoopInitRewriter. + .. _equivalent-function-combiner: EquivalentFunctionCombiner @@ -1134,6 +1281,7 @@ Ce composant ne peut être utilisé que sur des sources ayant des noms uniques. FullInliner ^^^^^^^^^^^ +<<<<<<< HEAD Le Full Inliner remplace certains appels de certaines fonctions par le corps de la fonction. Ceci n'est pas très utile dans la plupart des cas, car cela ne fait qu'augmenter la taille du code sans en tirer aucun avantage. De plus, @@ -1141,6 +1289,15 @@ le code est généralement très coûteux et nous préférons souvent avoir un code plus court qu'un code plus efficace. Dans certains cas, cependant, l'inlining d'une fonction peut avoir des effets positifs sur les étapes suivantes de l'optimiseur. C'est le cas si l'un des arguments de la fonction est une constante, par exemple. +======= +The FullInliner replaces certain calls of certain functions +by the function's body. This is not very helpful in most cases, because +it just increases the code size but does not have a benefit. Furthermore, +code is usually very expensive and we would often rather have shorter +code than more efficient code. In same cases, though, inlining a function +can have positive effects on subsequent optimizer steps. This is the case +if one of the function arguments is a constant, for example. +>>>>>>> english/develop Pendant l'inlining, une heuristique est utilisée pour déterminer si l'appel de fonction doit être inline ou non. @@ -1158,8 +1315,18 @@ nous pouvons exécuter l'optimiseur sur cette fonction spécialisée. Si cela résulte en des gains importants, la fonction spécialisée est conservée, sinon la fonction originale est utilisée à la place. +<<<<<<< HEAD Nettoyage --------- +======= +FunctionHoister and ExpressionSplitter are recommended as prerequisites since they make the step +more efficient, but are not required for correctness. +In particular, function calls with other function calls as arguments are not inlined, but running +ExpressionSplitter beforehand ensures that there are no such calls in the input. + +Cleanup +------- +>>>>>>> english/develop Le nettoyage est effectué à la fin de l'exécution de l'optimiseur. Il essaie de combiner à nouveau les expressions divisées en expressions profondément imbriquées, @@ -1200,10 +1367,17 @@ Il s'agit d'un petit pas qui permet d'inverser les effets de la transformation S si elle est combinée avec l'Éliminateur de sous-expression commune et l'Éliminateur d'élagueurs inutilisés. +<<<<<<< HEAD La forme SSA que nous générons est préjudiciable à la génération de code sur l'EVM et sur WebAssembly car elle génère de nombreuses variables locales. Il serait préférable de réutiliser les variables existantes avec des affectations au lieu de de nouvelles déclarations de variables. +======= +The SSA form we generate is detrimental to code generation +because it produces many local variables. It would +be better to just re-use existing variables with assignments instead of +fresh variable declarations. +>>>>>>> english/develop La transformation SSA réécrit @@ -1320,14 +1494,74 @@ en Le LiteralRematerialiser doit être exécuté avant cette étape. +Codegen-Based Optimizer Module +============================== +<<<<<<< HEAD Spécifique à WebAssembly ------------------------ +======= +Currently, the codegen-based optimizer module provides two optimizations. +>>>>>>> english/develop -MainFunction -^^^^^^^^^^^^ +The first one, available in the legacy code generator, moves literals to the right side of +commutative binary operators, which helps exploit their associativity. +<<<<<<< HEAD Change le bloc le plus haut en une fonction avec un nom spécifique ("main") qui n'a ni entrées ni sorties. Dépend du Function Grouper. +======= +The other one, available in the IR-based code generator, enables the use of unchecked arithmetic +when generating code for incrementing the counter variable of certain idiomatic ``for`` loops. +This avoids wasting gas by identifying some conditions that guarantee that the counter variable +cannot overflow. +This eliminates the need to use a verbose unchecked arithmetic block inside the loop body to +increment the counter variable. + +.. _unchecked-loop-optimizer: + +Unchecked Loop Increment +------------------------ + +Introduced in Solidity ``0.8.22``, the overflow check optimization step is concerned with identifying +the conditions under which the ``for`` loop counter can be safely incremented +without overflow checks. + +This optimization is **only** applied to ``for`` loops of the general form: + +.. code-block:: solidity + + for (uint i = X; i < Y; ++i) { + // variable i is not modified in the loop body + } + +The condition and the fact that the counter variable is only ever incremented +guarantee that it never overflows. +The precise requirements for the loop to be eligible for the optimization are as follows: + +- The loop condition is a comparison of the form ``i < Y``, for a local counter variable ``i`` + (called the "loop counter" hereon) and an expression ``Y``. +- The built-in operator ``<`` is necessarily used in the loop condition and is the only operator + that triggers the optimization. ``<=`` and the like are intentionally excluded. Additionally, + user-defined operators are **not** eligible. +- The loop expression is a prefix or postfix increment of the counter variable, i.e, ``i++`` or ``++i``. +- The loop counter is a local variable of a built-in integer type. +- The loop counter is **not** modified by the loop body or by the expression used as the loop condition. +- The comparison is performed on the same type as the loop counter, meaning that the type of the + right-hand-side expression is implicitly convertible to the type of the counter, such that the latter + is not implicitly widened before the comparison. + +To clarify the last condition, consider the following example: + +.. code-block:: solidity + + for (uint8 i = 0; i < uint16(1000); i++) { + // ... + } + +In this case, the counter ``i`` has its type implicitly converted from ``uint8`` +to ``uint16`` before the comparison and the condition is in fact never false, so +the overflow check for the increment cannot be removed. +>>>>>>> english/develop diff --git a/docs/internals/source_mappings.rst b/docs/internals/source_mappings.rst index 8a30f6e86a..4cea02c828 100644 --- a/docs/internals/source_mappings.rst +++ b/docs/internals/source_mappings.rst @@ -26,10 +26,17 @@ qui ne font pas partie de l'entrée d'origine mais sont référencés à partir Ces fichiers sources ainsi que leurs identifiants peuvent être obtenu via ``output['contracts'][sourceName][contractName]['evm']['bytecode']['generatedSources']``. +<<<<<<< HEAD .. note :: Dans le cas d'instructions qui ne sont associées à aucun fichier source particulier, le mappage source attribue un identifiant entier de ``-1``. Cela peut arriver pour sections de bytecode issues d'instructions d'assemblage en ligne générées par le compilateur. +======= +.. note:: + In the case of instructions that are not associated with any particular source file, + the source mapping assigns an integer identifier of ``-1``. This may happen for + bytecode sections stemming from compiler-generated inline assembly statements. +>>>>>>> english/develop Les SourceMap à l'intérieur de l'AST utilisent la notation suivantes diff --git a/docs/internals/variable_cleanup.rst b/docs/internals/variable_cleanup.rst index e2ed9c74d2..6dd3712708 100644 --- a/docs/internals/variable_cleanup.rst +++ b/docs/internals/variable_cleanup.rst @@ -4,6 +4,7 @@ Nettoyer les variables ********************* +<<<<<<< HEAD Lorsqu'une valeur est inférieure à 256 bits, dans certains cas, les bits restants doivent être nettoyé. Le compilateur Solidity est conçu pour nettoyer ces bits restants avant toute opération @@ -13,6 +14,18 @@ Par exemple, avant d'écrire une valeur en mémoire, les bits restants doivent hachages ou être envoyés en tant que données d'un appel de fonction. De même, avant de stocker une valeur dans le stockage, les bits restants doivent être nettoyés car sinon des valeurs brouillées peuvent être observées. +======= +Ultimately, all values in the EVM are stored in 256 bit words. +Thus, in some cases, when the type of a value has less than 256 bits, +it is necessary to clean the remaining bits. +The Solidity compiler is designed to do such cleaning before any operations +that might be adversely affected by the potential garbage in the remaining bits. +For example, before writing a value to memory, the remaining bits need +to be cleared because the memory contents can be used for computing +hashes or sent as the data of a message call. Similarly, before +storing a value in the storage, the remaining bits need to be cleaned +because otherwise the garbled value can be observed. +>>>>>>> english/develop Notez que l'accès via assembly dans le code Solidity n'est pas considéré comme une telle opération : Si vous utilisez assembly dans votre code pour accéder aux variables Solidity @@ -28,6 +41,7 @@ les valeurs booléennes avant qu'elles ne soient utilisées comme condition pour En plus du principe ci-dessus, le compilateur Solidity nettoie les données d'entrée lorsqu'elles sont chargées sur la stack. +<<<<<<< HEAD Différents types ont des règles différentes pour nettoyer les valeurs non valides : +---------------+---------------+-----------------------------+ @@ -52,3 +66,85 @@ Différents types ont des règles différentes pour nettoyer les valeurs non val +---------------+---------------+-----------------------------+ * enveloppe actuellement silencieusement ; à l'avenir, des exceptions seront levées +======= +The following table describes the cleaning rules applied to different types, +where ``higher bits`` refers to the remaining bits in case the type has less than 256 bits. + ++---------------+---------------+-------------------------+ +|Type |Valid Values |Cleanup of Invalid Values| ++===============+===============+=========================+ +|enum of n |0 until n - 1 |throws exception | +|members | | | ++---------------+---------------+-------------------------+ +|bool |0 or 1 |results in 1 | ++---------------+---------------+-------------------------+ +|signed integers|higher bits |currently silently | +| |set to the |signextends to a valid | +| |sign bit |value, i.e. all higher | +| | |bits are set to the sign | +| | |bit; may throw an | +| | |exception in the future | ++---------------+---------------+-------------------------+ +|unsigned |higher bits |currently silently masks | +|integers |zeroed |to a valid value, i.e. | +| | |all higher bits are set | +| | |to zero; may throw an | +| | |exception in the future | ++---------------+---------------+-------------------------+ + +Note that valid and invalid values are dependent on their type size. +Consider ``uint8``, the unsigned 8-bit type, which has the following valid values: + +.. code-block:: none + + 0000...0000 0000 0000 + 0000...0000 0000 0001 + 0000...0000 0000 0010 + .... + 0000...0000 1111 1111 + +Any invalid value will have the higher bits set to zero: + +.. code-block:: none + + 0101...1101 0010 1010 invalid value + 0000...0000 0010 1010 cleaned value + +For ``int8``, the signed 8-bit type, the valid values are: + +Negative + +.. code-block:: none + + 1111...1111 1111 1111 + 1111...1111 1111 1110 + .... + 1111...1111 1000 0000 + +Positive + +.. code-block:: none + + 0000...0000 0000 0000 + 0000...0000 0000 0001 + 0000...0000 0000 0010 + .... + 0000...0000 1111 1111 + +The compiler will ``signextend`` the sign bit, which is 1 for negative and 0 for +positive values, overwriting the higher bits: + +Negative + +.. code-block:: none + + 0010...1010 1111 1111 invalid value + 1111...1111 1111 1111 cleaned value + +Positive + +.. code-block:: none + + 1101...0101 0000 0100 invalid value + 0000...0000 0000 0100 cleaned value +>>>>>>> english/develop diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index 0a202eef8d..a5728913bc 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -8,9 +8,15 @@ Introduction Aux Smart Contracts Un Simple Smart Contract *********************** +<<<<<<< HEAD Commençons par un exemple de base qui définit la valeur d'une variable et l'expose à l'accès d'autres contrats. Ce n'est pas grave si vous ne comprenez pas tout de suite, nous entrerons dans les détails plus tard. +======= +Let us begin with a basic example that sets the value of a variable and exposes +it for other contracts to access. It is fine if you do not understand +everything right now, we will go into more details later. +>>>>>>> english/develop Exemple de stockage =============== @@ -91,7 +97,7 @@ s'enregistrer avec un nom d'utilisateur et un mot de passe, tout ce dont vous av // Le mot clé "public" rend les variables // accessibles depuis d'autres contrats address public minter; - mapping (address => uint) public balances; + mapping(address => uint) public balances; // Les événements permettent aux clients de réagir à des // changements de contrat que vous déclarez @@ -151,9 +157,15 @@ Vous n'avez pas besoin de le faire, le compilateur s'en charge pour vous. .. index:: mapping +<<<<<<< HEAD La ligne suivante, ``mapping (adresse => uint) public balances;`` crée également une variable d'état publique, mais il s'agit d'un type de données plus complexe. Le type :ref:`mapping ` fait correspondre les adresses aux :ref:``internes non signés `. +======= +The next line, ``mapping(address => uint) public balances;`` also +creates a public state variable, but it is a more complex datatype. +The :ref:`mapping ` type maps addresses to :ref:`unsigned integers `. +>>>>>>> english/develop Les mappings peuvent être vus comme des `tableaux de hachage `_ qui sont initialisées virtuellement, de telle sorte que chaque clé possible existe dès le départ et est mise en correspondance avec une @@ -168,8 +180,8 @@ suivante : .. code-block:: solidity - function balances(address _account) external view returns (uint) { - return balances[_account]; + function balances(address account) external view returns (uint) { + return balances[account]; } Vous pouvez utiliser cette fonction pour demander le solde d'un seul compte. @@ -184,9 +196,17 @@ coût. Dès que l'événement est émis, l'écouteur reçoit les arguments "from", "to" et "amount", ce qui permet de suivre les transactions. +<<<<<<< HEAD Pour écouter cet événement, vous pouvez utiliser le code suivant Du code JavaScript, qui utilise `web3.js `_ pour créer l'objet du contrat ``Coin``, et toute interface utilisateur appelle la fonction ``balances`` générée automatiquement ci-dessus:: +======= +To listen for this event, you could use the following +JavaScript code, which uses `web3.js `_ to create the ``Coin`` contract object, +and any user interface calls the automatically generated ``balances`` function from above: + +.. code-block:: javascript +>>>>>>> english/develop Coin.Sent().watch({}, '', function(error, result) { if (!error) { @@ -220,6 +240,7 @@ déborde, c'est-à-dire lorsque ``balances[receiver] + amount`` en arithmétique que la valeur maximale de ``uint`` (``2**256 - 1``). Ceci est également vrai pour l'instruction ``balances[receiver] += amount;`` dans la fonction ``send``. +<<<<<<< HEAD :ref:`Les erreurs ` vous permettent de fournir plus d'informations à l'appelant sur pourquoi une condition ou une opération a échoué. Les erreurs sont utilisées avec l'instruction :ref:`revert statement `. L'instruction revert interrompt et annule sans condition @@ -227,6 +248,15 @@ inconditionnellement et annule toutes les modifications, de manière similaire mais elle vous permet également de fournir le nom d'une erreur et des données supplémentaires qui seront fournies à l'appelant (et éventuellement à l'application frontale ou à l'explorateur de blocs) afin qu'un l'application frontale ou l'explorateur de blocs) afin de pouvoir déboguer ou réagir plus facilement à un échec. +======= +:ref:`Errors ` allow you to provide more information to the caller about +why a condition or operation failed. Errors are used together with the +:ref:`revert statement `. The ``revert`` statement unconditionally +aborts and reverts all changes similar to the ``require`` function, but it also +allows you to provide the name of an error and additional data which will be supplied to the caller +(and eventually to the front-end application or block explorer) so that +a failure can more easily be debugged or reacted upon. +>>>>>>> english/develop La fonction "envoyer" peut être utilisée par n'importe qui (qui possède déjà certaines de ces pièces) pour envoyer un message à un autre utilisateur. qui possède déjà certaines de ces pièces) pour envoyer des pièces à quelqu'un d'autre. Si l'expéditeur @@ -277,10 +307,17 @@ soustrait d'un compte, il est toujours ajouté à l'autre compte. Si pour pour une raison quelconque, l'ajout du montant au compte cible n'est pas possible, le compte source n'est pas non plus modifié. +<<<<<<< HEAD En outre, une transaction est toujours signée de manière cryptographique par l'expéditeur (créateur). Cela permet de protéger facilement l'accès à certaines modifications de la base de données. Dans l'exemple de la monnaie électronique, un simple contrôle permet de s'assurer que seule la personne détenant les clés du compte peut transférer de l'argent depuis celui-ci. +======= +Furthermore, a transaction is always cryptographically signed by the sender (creator). +This makes it straightforward to guard access to specific modifications of the +database. In the example of the electronic currency, a simple check ensures that +only the person holding the keys to the account can transfer some compensation, e.g. Ether, from it. +>>>>>>> english/develop .. index:: ! block @@ -298,9 +335,15 @@ puis elles seront exécutées et distribuées entre tous les nœuds participants Si deux transactions se contredisent, celle qui arrive en deuxième position sera rejetée et ne fera pas partie du bloc. +<<<<<<< HEAD Ces blocs forment une séquence linéaire dans le temps et c'est de là que vient le mot "blockchain". Les blocs sont ajoutés à la chaîne à intervalles assez réguliers. Ethereum, c'est à peu près toutes les 17 secondes. +======= +These blocks form a linear sequence in time, and that is where the word "blockchain" derives from. +Blocks are added to the chain at regular intervals, although these intervals may be subject to change in the future. +For the most up-to-date information, it is recommended to monitor the network, for example, on `Etherscan `_. +>>>>>>> english/develop Dans le cadre du "mécanisme de sélection des ordres" (appelé "minage"), il peut arriver que des blocs soient révoqués de temps en temps, mais seulement à la "pointe" de la chaîne. Plus de @@ -395,6 +438,7 @@ renvoie ce code lorsqu'il est exécuté. Gas === +<<<<<<< HEAD Lors de sa création, chaque transaction est chargée d'une certaine quantité de **gaz**, dont le but est de limiter la quantité de travail nécessaire pour exécuter la transaction et de payer en même temps pour cette exécution. Pendant que l'EVM exécute la @@ -407,14 +451,41 @@ S'il reste du gaz après l'exécution, il est remboursé au créateur de la mêm Si le gaz est épuisé à un moment donné (c'est-à-dire qu'il serait négatif), une exception pour épuisement du gaz est déclenchée, ce qui rétablit toutes les modifications apportées à l'état dans la trame d'appel actuelle. +======= +Upon creation, each transaction is charged with a certain amount of **gas** +that has to be paid for by the originator of the transaction (``tx.origin``). +While the EVM executes the +transaction, the gas is gradually depleted according to specific rules. +If the gas is used up at any point (i.e. it would be negative), +an out-of-gas exception is triggered, which ends execution and reverts all modifications +made to the state in the current call frame. +>>>>>>> english/develop + +This mechanism incentivizes economical use of EVM execution time +and also compensates EVM executors (i.e. miners / stakers) for their work. +Since each block has a maximum amount of gas, it also limits the amount +of work needed to validate a block. + +The **gas price** is a value set by the originator of the transaction, who +has to pay ``gas_price * gas`` up front to the EVM executor. +If some gas is left after execution, it is refunded to the transaction originator. +In case of an exception that reverts changes, already used up gas is not refunded. + +Since EVM executors can choose to include a transaction or not, +transaction senders cannot abuse the system by setting a low gas price. .. index:: ! storage, ! memory, ! stack Stockage, mémoire et pile ============================= +<<<<<<< HEAD La machine virtuelle d'Ethereum a trois zones où elle peut stocker des données- stockage, la mémoire et la pile, qui sont expliqués dans les paragraphes suivants. +======= +The Ethereum Virtual Machine has three areas where it can store data: +storage, memory and the stack. +>>>>>>> english/develop Chaque compte dispose d'une zone de données appelée **storage**, qui est persistante entre les appels de fonction et les transactions. @@ -492,8 +563,9 @@ complexes, les boucles doivent être préférées aux appels récursifs. En outr seuls 63/64ème du gaz peuvent être transmis dans un appel de message, ce qui entraîne une limite de profondeur d'un peu moins de 1000 en pratique. -.. index:: delegatecall, callcode, library +.. index:: delegatecall, library +<<<<<<< HEAD Delegatecall / Callcode et bibliothèques ===================================== @@ -501,6 +573,15 @@ Il existe une variante spéciale d'un appel de message, appelée **delegatecall* qui est identique à un appel de message, à l'exception du fait que le code à l'adresse cible est exécuté dans le contexte du contrat d'appel et appelant et que les valeurs de ``msg.sender`` et ``msg.value`` ne changent pas. +======= +Delegatecall and Libraries +========================== + +There exists a special variant of a message call, named **delegatecall** +which is identical to a message call apart from the fact that +the code at the target address is executed in the context (i.e. at the address) of the calling +contract and ``msg.sender`` and ``msg.value`` do not change their values. +>>>>>>> english/develop Cela signifie qu'un contrat peut charger dynamiquement du code provenant d'une autre différente au moment de l'exécution. Le stockage, l'adresse actuelle et le solde @@ -534,7 +615,7 @@ n'appellent pas simplement l'adresse zéro comme le ferait une transaction). La ces appels **create** et les appels de message normaux est que les données utiles sont exécutées et le résultat reçoit l'adresse du nouveau contrat sur la pile. -.. index:: selfdestruct, self-destruct, deactivate +.. index:: ! selfdestruct, deactivate Désactivation et autodestruction ============================ @@ -547,9 +628,20 @@ idée, mais elle est potentiellement dangereuse, car si quelqu'un envoie de l'Et contrats supprimés, l'Ether est perdu à jamais. .. warning:: +<<<<<<< HEAD Même si un contrat est supprimé par "autodestruction", il fait toujours partie de l'histoire de la blockchain et probablement conservé par la plupart des nœuds Ethereum. Ainsi, utiliser "l'autodestruction" n'est pas la même chose que de supprimer des données d'un disque dur. +======= + From version 0.8.18 and up, the use of ``selfdestruct`` in both Solidity and Yul will trigger a + deprecation warning, since the ``SELFDESTRUCT`` opcode will eventually undergo breaking changes in behavior + as stated in `EIP-6049 `_. + +.. warning:: + Even if a contract is removed by ``selfdestruct``, it is still part of the + history of the blockchain and probably retained by most Ethereum nodes. + So using ``selfdestruct`` is not the same as deleting data from a hard disk. +>>>>>>> english/develop .. note:: Même si le code d'un contrat ne contient pas d'appel à ``selfdestruct`', @@ -567,12 +659,21 @@ rend impossible l'utilisation du contrat, car il retourne immédiatement de l'Et Contrats précompilés ===================== +<<<<<<< HEAD Il existe un petit ensemble d'adresses de contrat qui sont spéciales : La plage d'adresses comprise entre ``1`` et (y compris) ``8`` contient des "contrats précompilés" qui peuvent être appelés comme n'importe quel autre contrat, mais leur comportement (et leur consommation de gaz) n'est pas défini par le code EVM stocké à cette adresse (ils ne contiennent pas de code), mais est plutôt mis en œuvre dans l'environnement d'exécution EVM lui-même. +======= +There is a small set of contract addresses that are special: +The address range between ``1`` and (including) ``8`` contains +"precompiled contracts" that can be called as any other contract +but their behavior (and their gas consumption) is not defined +by EVM code stored at that address (they do not contain code) +but instead is implemented in the EVM execution environment itself. +>>>>>>> english/develop Différentes chaînes compatibles EVM peuvent utiliser un ensemble différent de contrats précompilés. Il est également possible que de nouveaux diff --git a/docs/ir-breaking-changes.rst b/docs/ir-breaking-changes.rst index 578d72ad9b..9cfac68eb1 100644 --- a/docs/ir-breaking-changes.rst +++ b/docs/ir-breaking-changes.rst @@ -1,6 +1,8 @@ .. index: ir breaking changes +.. _ir-breaking-changes: + ********************************* Changements apportés au Codegen basé sur Solidity IR ********************************* @@ -13,6 +15,7 @@ Le générateur de code basé sur l'IR a été introduit dans le but non seuleme génération de code plus transparente et plus vérifiable, mais aussi de permettre des passes d'optimisation plus puissantes qui couvrent plusieurs fonctions. +<<<<<<< HEAD Actuellement, le générateur de code basé sur IR est toujours marqué comme expérimental, mais il supporte toutes les fonctionnalités du langage et a fait l'objet de nombreux tests. Nous considérons donc qu'il est presque prêt à être utilisé en production. @@ -25,6 +28,16 @@ Pour plusieurs raisons, il existe de minuscules différences sémantiques entre générateur de code basé sur l'IR, principalement dans des domaines où nous ne nous attendons pas à ce que les gens se fient à ce comportement de toute façon. Cette section met en évidence les principales différences entre l'ancien et le générateur de code basé sur la RI. +======= +You can enable it on the command-line using ``--via-ir`` +or with the option ``{"viaIR": true}`` in standard-json and we +encourage everyone to try it out! + +For several reasons, there are tiny semantic differences between the old +and the IR-based code generator, mostly in areas where we would not +expect people to rely on this behavior anyway. +This section highlights the main differences between the old and the IR-based codegen. +>>>>>>> english/develop Changements uniquement sémantiques ===================== @@ -32,6 +45,7 @@ Changements uniquement sémantiques Cette section énumère les changements qui sont uniquement sémantiques, donc potentiellement cacher un comportement nouveau et différent dans le code existant. +<<<<<<< HEAD - Lorsque les structures de stockage sont supprimées, chaque emplacement de stockage qui contient un membre de la structure est entièrement mis à zéro. Auparavant, l'espace de remplissage n'était pas modifié. @@ -39,6 +53,59 @@ cacher un comportement nouveau et différent dans le code existant. (par exemple, dans le contexte d'une mise à jour de contrat), vous devez être conscient que que ``delete`` effacera maintenant aussi le membre ajouté (alors qu'il n'aurait pas été effacé dans le passé). +======= +.. _state-variable-initialization-order: + +- The order of state variable initialization has changed in case of inheritance. + + The order used to be: + + - All state variables are zero-initialized at the beginning. + - Evaluate base constructor arguments from most derived to most base contract. + - Initialize all state variables in the whole inheritance hierarchy from most base to most derived. + - Run the constructor, if present, for all contracts in the linearized hierarchy from most base to most derived. + + New order: + + - All state variables are zero-initialized at the beginning. + - Evaluate base constructor arguments from most derived to most base contract. + - For every contract in order from most base to most derived in the linearized hierarchy: + + 1. Initialize state variables. + 2. Run the constructor (if present). + + This causes differences in contracts where the initial value of a state + variable relies on the result of the constructor in another contract: + + .. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.7.1; + + contract A { + uint x; + constructor() { + x = 42; + } + function f() public view returns(uint256) { + return x; + } + } + contract B is A { + uint public y = f(); + } + + Previously, ``y`` would be set to 0. This is due to the fact that we would first initialize state variables: First, ``x`` is set to 0, and when initializing ``y``, ``f()`` would return 0 causing ``y`` to be 0 as well. + With the new rules, ``y`` will be set to 42. We first initialize ``x`` to 0, then call A's constructor which sets ``x`` to 42. Finally, when initializing ``y``, ``f()`` returns 42 causing ``y`` to be 42. + +- When storage structs are deleted, every storage slot that contains + a member of the struct is set to zero entirely. Formerly, padding space + was left untouched. + Consequently, if the padding space within a struct is used to store data + (e.g. in the context of a contract upgrade), you have to be aware that + ``delete`` will now also clear the added member (while it wouldn't + have been cleared in the past). +>>>>>>> english/develop .. code-block:: solidity @@ -75,14 +142,19 @@ cacher un comportement nouveau et différent dans le code existant. // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0; contract C { - function f(uint _a) public pure mod() returns (uint _r) { - _r = _a++; + function f(uint a) public pure mod() returns (uint r) { + r = a++; } modifier mod() { _; _; } } +<<<<<<< HEAD Si vous exécutez ``f(0)`` dans l'ancien générateur de code, il retournera ``2``, alors qu'il retournera ``1`` en utilisant le nouveau générateur de code. +======= + If you execute ``f(0)`` in the old code generator, it will return ``1``, while + it will return ``0`` when using the new code generator. +>>>>>>> english/develop .. code-block:: solidity @@ -113,6 +185,7 @@ cacher un comportement nouveau et différent dans le code existant. - Nouveau générateur de code : ``0`` car tous les paramètres, y compris les paramètres de retour, seront ré-initialisés avant chaque évaluation ``_;``. +<<<<<<< HEAD - L'ordre d'initialisation des contrats a changé en cas d'héritage. L'ordre était auparavant le suivant : @@ -185,6 +258,8 @@ Cela entraîne des différences dans certains contrats, par exemple : Maintenant, il renvoie ``0x6465616462656566000000000000000000000000000000000000000000000010`` (il a une longueur correcte, et des éléments corrects, mais il ne contient pas de données superflues). +======= +>>>>>>> english/develop .. index:: ! evaluation order; expression - Pour l'ancien générateur de code, l'ordre d'évaluation des expressions n'est pas spécifié. @@ -198,15 +273,20 @@ Cela entraîne des différences dans certains contrats, par exemple : // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.1; contract C { - function preincr_u8(uint8 _a) public pure returns (uint8) { - return ++_a + _a; + function preincr_u8(uint8 a) public pure returns (uint8) { + return ++a + a; } } La fonction ``preincr_u8(1)`` retourne les valeurs suivantes : +<<<<<<< HEAD - Ancien générateur de code : 3 (``1 + 2``) mais la valeur de retour n'est pas spécifiée en général. - Nouveau générateur de code : 4 (``2 + 2``) mais la valeur de retour n'est pas garantie +======= + - Old code generator: ``3`` (``1 + 2``) but the return value is unspecified in general + - New code generator: ``4`` (``2 + 2``) but the return value is not guaranteed +>>>>>>> english/develop .. index:: ! evaluation order; function arguments @@ -219,11 +299,11 @@ Cela entraîne des différences dans certains contrats, par exemple : // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.1; contract C { - function add(uint8 _a, uint8 _b) public pure returns (uint8) { - return _a + _b; + function add(uint8 a, uint8 b) public pure returns (uint8) { + return a + b; } - function g(uint8 _a, uint8 _b) public pure returns (uint8) { - return add(++_a + ++_b, _a + _b); + function g(uint8 a, uint8 b) public pure returns (uint8) { + return add(++a + ++b, a + b); } } @@ -278,7 +358,11 @@ Cela entraîne des différences dans certains contrats, par exemple : } } +<<<<<<< HEAD La fonction `f()` se comporte comme suit : +======= + The function ``f()`` behaves as follows: +>>>>>>> english/develop - Ancien générateur de code : manque de gaz lors de la mise à zéro du contenu du tableau après la grande allocation de mémoire. - Nouveau générateur de code : retour en arrière en raison d'un débordement du pointeur de mémoire libre (ne tombe pas en panne sèche). @@ -323,13 +407,13 @@ Par exemple : // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.1; contract C { - function f(uint8 _a) public pure returns (uint _r1, uint _r2) + function f(uint8 a) public pure returns (uint r1, uint r2) { - _a = ~_a; + a = ~a; assembly { - _r1 := _a + r1 := a } - _r2 = _a; + r2 = a; } } @@ -338,6 +422,12 @@ La fonction ``f(1)`` renvoie les valeurs suivantes : - Ancien générateur de code: (``fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe``, ``00000000000000000000000000000000000000000000000000000000000000fe``) - Nouveau générateur de codes: (``00000000000000000000000000000000000000000000000000000000000000fe``, ``00000000000000000000000000000000000000000000000000000000000000fe``) +<<<<<<< HEAD Notez que, contrairement au nouveau générateur de code, l'ancien générateur de code n'effectue pas de nettoyage après l'affectation bit-non (``_a = ~_a``). Il en résulte que des valeurs différentes sont assignées (dans le bloc d'assemblage en ligne) à la valeur de retour ``_r1`` entre l'ancien et le nouveau générateur de code. Cependant, les deux générateurs de code effectuent un nettoyage avant que la nouvelle valeur de ``_a`` soit assignée à ``_r2``. +======= +Note that, unlike the new code generator, the old code generator does not perform a cleanup after the bit-not assignment (``a = ~a``). +This results in different values being assigned (within the inline assembly block) to return value ``r1`` between the old and new code generators. +However, both code generators perform a cleanup before the new value of ``a`` is assigned to ``r2``. +>>>>>>> english/develop diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst index 1f4c6115b8..0c6c6963c7 100644 --- a/docs/layout-of-source-files.rst +++ b/docs/layout-of-source-files.rst @@ -2,9 +2,15 @@ Mise en page d'un fichier source Solidity ******************************** +<<<<<<< HEAD Les fichiers sources peuvent contenir un nombre arbitraire de :ref:`définitions des contrats`, directives d'importation, :ref:`directives pragmatiques` et +======= +Source files can contain an arbitrary number of +:ref:`contract definitions`, import_ , +:ref:`pragma` and :ref:`using for` directives and +>>>>>>> english/develop :ref:`struct`, :ref:`enum`, :ref:`function`, :ref:`error` et :ref:`constant variable` définitions. @@ -25,8 +31,16 @@ Le compilateur ne valide pas que la licence fait partie de la `liste autorisée par SPDX `_, mais il inclut la chaîne fournie dans les :ref:`métadonnées du code source `. +<<<<<<< HEAD Si vous ne voulez pas spécifier une licence ou si le code source n'est pas pas open-source, veuillez utiliser la valeur spéciale ``UNLICENSED``. +======= +If you do not want to specify a license or if the source code is +not open-source, please use the special value ``UNLICENSED``. +Note that ``UNLICENSED`` (no usage allowed, not present in SPDX license list) +is different from ``UNLICENSE`` (grants all rights to everyone). +Solidity follows `the npm recommendation `_. +>>>>>>> english/develop Le fait de fournir ce commentaire ne vous libère bien sûr pas des autres obligations liées à la licence, comme l'obligation de mentionner @@ -36,8 +50,13 @@ détenteur du droit d'auteur original. Le commentaire est reconnu par le compilateur à n'importe quel endroit du fichier, mais il est recommandé de le placer en haut du fichier. +<<<<<<< HEAD Plus d'informations sur la façon d'utiliser les identifiants de licence SPDX peuvent être trouvées sur le site web de `SPDX `_. +======= +More information about how to use SPDX license identifiers +can be found at the `SPDX website `_. +>>>>>>> english/develop .. index:: ! pragma @@ -53,7 +72,7 @@ vous devez ajouter la directive pragma à tous vos fichiers si vous voulez l'act dans l'ensemble de votre projet. Si vous :ref:`import` un autre fichier, la directive pragma de ce fichier ne s'applique pas automatiquement au fichier d'importation. -.. index:: ! pragma, version +.. index:: ! pragma;version .. _version_pragma: @@ -88,12 +107,20 @@ celles-ci suivent la même syntaxe que celle utilisée par `npm >>>>>> english/develop ---------------- En utilisant ``pragma abicoder v1`` ou ``pragma abicoder v2``, vous pouvez choisir entre les deux implémentations du codeur et du décodeur ABI. +<<<<<<< HEAD Le nouveau codeur ABI (v2) est capable de coder et de décoder tableaux et structs. Il peut produire un code moins optimal et n'a pas été testé autant que l'ancien codeur, mais est considéré comme @@ -101,6 +128,14 @@ non expérimental à partir de Solidity 0.6.0. Vous devez toujours explicitement l'activer en utilisant ``pragma abicoder v2;``. Puisqu'il sera activé par défaut à partir de Solidity 0.8.0, il existe une option pour sélectionner l'ancien codeur en utilisant ``pragma abicoder v1;``. +======= +The new ABI coder (v2) is able to encode and decode arbitrarily nested +arrays and structs. Apart from supporting more types, it involves more extensive +validation and safety checks, which may result in higher gas costs, but also heightened +security. It is considered +non-experimental as of Solidity 0.6.0 and it is enabled by default starting +with Solidity 0.8.0. The old ABI coder can still be selected using ``pragma abicoder v1;``. +>>>>>>> english/develop L'ensemble des types supportés par le nouveau codeur est un sur-ensemble strict de ceux supportés par l'ancien. Les contrats qui l'utilisent peuvent interagir @@ -122,8 +157,7 @@ et émettra une erreur. Il suffit d'activer "abicoder v2" pour votre contrat pou en utilisant ``pragma experimental ABIEncoderV2``, mais il n'était pas possible de sélectionner explicitement le codeur v1 parce qu'il était par défaut. -.. index:: ! pragma, experimental - +.. index:: ! pragma; experimental .. _experimental_pragma: Pragma expérimental @@ -133,6 +167,7 @@ Le deuxième pragma est le pragma expérimental. Il peut être utilisé pour act des fonctionnalités du compilateur ou du langage qui ne sont pas encore activées par défaut. Les pragmes expérimentaux suivants sont actuellement supportés : +.. index:: ! pragma; ABIEncoderV2 ABIEncoderV2 ~~~~~~~~~~~~ @@ -141,6 +176,7 @@ Parce que le codeur ABI v2 n'est plus considéré comme expérimental, il peut être sélectionné via ``pragma abicoder v2`` (voir ci-dessus) depuis Solidity 0.7.4. +.. index:: ! pragma; SMTChecker .. _smt_checker: SMTChecker @@ -172,10 +208,17 @@ Importation d'autres fichiers sources Syntaxe et sémantique -------------------- +<<<<<<< HEAD Solidity prend en charge des déclarations d'importation pour aider à modulariser votre code. Ils sont similaires à celles disponibles en JavaScript (à partir de ES6). Cependant, Solidity ne supporte pas le concept de l'`exportation par défaut `_. +======= +Solidity supports import statements to help modularise your code that +are similar to those available in JavaScript +(from ES6 on). However, Solidity does not support the concept of +a `default export `_. +>>>>>>> english/develop Au niveau global, vous pouvez utiliser des déclarations d'importation de la forme suivante : diff --git a/docs/logo.svg b/docs/logo.svg index 86b9f4995b..19391843b4 100644 --- a/docs/logo.svg +++ b/docs/logo.svg @@ -1,27 +1,8 @@ - - - - -Vector 1 -Created with Sketch. - - - - - - - - - - - - + + + + + + + diff --git a/docs/make.bat b/docs/make.bat index bc06e706e0..d11deb3ffc 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -28,6 +28,7 @@ if "%1" == "help" ( echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. latexpdf to make LaTeX files and run them through pdflatex echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files @@ -155,16 +156,6 @@ if "%1" == "latexpdf" ( goto end ) -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %BUILDDIR%/.. - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 diff --git a/docs/metadata.rst b/docs/metadata.rst index ada22c0a4d..37d60381fc 100644 --- a/docs/metadata.rst +++ b/docs/metadata.rst @@ -6,6 +6,7 @@ Métadonnées du contrat .. index:: metadata, contract verification +<<<<<<< HEAD Le compilateur Solidity génère automatiquement un fichier JSON, le contrat qui contient des informations sur le contrat compilé. Vous pouvez utiliser ce fichier pour interroger la version du compilateur, les sources utilisées, l'ABI et la documentation NatSpec, @@ -28,10 +29,41 @@ manière lisible par l'homme. Des métadonnées correctement formatées doivent réduire les espaces blancs au minimum et trier les clés de tous les objets pour arriver à un formatage unique. Les commentaires ne sont pas autorisés et ne sont utilisés ici qu'à à des fins explicatives. +======= +The Solidity compiler automatically generates a JSON file. +The file contains two kinds of information about the compiled contract: + +- How to interact with the contract: ABI, and NatSpec documentation. +- How to reproduce the compilation and verify a deployed contract: + compiler version, compiler settings, and source files used. + +The compiler appends by default the IPFS hash of the metadata file to the end +of the runtime bytecode (not necessarily the creation bytecode) of each contract, +so that, if published, you can retrieve the file in an authenticated way without +having to resort to a centralized data provider. The other available options are +the Swarm hash and not appending the metadata hash to the bytecode. These can be +configured via the :ref:`Standard JSON Interface`. + +You have to publish the metadata file to IPFS, Swarm, or another service so +that others can access it. You create the file by using the ``solc --metadata`` +command together with the ``--output-dir`` parameter. Without the parameter, +the metadata will be written to standard output. +The metadata contains IPFS and Swarm references to the source code, so you have to +upload all source files in addition to the metadata file. For IPFS, the hash contained +in the CID returned by ``ipfs add`` (not the direct sha2-256 hash of the file) +shall match with the one contained in the bytecode. + +The metadata file has the following format. The example below is presented in a +human-readable way. Properly formatted metadata should use quotes correctly, +reduce whitespace to a minimum, and sort the keys of all objects in alphabetical order +to arrive at a canonical formatting. Comments are not permitted and are used here only for +explanatory purposes. +>>>>>>> english/develop .. code-block:: javascript { +<<<<<<< HEAD // Obligatoire : La version du format de métadonnées "version": "1", // Obligatoire : Langue du code source, sélectionne essentiellement une "sous-version" @@ -72,28 +104,149 @@ formatage unique. Les commentaires ne sont pas autorisés et ne sont utilisés i "remappings": [ ":g=/dir" ], // Facultatif : Paramètres de l'optimiseur. Les champs "enabled" et "runs" sont obsolètes // et ne sont fournis que pour des raisons de compatibilité ascendante. +======= + // Required: Details about the compiler, contents are specific + // to the language. + "compiler": { + // Optional: Hash of the compiler binary which produced this output + "keccak256": "0x123...", + // Required for Solidity: Version of the compiler + "version": "0.8.2+commit.661d1103" + }, + // Required: Source code language, basically selects a "sub-version" + // of the specification + "language": "Solidity", + // Required: Generated information about the contract. + "output": { + // Required: ABI definition of the contract. See "Contract ABI Specification" + "abi": [/* ... */], + // Required: NatSpec developer documentation of the contract. See https://docs.soliditylang.org/en/latest/natspec-format.html for details. + "devdoc": { + // Contents of the @author NatSpec field of the contract + "author": "John Doe", + // Contents of the @dev NatSpec field of the contract + "details": "Interface of the ERC20 standard as defined in the EIP. See https://eips.ethereum.org/EIPS/eip-20 for details", + "errors": { + "MintToZeroAddress()" : { + "details": "Cannot mint to zero address" + } + }, + "events": { + "Transfer(address,address,uint256)": { + "details": "Emitted when `value` tokens are moved from one account (`from`) toanother (`to`).", + "params": { + "from": "The sender address", + "to": "The receiver address", + "value": "The token amount" + } + } + }, + "kind": "dev", + "methods": { + "transfer(address,uint256)": { + // Contents of the @dev NatSpec field of the method + "details": "Returns a boolean value indicating whether the operation succeeded. Must be called by the token holder address", + // Contents of the @param NatSpec fields of the method + "params": { + "_value": "The amount tokens to be transferred", + "_to": "The receiver address" + }, + // Contents of the @return NatSpec field. + "returns": { + // Return var name (here "success") if exists. "_0" as key if return var is unnamed + "success": "a boolean value indicating whether the operation succeeded" + } + } + }, + "stateVariables": { + "owner": { + // Contents of the @dev NatSpec field of the state variable + "details": "Must be set during contract creation. Can then only be changed by the owner" + } + }, + // Contents of the @title NatSpec field of the contract + "title": "MyERC20: an example ERC20", + "version": 1 // NatSpec version + }, + // Required: NatSpec user documentation of the contract. See "NatSpec Format" + "userdoc": { + "errors": { + "ApprovalCallerNotOwnerNorApproved()": [ + { + "notice": "The caller must own the token or be an approved operator." + } + ] + }, + "events": { + "Transfer(address,address,uint256)": { + "notice": "`_value` tokens have been moved from `from` to `to`" + } + }, + "kind": "user", + "methods": { + "transfer(address,uint256)": { + "notice": "Transfers `_value` tokens to address `_to`" + } + }, + "version": 1 // NatSpec version + } + }, + // Required: Compiler settings. Reflects the settings in the JSON input during compilation. + // Check the documentation of standard JSON input's "settings" field + "settings": { + // Required for Solidity: File path and the name of the contract or library this + // metadata is created for. + "compilationTarget": { + "myDirectory/myFile.sol": "MyContract" + }, + // Required for Solidity. + "evmVersion": "london", + // Required for Solidity: Addresses for libraries used. + "libraries": { + "MyLib": "0x123123..." + }, + "metadata": { + // Reflects the setting used in the input json, defaults to "true" + "appendCBOR": true, + // Reflects the setting used in the input json, defaults to "ipfs" + "bytecodeHash": "ipfs", + // Reflects the setting used in the input json, defaults to "false" + "useLiteralContent": true + }, + // Optional: Optimizer settings. The fields "enabled" and "runs" are deprecated + // and are only given for backward-compatibility. +>>>>>>> english/develop "optimizer": { - "enabled": true, - "runs": 500, "details": { +<<<<<<< HEAD // peephole a la valeur par défaut "true". "peephole": true, // la valeur par défaut de l'inliner est "true". "inliner": true, // jumpdestRemover a la valeur par défaut "true". +======= + "constantOptimizer": false, + "cse": false, + "deduplicate": false, + // inliner defaults to "false" + "inliner": false, + // jumpdestRemover defaults to "true" +>>>>>>> english/develop "jumpdestRemover": true, "orderLiterals": false, - "deduplicate": false, - "cse": false, - "constantOptimizer": false, + // peephole defaults to "true" + "peephole": true, "yul": true, // Facultatif : Présent uniquement si "yul" est "true". "yulDetails": { - "stackAllocation": false, - "optimizerSteps": "dhfoDgvulfnTUtnIf..." + "optimizerSteps": "dhfoDgvulfnTUtnIf...", + "stackAllocation": false } - } + }, + "enabled": true, + "runs": 500 }, +<<<<<<< HEAD "metadata": { // Reflète le paramètre utilisé dans le json d'entrée, la valeur par défaut est false. "useLiteralContent": true, @@ -120,6 +273,32 @@ formatage unique. Les commentaires ne sont pas autorisés et ne sont utilisés i // Requis : Documentation du contrat par le développeur NatSpec "devdoc": [/* ... */] } +======= + // Required for Solidity: Sorted list of import remappings. + "remappings": [ ":g=/dir" ] + }, + // Required: Compilation source files/source units, keys are file paths + "sources": { + "destructible": { + // Required (unless "url" is used): literal contents of the source file + "content": "contract destructible is owned { function destroy() { if (msg.sender == owner) selfdestruct(owner); } }", + // Required: keccak256 hash of the source file + "keccak256": "0x234..." + }, + "myDirectory/myFile.sol": { + // Required: keccak256 hash of the source file + "keccak256": "0x123...", + // Optional: SPDX license identifier as given in the source file + "license": "MIT", + // Required (unless "content" is used, see above): Sorted URL(s) + // to the source file, protocol is more or less arbitrary, but an + // IPFS URL is recommended + "urls": [ "bzz-raw://7d7a...", "dweb:/ipfs/QmN..." ] + } + }, + // Required: The version of the metadata format + "version": 1 +>>>>>>> english/develop } .. warning:: @@ -139,6 +318,7 @@ formatage unique. Les commentaires ne sont pas autorisés et ne sont utilisés i Encodage du hachage des métadonnées dans le bytecode ============================================= +<<<<<<< HEAD Parce que nous pourrions supporter d'autres façons de récupérer le fichier de métadonnées à l'avenir, le mappage ``{"ipfs" : , "solc" : }`` est stockée `CBOR `_-encodé. Puisque la cartographie peut @@ -146,9 +326,17 @@ contenir plus de clés (voir ci-dessous) et que le début de cet encodage n'est pas facile à trouver, sa longueur est ajoutée dans un encodage big-endian de deux octets. La version actuelle du compilateur Solidity ajoute généralement l'élément suivant à la fin du bytecode déployé. +======= +The compiler currently by default appends the +`IPFS hash (in CID v0) `_ +of the canonical metadata file and the compiler version to the end of the bytecode. +Optionally, a Swarm hash instead of the IPFS, or an experimental flag is used. +Below are all the possible fields: +>>>>>>> english/develop -.. code-block:: text +.. code-block:: javascript +<<<<<<< HEAD 0xa2 0x64 'i' 'p' 'f' 's' 0x58 0x22 <34 octets hachage IPFS> 0x64 's' 'o' 'l' 'c' 0x43 @@ -160,8 +348,37 @@ pour correspondre à ce modèle et utiliser le hachage IPFS pour récupérer le Alors que les versions de solc utilisent un encodage de 3 octets de la version comme indiqué ci-dessus (un octet pour chaque numéro de version majeure, mineure et de patch), les versions préversées utiliseront à la place une chaîne de version complète incluant le hachage du commit et la date de construction. +======= + { + "ipfs": "", + // If "bytecodeHash" was "bzzr1" in compiler settings not "ipfs" but "bzzr1" + "bzzr1": "", + // Previous versions were using "bzzr0" instead of "bzzr1" + "bzzr0": "", + // If any experimental features that affect code generation are used + "experimental": true, + "solc": "" + } + +Because we might support other ways to retrieve the +metadata file in the future, this information is stored +`CBOR `_-encoded. The last two bytes in the bytecode +indicate the length of the CBOR encoded information. By looking at this length, the +relevant part of the bytecode can be decoded with a CBOR decoder. + +Check the `Metadata Playground `_ to see it in action. + +Whereas release builds of solc use a 3 byte encoding of the version as shown +above (one byte each for major, minor and patch version number), pre-release builds +will instead use a complete version string including commit hash and build date. +>>>>>>> english/develop + +The commandline flag ``--no-cbor-metadata`` can be used to skip metadata +from getting appended at the end of the deployed bytecode. Equivalently, the +boolean field ``settings.metadata.appendCBOR`` in Standard JSON input can be set to false. .. note:: +<<<<<<< HEAD Le mappage CBOR peut également contenir d'autres clés, il est donc préférable de décoder complètement les données plutôt que de se fier à ce qu'elles commencent par ``0xa264``. Par exemple, si des fonctionnalités expérimentales qui affectent la génération de code @@ -173,27 +390,48 @@ utiliseront à la place une chaîne de version complète incluant le hachage du ne comptez pas sur cette séquence pour commencer avec ``0xa2 0x64 'i' 'p' 'f' 's'``. Nous ajouterons peut-être des données supplémentaires à cette structure CBOR. +======= + The CBOR mapping can also contain other keys, so it is better to fully + decode the data by looking at the end of the bytecode for the CBOR length, + and to use a proper CBOR parser. Do not rely on it starting with ``0xa264`` + or ``0xa2 0x64 'i' 'p' 'f' 's'``. +>>>>>>> english/develop Utilisation pour la génération automatique d'interface et NatSpec ==================================================== +<<<<<<< HEAD Les métadonnées sont utilisées de la manière suivante : Un composant qui veut interagir avec un contrat (par exemple Mist ou tout autre porte-monnaie) récupère le code du contrat, à partir de là, le hachage IPFS/Swarm d'un fichier qui est ensuite récupéré. Ce fichier est décodé en JSON dans une structure comme ci-dessus. +======= +The metadata is used in the following way: A component that wants to interact +with a contract (e.g. a wallet) retrieves the code of the contract. +It decodes the CBOR encoded section containing the IPFS/Swarm hash of the +metadata file. With that hash, the metadata file is retrieved. That file +is JSON-decoded into a structure like above. +>>>>>>> english/develop Le composant peut alors utiliser l'ABI pour générer automatiquement une interface utilisateur rudimentaire pour le contrat. +<<<<<<< HEAD En outre, le portefeuille peut utiliser la documentation utilisateur NatSpec pour afficher un message de confirmation à l'utilisateur chaque fois qu'il interagit avec le contrat, ainsi qu'une demande d'autorisation pour la signature de la transaction. +======= +Furthermore, the wallet can use the NatSpec user documentation to display a +human-readable confirmation message to the user whenever they interact with +the contract, together with requesting authorization for the transaction signature. +>>>>>>> english/develop Pour plus d'informations, lisez :doc:`Format de la spécification en langage naturel d'Ethereum (NatSpec) `. Utilisation pour la vérification du code source ================================== +<<<<<<< HEAD Afin de vérifier la compilation, les sources peuvent être récupérées sur IPFS/Swarm via le lien dans le fichier de métadonnées. Le compilateur de la version correcte (qui est vérifié pour faire partie des compilateurs "officiels") @@ -206,3 +444,20 @@ selon l'interface et présentées à l'utilisateur. Dans le référentiel `sourcify `_ (`npm package `_) vous pouvez voir un exemple de code qui montre comment utiliser cette fonctionnalité. +======= +If pinned/published, it is possible to retrieve the metadata of the contract from IPFS/Swarm. +The metadata file also contains the URLs or the IPFS hashes of the source files, as well as +the compilation settings, i.e. everything needed to reproduce a compilation. + +With this information it is then possible to verify the source code of a contract by +reproducing the compilation, and comparing the bytecode from the compilation with +the bytecode of the deployed contract. + +This automatically verifies the metadata since its hash is part of the bytecode, as well +as the source codes, because their hashes are part of the metadata. Any change in the files +or settings would result in a different metadata hash. The metadata here serves +as a fingerprint of the whole compilation. + +`Sourcify `_ makes use of this feature for "full/perfect verification", +as well as pinning the files publicly on IPFS to be accessed with the metadata hash. +>>>>>>> english/develop diff --git a/docs/natspec-format.rst b/docs/natspec-format.rst index 289f4cf8cd..266bbe12e5 100644 --- a/docs/natspec-format.rst +++ b/docs/natspec-format.rst @@ -42,8 +42,14 @@ pour les besoins de NatSpec. - Pour Solidity, vous pouvez choisir ``///`` pour les commentaires d'une ou plusieurs lignes commentaires, ou ``/**`` et se terminant par ``*/``. +<<<<<<< HEAD - Pour Vyper, utilisez ``"""`` indenté jusqu'au contenu intérieur avec des commentaires. Voir la documentation de `Vyper `__. +======= +- For Vyper, use ``"""`` indented to the inner contents with bare + comments. See the `Vyper + documentation `__. +>>>>>>> english/develop L'exemple suivant montre un contrat et une fonction utilisant toutes les balises disponibles. @@ -55,7 +61,7 @@ L'exemple suivant montre un contrat et une fonction utilisant toutes les balises Ceci pourrait changer à l'avenir. -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.2 < 0.9.0; @@ -151,10 +157,13 @@ to the end-user as: Si une fonction est appelée et que la valeur 10 est attribuée à l'entrée ``a``. +<<<<<<< HEAD La spécification de ces expressions dynamiques n'entre pas dans le cadre de la documentation de Solidity. et vous pouvez en savoir plus à l'adresse suivante `le projet radspec `__. +======= +>>>>>>> english/develop .. _header-inheritance: Notes sur l'héritage @@ -180,7 +189,7 @@ l'autre à être utilisé par le développeur. Si le contrat ci-dessus est enregistré sous le nom de ``ex1.sol``, alors vous pouvez générer la documentation en utilisant : -.. code:: +.. code-block:: shell solc --userdoc --devdoc ex1.sol @@ -199,7 +208,7 @@ Documentation pour les utilisateurs La documentation ci-dessus produira la documentation utilisateur suivante Fichier JSON en sortie : -.. code:: +.. code-block:: json { "version" : 1, @@ -226,7 +235,7 @@ Documentation pour les développeurs Outre le fichier de documentation utilisateur, un fichier JSON de documentation pour les développeurs doit également être produit et doit ressembler à ceci : -.. code:: +.. code-block:: json { "version" : 1, diff --git a/docs/path-resolution.rst b/docs/path-resolution.rst index 30829d6d44..152eb61de9 100644 --- a/docs/path-resolution.rst +++ b/docs/path-resolution.rst @@ -21,7 +21,7 @@ unité source se voit attribuer un *nom d'unité source* unique qui est un ident Lorsque vous utilisez l'instruction :ref:`import `, vous spécifiez un *chemin d'accès à l'importation* qui fait référence à un nom d'unité source. -.. index:: ! import callback, ! Host Filesystem Loader +.. index:: ! import callback, ! Host Filesystem Loader, ! --no-import-callback .. _import-callback: Rappel d'importation @@ -36,6 +36,7 @@ Un callback d'importation est libre d'interpréter les noms d'unité source d'un S'il n'y a pas de callback disponible lorsqu'on en a besoin ou s'il ne parvient pas à localiser le code source, la compilation échoue. +<<<<<<< HEAD Le compilateur en ligne de commande fournit le *Host Filesystem Loader* - un rappel rudimentaire qui interprète un nom d'unité source comme un chemin dans le système de fichiers local. L'interface `JavaScript `_ n'en fournit pas par défaut, @@ -44,6 +45,17 @@ Ce mécanisme peut être utilisé pour obtenir du code source à partir d'emplac (qui peut même ne pas être accessible, par exemple lorsque le compilateur est exécuté dans un navigateur). Par exemple l'IDE `Remix `_ fournit un callback polyvalent qui vous permet `d'importer des fichiers à partir d'URL HTTP, IPFS et Swarm ou de vous référer directement à des paquets dans le registre NPM +======= +By default, the command-line compiler provides the *Host Filesystem Loader* - a rudimentary callback +that interprets a source unit name as a path in the local filesystem. +This callback can be disabled using the ``--no-import-callback`` command-line option. +The `JavaScript interface `_ does not provide any by default, +but one can be provided by the user. +This mechanism can be used to obtain source code from locations other than the local filesystem +(which may not even be accessible, e.g. when the compiler is running in a browser). +For example the `Remix IDE `_ provides a versatile callback that +lets you `import files from HTTP, IPFS and Swarm URLs or refer directly to packages in NPM registry +>>>>>>> english/develop `_. .. note:: @@ -138,8 +150,13 @@ Le contenu initial du VFS dépend de la façon dont vous invoquez le compilateur #. **Entrée standard** +<<<<<<< HEAD En ligne de commande, il est également possible de fournir la source en l'envoyant à l'entrée standard du compilateur : +======= + On the command-line it is also possible to provide the source by sending it to compiler's + standard input: +>>>>>>> english/develop .. code-block:: bash @@ -193,11 +210,19 @@ nom de l'unité source. .. note:: +<<<<<<< HEAD Le nom d'une unité source n'est qu'un identifiant et même si sa valeur ressemble à un chemin, il n'est pas soumis aux règles de normalisation que l'on peut attendre d'un shell. Tous les segments ``/./`` ou ``../`` ou les séquences de barres obliques multiples en font toujours partie. Lorsque la source est fournie via une interface JSON standard, il est tout à fait possible d'associer différents contenus à des noms d'unités de source qui feraient référence au même fichier sur le disque. +======= + A source unit name is just an identifier and even if its value happens to look like a path, it + is not subject to the normalization rules you would typically expect in a shell. + Any ``/./`` or ``/../`` segments or sequences of multiple slashes remain a part of it. + When the source is provided via Standard JSON interface it is entirely possible to associate + different content with source unit names that would refer to the same file on disk. +>>>>>>> english/develop Lorsque la source n'est pas disponible dans le système de fichiers virtuel, le compilateur transmet le nom de l'unité source à l'import callback. @@ -246,6 +271,7 @@ et qui est délimitée par deux séparateurs de chemin. Un séparateur est un slash avant ou le début/la fin de la chaîne. Par exemple, dans ``./abc/..//``, il y a trois segments de chemin : ``.``, ``abc`` et ``..``. +<<<<<<< HEAD Le compilateur calcule un nom d'unité source à partir du chemin d'importation de la manière suivante : 1. Un préfixe est d'abord calculé @@ -258,6 +284,17 @@ Le compilateur calcule un nom d'unité source à partir du chemin d'importation 2. Ensuite, le préfixe est ajouté au chemin d'importation normalisé. Si le préfixe n'est pas vide, une seule barre oblique est insérée entre lui et le chemin d'importation. +======= +The compiler resolves the import into a source unit name based on the import path, in the following way: + +#. We start with the source unit name of the importing source unit. +#. The last path segment with preceding slashes is removed from the resolved name. +#. Then, for every segment in the import path, starting from the leftmost one: + + - If the segment is ``.``, it is skipped. + - If the segment is ``..``, the last path segment with preceding slashes is removed from the resolved name. + - Otherwise, the segment (preceded by a single slash if the resolved name is not empty), is appended to the resolved name. +>>>>>>> english/develop L'élimination du dernier segment de chemin avec les barres obliques précédentes fonctionne comme suit : @@ -265,6 +302,7 @@ fonctionne comme suit : 1. Tout ce qui dépasse la dernière barre oblique est supprimé (c'est-à-dire que ``a/b//c.sol`` devient ``a/b//``). 2. Toutes les barres obliques de fin de ligne sont supprimées (par exemple, ``a/b//`` devient ``a/b``). +<<<<<<< HEAD Les règles de normalisation sont les mêmes que pour les chemins UNIX, à savoir : - Tous les segments internes ``.`` sont supprimés. @@ -275,6 +313,14 @@ Notez que la normalisation est effectuée uniquement sur le chemin d'importation Le nom de l'unité source du module d'importation qui est utilisé pour le préfixe n'est pas normalisé. Cela garantit que la partie ``protocol://`` ne se transforme pas en ``protocol:/`` si le fichier d'importation est identifié par une URL. +======= +Note that the process normalizes the part of the resolved source unit name that comes from the import path according +to the usual rules for UNIX paths, i.e. all ``.`` and ``..`` are removed and multiple slashes are +squashed into a single one. +On the other hand, the part that comes from the source unit name of the importing module remains unnormalized. +This ensures that the ``protocol://`` part does not turn into ``protocol:/`` if the importing file +is identified with a URL. +>>>>>>> english/develop Si vos chemins d'importation sont déjà normalisés, vous pouvez vous attendre à ce que l'algorithme ci-dessus produise des résultats très intuitifs. @@ -350,6 +396,7 @@ du compilateur. Normalisation et suppression des chemins CLI ------------------------------------ +<<<<<<< HEAD Sur la ligne de commande, le compilateur se comporte comme vous le feriez avec n'importe quel autre programme : Il accepte les chemins dans un format natif de la plate-forme et les chemins relatifs sont relatifs au répertoire de travail actuel. Les noms d'unités sources attribués aux fichiers dont les chemins sont spécifiés sur la ligne de commande, cependant, @@ -357,6 +404,16 @@ ne doivent pas changer simplement parce que le projet est compilé sur une plate compilateur a été invoqué à partir d'un répertoire différent. Pour cela, les chemins des fichiers sources provenant de la ligne de commande doivent être convertis en une forme canonique et, si possible, rendus relatifs au chemin de base ou à l'un des chemins d'inclusion. +======= +On the command-line the compiler behaves just as you would expect from any other program: +it accepts paths in a format native to the platform and relative paths are relative to the current +working directory. +The source unit names assigned to files whose paths are specified on the command-line, however, +should not change just because the project is being compiled on a different platform or because the +compiler happens to have been invoked from a different directory. +To achieve this, paths to source files coming from the command-line must be converted to a canonical +form, and, if possible, made relative to the base path or one of the include paths. +>>>>>>> english/develop Les règles de normalisation sont les suivantes : @@ -408,10 +465,17 @@ Le chemin de fichier résultant devient le nom de l'unité source. .. note:: +<<<<<<< HEAD Avant la version 0.8.8, la suppression des chemins d'accès de l'interface CLI n'était pas effectuée et la seule normalisation appliquée était la conversion des séparateurs de chemin. Lorsque vous travaillez avec des versions plus anciennes du compilateur, il est recommandé d'invoquer le compilateur à partir du chemin de base et de n'utiliser que des chemins relatifs sur la ligne de commande. +======= + Prior to version 0.8.8, CLI path stripping was not performed and the only normalization applied + was the conversion of path separators. + When working with older versions of the compiler it is recommended to invoke the compiler from + the base path and to only use relative paths on the command-line. +>>>>>>> english/develop .. index:: ! allowed paths, ! --allow-paths, remapping; target .. _allowed-paths: @@ -424,11 +488,19 @@ emplacements qui sont considérés comme sûrs par défaut : - En dehors du mode JSON standard : +<<<<<<< HEAD - Les répertoires contenant les fichiers d'entrée listés sur la ligne de commande. - Les répertoires utilisés comme cibles :ref:`remapping `. Si la cible n'est pas un répertoire (c'est-à-dire ne se termine pas par ``/``, ``/.`` ou ``/..``), le répertoire contenant la cible est utilisé à la place. - Chemin de base et chemins d'inclusion. +======= + - The directories containing input files listed on the command-line. + - The directories used as :ref:`remapping ` targets. + If the target is not a directory (i.e does not end with ``/``, ``/.`` or ``/..``) the directory + containing the target is used instead. + - Base path and include paths. +>>>>>>> english/develop - En mode JSON standard : @@ -514,9 +586,15 @@ vous pouvez utiliser ce qui suit dans votre fichier source : import "github.com/ethereum/dapp-bin/library/math.sol"; // source unit name: dapp-bin/library/math.sol +<<<<<<< HEAD Le compilateur cherchera le fichier dans le VFS sous ``dapp-bin/library/math.sol``. Si le fichier n'est pas disponible à cet endroit, le nom de l'unité source sera transmis au Host Filesystem Loader, qui cherchera alors dans ``/project/dapp-bin/library/iterable_mapping.sol``. +======= +The compiler will look for the file in the VFS under ``dapp-bin/library/math.sol``. +If the file is not available there, the source unit name will be passed to the Host Filesystem +Loader, which will then look in ``/project/dapp-bin/library/math.sol``. +>>>>>>> english/develop .. warning:: @@ -551,7 +629,11 @@ que vous avez extraite vers ``/project/dapp-bin_old``, alors vous pouvez exécut Cela signifie que tous les imports de ``module2`` pointent vers l'ancienne version mais que les imports de ``module1`` pointent vers la nouvelle version. +<<<<<<< HEAD Voici les règles détaillées qui régissent le comportement des remappages : +======= +Here are the detailed rules governing the behavior of remappings: +>>>>>>> english/develop #. **Les remappages n'affectent que la traduction entre les chemins d'importation et les noms d'unités sources.** diff --git a/docs/requirements.txt b/docs/requirements.txt index cee188db03..20699a9d10 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,7 +4,11 @@ sphinx_rtd_theme>=0.5.2 pygments-lexer-solidity>=0.7.0 +<<<<<<< HEAD sphinx-a4doc==1.3.0 +======= +sphinx-a4doc>=1.6.0 +>>>>>>> english/develop # Sphinx 2.1.0 is the oldest version that accepts a lexer class in add_lexer() -sphinx>=2.1.0 +sphinx>=2.1.0, <6.0 diff --git a/docs/resources.rst b/docs/resources.rst index 39d20e9ff8..e7d33ca9d2 100644 --- a/docs/resources.rst +++ b/docs/resources.rst @@ -23,10 +23,17 @@ Environnements de développement intégrés (Ethereum) Cadre de développement et de test basé sur Python pour les contrats intelligents ciblant la machine virtuelle Ethereum. * `Dapp `_ +<<<<<<< HEAD Outil pour construire, tester et déployer des contrats intelligents à partir de la ligne de commande. * `Embark `_ Plateforme de développeurs pour la création et le déploiement d'applications décentralisées. +======= + Tool for building, testing and deploying smart contracts from the command-line. + + * `Foundry `_ + Fast, portable and modular toolkit for Ethereum application development written in Rust. +>>>>>>> english/develop * `Hardhat `_ Environnement de développement Ethereum avec réseau Ethereum local, fonctions de débogage et écosystème de plugins. @@ -37,12 +44,18 @@ Environnements de développement intégrés (Ethereum) * `Scaffold-ETH `_ Pile de développement Ethereum axée sur des itérations rapides du produit. +<<<<<<< HEAD * `Truffle `_ Cadre de développement Ethereum. +======= + * `Truffle `_ + Ethereum development framework. +>>>>>>> english/develop Intégrations de l'éditeur =================== +<<<<<<< HEAD * Atom * `Etheratom `_ @@ -55,6 +68,8 @@ Intégrations de l'éditeur * `Atom Solium Linter `_ Linter Solidity configurable pour Atom utilisant Solium (maintenant Ethlint) comme base. +======= +>>>>>>> english/develop * Emacs * `Emacs Solidity `_ @@ -62,28 +77,60 @@ Intégrations de l'éditeur * IntelliJ +<<<<<<< HEAD * `IntelliJ IDEA plugin `_ Plugin Solidity pour IntelliJ IDEA (et tous les autres IDE de JetBrains) +======= + * `IntelliJ IDEA plugin `_ + Solidity plugin for IntelliJ IDEA (and all other JetBrains IDEs). +>>>>>>> english/develop -* Sublime +* Sublime Text * `Package for SublimeText - Solidity language syntax `_ Coloration syntaxique Solidity pour l'éditeur SublimeText. * Vim +<<<<<<< HEAD * `Vim Solidity `_ Plugin pour l'éditeur Vim fournissant une coloration syntaxique. +======= + * `Vim Solidity by Thesis `_ + Syntax highlighting for Solidity in Vim. + + * `Vim Solidity by TovarishFin `_ + Vim syntax file for Solidity. +>>>>>>> english/develop * `Vim Syntastic `_ Plugin pour l'éditeur Vim permettant de vérifier la compilation. -* Visual Studio Code +* Visual Studio Code (VS Code) +<<<<<<< HEAD * `Visual Studio Code extension `_ Plugin Solidity pour Microsoft Visual Studio Code qui comprend la coloration syntaxique et le compilateur Solidity. Outils Solidity +======= + * `Ethereum Remix Visual Studio Code extension `_ + Ethereum Remix extension pack for VS Code + + * `Solidity Visual Studio Code extension, by Juan Blanco `_ + Solidity plugin for Microsoft Visual Studio Code that includes syntax highlighting and the Solidity compiler. + + * `Solidity Visual Studio Code extension, by Nomic Foundation `_ + Solidity and Hardhat support by the Hardhat team, including: syntax highlighting, jump to definition, renames, quick fixes and inline solc warnings and errors. + + * `Solidity Visual Auditor extension `_ + Adds security centric syntax and semantic highlighting to Visual Studio Code. + + * `Truffle for VS Code `_ + Build, debug and deploy smart contracts on Ethereum and EVM-compatible blockchains. + +Solidity Tools +>>>>>>> english/develop ============== * `ABI to Solidity interface converter `_ @@ -110,8 +157,13 @@ Outils Solidity * `leafleth `_ Un générateur de documentation pour les smart-contracts de Solidity. +<<<<<<< HEAD * `PIET `_ Un outil pour développer, auditer et utiliser les contrats intelligents Solidity à travers une interface graphique simple. +======= +* `Scaffold-ETH `_ + Forkable Ethereum development stack focused on fast product iterations. +>>>>>>> english/develop * `sol2uml `_ Générateur de diagrammes de classe en langage de modélisation unifié (UML) pour les contrats Solidity. diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst index 576b9c2143..3d65e6308d 100644 --- a/docs/security-considerations.rst +++ b/docs/security-considerations.rst @@ -7,6 +7,7 @@ Considérations de sécurité Alors qu'il est généralement assez facile de construire un logiciel qui fonctionne comme prévu, il est beaucoup plus difficile de vérifier que personne ne peut l'utiliser d'une manière **non** prévue. +<<<<<<< HEAD Dans Solidity, cela est encore plus important car vous pouvez utiliser des contrats intelligents pour gérer des jetons ou, éventuellement, des choses encore plus précieuses. De plus, chaque exécution d'un contrat intelligent se fait en public et, en plus de cela, @@ -29,6 +30,30 @@ générateur de code du compilateur Solidity. Comme toujours, avec la documentation open source, merci de nous aider à étendre cette section (surtout, quelques exemples ne feraient pas de mal) ! +======= +In Solidity, this is even more important because you can use smart contracts to handle tokens or, +possibly, even more valuable things. +Furthermore, every execution of a smart contract happens in public and, +in addition to that, the source code is often available. + +Of course, you always have to consider how much is at stake: +You can compare a smart contract with a web service that is open to the public +(and thus, also to malicious actors) and perhaps even open-source. +If you only store your grocery list on that web service, you might not have to take too much care, +but if you manage your bank account using that web service, you should be more careful. + +This section will list some pitfalls and general security recommendations +but can, of course, never be complete. +Also, keep in mind that even if your smart contract code is bug-free, +the compiler or the platform itself might have a bug. +A list of some publicly known security-relevant bugs of the compiler can be found +in the :ref:`list of known bugs`, which is also machine-readable. +Note that there is a `Bug Bounty Program `_ +that covers the code generator of the Solidity compiler. + +As always, with open-source documentation, +please help us extend this section (especially, some examples would not hurt)! +>>>>>>> english/develop NOTE : En plus de la liste ci-dessous, vous pouvez trouver plus de recommandations de sécurité et de meilleures pratiques `dans la liste de connaissances de Guy Lando `_ et @@ -41,6 +66,7 @@ Pièges Information privée et aléatoire ================================== +<<<<<<< HEAD Tout ce que vous utilisez dans un contrat intelligent est visible publiquement, même les variables locales et les variables d'état marquées ``private``. @@ -55,6 +81,20 @@ d'Ether transmet le contrôle à ce contrat (B). Il est donc possible pour B de rappeler A avant que cette interaction ne soit terminée. Pour donner un exemple, le code suivant contient un bug (il ne s'agit que d'un extrait et non d'un contrat complet) : +======= +Everything you use in a smart contract is publicly visible, +even local variables and state variables marked ``private``. + +Using random numbers in smart contracts is quite tricky if you do not want block builders to be able to cheat. + +Reentrancy +========== + +Any interaction from a contract (A) with another contract (B) +and any transfer of Ether hands over control to that contract (B). +This makes it possible for B to call back into A before this interaction is completed. +To give an example, the following code contains a bug (it is just a snippet and not a complete contract): +>>>>>>> english/develop .. code-block:: solidity @@ -72,6 +112,7 @@ contrat complet) : } } +<<<<<<< HEAD Le problème n'est pas trop grave ici en raison du gaz limité dans le cadre de de ``send``, mais il expose quand même une faiblesse : Le transfert d'éther peut toujours inclure l'exécution de code, donc le destinataire pourrait être un contrat qui appelle @@ -79,6 +120,15 @@ dans ``withdraw``. Cela lui permettrait d'obtenir de multiples remboursements et de récupérer tout l'Ether du contrat. En particulier, le contrat suivant permettra à un attaquant de rembourser plusieurs fois car il utilise ``call`` qui renvoie tout le gaz restant par défaut : +======= +The problem is not too serious here because of the limited gas as part of ``send``, +but it still exposes a weakness: +Ether transfer can always include code execution, +so the recipient could be a contract that calls back into ``withdraw``. +This would let it get multiple refunds and, basically, retrieve all the Ether in the contract. +In particular, the following contract will allow an attacker to refund multiple times +as it uses ``call`` which forwards all remaining gas by default: +>>>>>>> english/develop .. code-block:: solidity @@ -97,8 +147,12 @@ car il utilise ``call`` qui renvoie tout le gaz restant par défaut : } } +<<<<<<< HEAD Pour éviter la ré-entrance, vous pouvez utiliser le modèle Checks-Effects-Interactions comme comme indiqué ci-dessous : +======= +To avoid reentrancy, you can use the Checks-Effects-Interactions pattern as demonstrated below: +>>>>>>> english/develop .. code-block:: solidity @@ -116,24 +170,54 @@ comme indiqué ci-dessous : } } +<<<<<<< HEAD Notez que la ré-entrance n'est pas seulement un effet du transfert d'Ether mais de tout appel de fonction sur un autre contrat. De plus, vous devez également prendre en compte les situations de multi-contrats. Un contrat appelé pourrait modifier l'état d'un autre contrat dont vous dépendez. +======= +The Checks-Effects-Interactions pattern ensures that all code paths through a contract +complete all required checks of the supplied parameters before modifying the contract's state (Checks); +only then it makes any changes to the state (Effects); +it may make calls to functions in other contracts +*after* all planned state changes have been written to storage (Interactions). +This is a common foolproof way to prevent *reentrancy attacks*, +where an externally called malicious contract can double-spend an allowance, +double-withdraw a balance, among other things, +by using logic that calls back into the original contract before it has finalized its transaction. + +Note that reentrancy is not only an effect of Ether transfer +but of any function call on another contract. +Furthermore, you also have to take multi-contract situations into account. +A called contract could modify the state of another contract you depend on. +>>>>>>> english/develop Limite et boucles de gaz =================== +<<<<<<< HEAD Les boucles qui n'ont pas un nombre fixe d'itérations, par exemple les boucles qui dépendent de valeurs de stockage, doivent être utilisées avec précaution : En raison de la limite de gaz de bloc, les transactions ne peuvent consommer qu'une certaine quantité de gaz. Que ce soit explicitement ou simplement en raison du fonctionnement normal, le nombre d'itérations d'une boucle peut dépasser la limite de gaz en bloc, ce qui peut entraîner que le contrat complet soit bloqué à un certain point. Cela peut ne pas s'appliquer aux fonctions ``view`` qui sont uniquement exécutées pour lire les données de la blockchain. Cependant, de telles fonctions peuvent être appelées par d'autres contrats dans le cadre d'opérations sur la blockchain et les bloquer. Veuillez être explicite sur ces cas dans la documentation de vos contrats. +======= +Loops that do not have a fixed number of iterations, for example, +loops that depend on storage values, have to be used carefully: +Due to the block gas limit, transactions can only consume a certain amount of gas. +Either explicitly or just due to normal operation, +the number of iterations in a loop can grow beyond the block gas limit +which can cause the complete contract to be stalled at a certain point. +This may not apply to ``view`` functions that are only executed to read data from the blockchain. +Still, such functions may be called by other contracts as part of on-chain operations and stall those. +Please be explicit about such cases in the documentation of your contracts. +>>>>>>> english/develop Envoi et réception d'Ether =========================== +<<<<<<< HEAD - Ni les contrats ni les "comptes externes" ne sont actuellement capables d'empêcher que quelqu'un leur envoie de l'Ether. Les contrats peuvent réagir et rejeter un transfert régulier, mais il existe des moyens de déplacer de l'Ether sans créer un appel de message. Une façon est de simplement "miner vers" @@ -161,6 +245,29 @@ Envoi et réception d'Ether - Utilisez les unités les plus précises possibles pour représenter le montant du wei, car vous perdez tout ce qui est arrondi en raison d'un manque de précision. +======= +- Neither contracts nor "external accounts" are currently able to prevent someone from sending them Ether. + Contracts can react on and reject a regular transfer, but there are ways to move Ether without creating a message call. + One way is to simply "mine to" the contract address and the second way is using ``selfdestruct(x)``. + +- If a contract receives Ether (without a function being called), either the :ref:`receive Ether ` + or the :ref:`fallback ` function is executed. + If it does not have a ``receive`` nor a ``fallback`` function, the Ether will be rejected (by throwing an exception). + During the execution of one of these functions, the contract can only rely on the "gas stipend" it is passed (2300 gas) + being available to it at that time. + This stipend is not enough to modify storage (do not take this for granted though, the stipend might change with future hard forks). + To be sure that your contract can receive Ether in that way, check the gas requirements of the receive and fallback functions + (for example in the "details" section in Remix). + +- There is a way to forward more gas to the receiving contract using ``addr.call{value: x}("")``. + This is essentially the same as ``addr.transfer(x)``, only that it forwards all remaining gas + and opens up the ability for the recipient to perform more expensive actions + (and it returns a failure code instead of automatically propagating the error). + This might include calling back into the sending contract or other state changes you might not have thought of. + So it allows for great flexibility for honest users but also for malicious actors. + +- Use the most precise units to represent the Wei amount as possible, as you lose any that is rounded due to a lack of precision. +>>>>>>> english/develop - Si vous voulez envoyer des Ether en utilisant ``address.transfer``, il y a certains détails à connaître : @@ -183,6 +290,7 @@ Envoi et réception d'Ether Profondeur de la pile d'appel ================ +<<<<<<< HEAD Les appels de fonctions externes peuvent échouer à tout moment parce qu'ils dépassent la limite de taille de la pile d'appels de 1024. Dans de telles situations, Solidity lève une exception. Les acteurs malveillants pourraient être en mesure de forcer la pile d'appels à une valeur élevée @@ -193,16 +301,39 @@ Notez également que la pile d'appel et la pile d'expression ne sont pas liées, Notez que ``.send()`` ne lève **pas** d'exception si la pile d'appels est épuisée, mais renvoie plutôt ``false`` dans ce cas. Les fonctions de bas niveau ``.call()``, ``.delegatecall()`` et ``.staticcall()`` se comportent de la même manière. +======= +External function calls can fail at any time +because they exceed the maximum call stack size limit of 1024. +In such situations, Solidity throws an exception. +Malicious actors might be able to force the call stack to a high value +before they interact with your contract. +Note that, since `Tangerine Whistle `_ hardfork, +the `63/64 rule `_ makes call stack depth attack impractical. +Also note that the call stack and the expression stack are unrelated, +even though both have a size limit of 1024 stack slots. + +Note that ``.send()`` does **not** throw an exception if the call stack is depleted +but rather returns ``false`` in that case. +The low-level functions ``.call()``, ``.delegatecall()`` and ``.staticcall()`` behave in the same way. +>>>>>>> english/develop Procurations autorisées ================== +<<<<<<< HEAD Si votre contrat peut agir comme un proxy, c'est-à-dire s'il peut appeler des contrats arbitraires avec des données fournies par l'utilisateur, alors l'utilisateur peut essentiellement assumer l'identité du contrat proxy. Même si vous avez mis en place d'autres mesures de protection, il est préférable de construire votre système de contrat de telle sorte que le proxy n'a aucune autorisation (même pas pour lui-même). Si nécessaire, vous pouvez y parvenir en utilisant un deuxième proxy : +======= +If your contract can act as a proxy, i.e. if it can call arbitrary contracts with user-supplied data, +then the user can essentially assume the identity of the proxy contract. +Even if you have other protective measures in place, it is best to build your contract system such +that the proxy does not have any permissions (not even for itself). +If needed, you can accomplish that using a second proxy: +>>>>>>> english/develop .. code-block:: solidity @@ -211,9 +342,9 @@ en utilisant un deuxième proxy : contract ProxyWithMoreFunctionality { PermissionlessProxy proxy; - function callOther(address _addr, bytes memory _payload) public + function callOther(address addr, bytes memory payload) public returns (bool, bytes memory) { - return proxy.callOther(_addr, _payload); + return proxy.callOther(addr, payload); } // Autres fonctions et autres fonctionnalités } @@ -221,16 +352,21 @@ en utilisant un deuxième proxy : // Il s'agit du contrat complet, il n'a pas d'autre fonctionnalités et // ne nécessite aucun privilège pour fonctionner. contract PermissionlessProxy { - function callOther(address _addr, bytes memory _payload) public + function callOther(address addr, bytes memory payload) public returns (bool, bytes memory) { - return _addr.call(_payload); + return addr.call(payload); } } tx.origin ========= +<<<<<<< HEAD N'utilisez jamais tx.origin pour l'autorisation. Disons que vous avez un contrat de portefeuille comme celui-ci : +======= +Never use ``tx.origin`` for authorization. +Let's say you have a wallet contract like this: +>>>>>>> english/develop .. code-block:: solidity @@ -274,9 +410,17 @@ Maintenant, quelqu'un vous incite à envoyer de l'Ether à l'adresse de ce porte } } +<<<<<<< HEAD Si votre porte-monnaie avait vérifié l'autorisation de ``msg.sender``, il aurait obtenu l'adresse du porte-monnaie attaqué, au lieu de l'adresse du propriétaire. Mais en vérifiant ``tx.origin``, il obtient l'adresse originale qui a déclenché la transaction, qui est toujours l'adresse du propriétaire. Le porte-monnaie attaqué draine instantanément tous vos fonds. +======= +If your wallet had checked ``msg.sender`` for authorization, it would get the address of the attack wallet, +instead of the owner's address. +But by checking ``tx.origin``, it gets the original address that kicked off the transaction, +which is still the owner's address. +The attack wallet instantly drains all your funds. +>>>>>>> english/develop .. _underflow-overflow: @@ -316,6 +460,7 @@ Essayez d'utiliser ``require`` pour limiter la taille des entrées à un interva Effacement des mappages ================= +<<<<<<< HEAD Le type Solidity ``mapping`` (voir :ref:`mapping-types`) est une structure de données de type clé-valeur qui ne garde pas la trace des clés auxquelles qui ont reçu une valeur non nulle. Pour cette raison, le nettoyage d'un mappage sans @@ -325,6 +470,16 @@ ou l'éclatement du tableau n'aura aucun effet sur les éléments du ``mapping`` Il en va de même, par exemple, si un ``mapping`` est utilisé comme type d'un champ d'une ``structure`` qui est le type de base d'un tableau de stockage dynamique. Le site ``mapping`` est également ignoré dans les affectations de structs ou de tableaux contenant un ``mapping``. +======= +The Solidity type ``mapping`` (see :ref:`mapping-types`) is a storage-only key-value data structure +that does not keep track of the keys that were assigned a non-zero value. +Because of that, cleaning a mapping without extra information about the written keys is not possible. +If a ``mapping`` is used as the base type of a dynamic storage array, +deleting or popping the array will have no effect over the ``mapping`` elements. +The same happens, for example, if a ``mapping`` is used as the type of a member field of a ``struct`` +that is the base type of a dynamic storage array. +The ``mapping`` is also ignored in assignments of structs or arrays containing a ``mapping``. +>>>>>>> english/develop .. code-block:: solidity @@ -332,19 +487,19 @@ d'une ``structure`` qui est le type de base d'un tableau de stockage dynamique. pragma solidity >=0.6.0 <0.9.0; contract Map { - mapping (uint => uint)[] array; + mapping(uint => uint)[] array; - function allocate(uint _newMaps) public { - for (uint i = 0; i < _newMaps; i++) + function allocate(uint newMaps) public { + for (uint i = 0; i < newMaps; i++) array.push(); } - function writeMap(uint _map, uint _key, uint _value) public { - array[_map][_key] = _value; + function writeMap(uint map, uint key, uint value) public { + array[map][key] = value; } - function readMap(uint _map, uint _key) public view returns (uint) { - return array[_map][_key]; + function readMap(uint map, uint key) public view returns (uint) { + return array[map][key]; } function eraseMaps() public { @@ -352,6 +507,7 @@ d'une ``structure`` qui est le type de base d'un tableau de stockage dynamique. } } +<<<<<<< HEAD Considérons l'exemple ci-dessus et la séquence d'appels suivante : ``allocate(10)``, ``writeMap(4, 128, 256)``. À ce stade, l'appel à ``readMap(4, 128)`` renvoie 256. Si on appelle ``eraseMaps``, la longueur de la variable d'état ``array`` est remise à zéro, mais @@ -360,6 +516,14 @@ dans le stockage du contrat. Après avoir supprimé ``array``, l'appel à ``allocate(5)`` nous permet d'accéder à ``array[4]`` à nouveau, et l'appel à ``readMap(4, 128)`` renvoie 256 même sans un autre appel à ``writeMap``. +======= +Consider the example above and the following sequence of calls: ``allocate(10)``, ``writeMap(4, 128, 256)``. +At this point, calling ``readMap(4, 128)`` returns 256. +If we call ``eraseMaps``, the length of the state variable ``array`` is zeroed, +but since its ``mapping`` elements cannot be zeroed, their information stays alive in the contract's storage. +After deleting ``array``, calling ``allocate(5)`` allows us to access ``array[4]`` again, +and calling ``readMap(4, 128)`` returns 256 even without another call to ``writeMap``. +>>>>>>> english/develop Si vos informations de ``mapping`` doivent être effacées, envisagez d'utiliser une bibliothèque similaire à `iterable mapping `_, @@ -368,12 +532,22 @@ vous permettant de parcourir les clés et de supprimer leurs valeurs dans le ``m Détails mineurs ============= +<<<<<<< HEAD - Les types qui n'occupent pas la totalité des 32 octets peuvent contenir des "bits d'ordre supérieur sales". Ceci est particulièrement important si vous accédez à ``msg.data`` - cela pose un risque de malléabilité : Vous pouvez créer des transactions qui appellent une fonction ``f(uint8 x)`` avec un argument brut de 32 octets de ``0xff000001`` et avec ``0x00000001``. Les deux sont envoyés au contrat et les deux ressemblent au nombre ``1`` en ce qui concerne ``x``, mais ``msg.data`` sera différente, donc si vous utilisez ``keccak256(msg.data)`` pour quoi que ce soit, vous obtiendrez des résultats différents. +======= +- Types that do not occupy the full 32 bytes might contain "dirty higher order bits". + This is especially important if you access ``msg.data`` - it poses a malleability risk: + You can craft transactions that call a function ``f(uint8 x)`` + with a raw byte argument of ``0xff000001`` and with ``0x00000001``. + Both are fed to the contract and both will look like the number ``1`` as far as ``x`` is concerned, + but ``msg.data`` will be different, so if you use ``keccak256(msg.data)`` for anything, + you will get different results. +>>>>>>> english/develop *************** Recommandations @@ -382,6 +556,7 @@ Recommandations Prenez les avertissements au sérieux ======================= +<<<<<<< HEAD Si le compilateur vous avertit de quelque chose, vous devez le modifier. Même si vous ne pensez pas que cet avertissement particulier a des implications de sécurité, il peut y avoir un autre problème caché. @@ -393,26 +568,54 @@ avertissements récemment introduits. Les messages de type ``info`` émis par le compilateur ne sont pas dangereux, et représentent simplement des suggestions supplémentaires et des informations optionnelles que le compilateur pense pourrait être utile à l'utilisateur. +======= +If the compiler warns you about something, you should change it. +Even if you do not think that this particular warning has security implications, +there might be another issue buried beneath it. +Any compiler warning we issue can be silenced by slight changes to the code. + +Always use the latest version of the compiler to be notified about all recently introduced warnings. + +Messages of type ``info``, issued by the compiler, are not dangerous +and simply represent extra suggestions and optional information +that the compiler thinks might be useful to the user. +>>>>>>> english/develop Limiter la quantité d'éther ============================ +<<<<<<< HEAD Restreindre la quantité d'Ether (ou d'autres jetons) qui peut être stockée dans un contrat intelligent. Si votre code source, le compilateur ou la plateforme a un bug, ces fonds peuvent être perdus. Si vous voulez limiter vos pertes, limitez la quantité d'Ether. +======= +Restrict the amount of Ether (or other tokens) that can be stored in a smart contract. +If your source code, the compiler or the platform has a bug, these funds may be lost. +If you want to limit your loss, limit the amount of Ether. +>>>>>>> english/develop Restez petit et modulaire ========================= +<<<<<<< HEAD Gardez vos contrats petits et facilement compréhensibles. Isolez les fonctionnalités sans rapport dans d'autres contrats ou dans des bibliothèques. Les recommandations générales sur la qualité du code source s'appliquent bien sûr : Limitez la quantité de variables locales, la longueur des fonctions et ainsi de suite. Documentez vos fonctions afin que les autres puissent voir quelle était votre intention et si elle est différente de ce que fait le code. +======= +Keep your contracts small and easily understandable. +Single out unrelated functionality in other contracts or into libraries. +General recommendations about the source code quality of course apply: +Limit the amount of local variables, the length of functions and so on. +Document your functions so that others can see what your intention was +and whether it is different than what the code does. +>>>>>>> english/develop Utiliser le modèle Verifications-Effects-Interactions =========================================== +<<<<<<< HEAD La plupart des fonctions vont d'abord effectuer quelques vérifications (qui a appelé la fonction, les arguments sont-ils à portée, ont-ils envoyé assez d'Ether, la personne a-t-elle des jetons, etc.) Ces vérifications doivent être effectuées en premier. @@ -424,6 +627,17 @@ doit être la toute dernière étape de toute fonction. Les premiers contrats retardaient certains effets et attendaient que les appels de fonctions externes reviennent dans un état de non-erreur. C'est souvent une grave erreur à cause du problème de ré-entrance expliqué ci-dessus. +======= +Most functions will first perform some checks and they should be done first +(who called the function, are the arguments in range, did they send enough Ether, +does the person have tokens, etc.). + +As the second step, if all checks passed, effects to the state variables of the current contract should be made. +Interaction with other contracts should be the very last step in any function. + +Early contracts delayed some effects and waited for external function calls to return in a non-error state. +This is often a serious mistake because of the reentrancy problem explained above. +>>>>>>> english/develop Notez également que les appels à des contrats connus peuvent à leur tour provoquer des appels à des contrats inconnus, il est donc probablement préférable de toujours appliquer ce modèle. @@ -431,6 +645,7 @@ contrats inconnus, il est donc probablement préférable de toujours appliquer c Inclure un mode de sécurité intégrée ======================== +<<<<<<< HEAD Bien que le fait de rendre votre système entièrement décentralisé supprime tout intermédiaire, ce serait une bonne idée, surtout pour un nouveau code, d'inclure une sorte de mécanisme de sécurité : @@ -445,10 +660,31 @@ Si l'auto-vérification échoue, le contrat passe automatiquement dans une sorte mode "failsafe", qui, par exemple, désactive la plupart des fonctions, remet le contrôle à un tiers fixe et de confiance ou simplement convertir le contrat en un simple contrat "rendez-moi mon argent". +======= +While making your system fully decentralized will remove any intermediary, +it might be a good idea, especially for new code, to include some kind of fail-safe mechanism: + +You can add a function in your smart contract that performs some self-checks like "Has any Ether leaked?", +"Is the sum of the tokens equal to the balance of the contract?" or similar things. +Keep in mind that you cannot use too much gas for that, +so help through off-chain computations might be needed there. + +If the self-check fails, the contract automatically switches into some kind of "failsafe" mode, +which, for example, disables most of the features, +hands over control to a fixed and trusted third party +or just converts the contract into a simple "give me back my Ether" contract. +>>>>>>> english/develop Demandez un examen par les pairs =================== +<<<<<<< HEAD Plus il y a de personnes qui examinent un morceau de code, plus on découvre de problèmes. Demander à des personnes d'examiner votre code permet également de vérifier par recoupement si votre code est facile à comprendre - un critère très important pour les bons contrats intelligents. +======= +The more people examine a piece of code, the more issues are found. +Asking people to review your code also helps as a cross-check to find out +whether your code is easy to understand - +a very important criterion for good smart contracts. +>>>>>>> english/develop diff --git a/docs/smtchecker.rst b/docs/smtchecker.rst index 35abaf1c3a..f76fb4127e 100644 --- a/docs/smtchecker.rst +++ b/docs/smtchecker.rst @@ -73,7 +73,7 @@ Tutoriel Débordement ======== -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0; @@ -82,12 +82,12 @@ Débordement uint immutable x; uint immutable y; - function add(uint _x, uint _y) internal pure returns (uint) { - return _x + _y; + function add(uint x_, uint y_) internal pure returns (uint) { + return x_ + y_; } - constructor(uint _x, uint _y) { - (x, y) = (_x, _y); + constructor(uint x_, uint y_) { + (x, y) = (x_, y_); } function stateAdd() public view returns (uint) { @@ -95,12 +95,21 @@ Débordement } } +<<<<<<< HEAD Le contrat ci-dessus montre un exemple de vérification de débordement (overflow). Le SMTChecker ne vérifie pas l'underflow et l'overflow par défaut pour Solidity >=0.8.7, donc nous devons utiliser l'option de ligne de commande ``--model-checker-targets "underflow,overflow"`` ou l'option JSON ``settings.modelChecker.targets = ["underflow", "overflow"]``. Voir :ref:`cette section pour la configuration des cibles`. Ici, il signale ce qui suit : +======= +The contract above shows an overflow check example. +The SMTChecker does not check underflow and overflow by default for Solidity >=0.8.7, +so we need to use the command-line option ``--model-checker-targets "underflow,overflow"`` +or the JSON option ``settings.modelChecker.targets = ["underflow", "overflow"]``. +See :ref:`this section for targets configuration`. +Here, it reports the following: +>>>>>>> english/develop .. code-block:: text @@ -116,13 +125,13 @@ Ici, il signale ce qui suit : Overflow.add(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935) -- internal call --> o.sol:9:20: | - 9 | return _x + _y; + 9 | return x_ + y_; | ^^^^^^^ Si nous ajoutons des déclarations ``require`` qui filtrent les cas de débordement, le SMTChecker prouve qu'aucun débordement n'est atteignable (en ne signalant pas d'avertissement) : -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0; @@ -131,12 +140,12 @@ le SMTChecker prouve qu'aucun débordement n'est atteignable (en ne signalant pa uint immutable x; uint immutable y; - function add(uint _x, uint _y) internal pure returns (uint) { - return _x + _y; + function add(uint x_, uint y_) internal pure returns (uint) { + return x_ + y_; } - constructor(uint _x, uint _y) { - (x, y) = (_x, _y); + constructor(uint x_, uint y_) { + (x, y) = (x_, y_); } function stateAdd() public view returns (uint) { @@ -153,27 +162,36 @@ Affirmer Une assertion représente un invariant dans votre code : une propriété qui doit être vraie *pour toutes les opérations, y compris toutes les valeurs d'entrée et de stockage*, sinon il y a un bug. +<<<<<<< HEAD Le code ci-dessous définit une fonction ``f`` qui garantit l'absence de débordement. La fonction ``inv`` définit la spécification que ``f`` est monotone et croissante : pour chaque paire possible ``(_a, _b)``, si ``_b > _a`` alors ``f(_b) > f(_a)``. Puisque ``f`` est effectivement monotone et croissante, le SMTChecker prouve que notre propriété est correcte. Nous vous encourageons à jouer avec la propriété et la définition de la fonction pour voir les résultats qui en découlent ! +======= +The code below defines a function ``f`` that guarantees no overflow. +Function ``inv`` defines the specification that ``f`` is monotonically increasing: +for every possible pair ``(a, b)``, if ``b > a`` then ``f(b) > f(a)``. +Since ``f`` is indeed monotonically increasing, the SMTChecker proves that our +property is correct. You are encouraged to play with the property and the function +definition to see what results come out! +>>>>>>> english/develop -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0; contract Monotonic { - function f(uint _x) internal pure returns (uint) { - require(_x < type(uint128).max); - return _x * 42; + function f(uint x) internal pure returns (uint) { + require(x < type(uint128).max); + return x * 42; } - function inv(uint _a, uint _b) public pure { - require(_b > _a); - assert(f(_b) > f(_a)); + function inv(uint a, uint b) public pure { + require(b > a); + assert(f(b) > f(a)); } } @@ -182,20 +200,20 @@ Le code suivant recherche l'élément maximum d'un tableau non restreint de nombres, et affirme la propriété selon laquelle l'élément trouvé doit être supérieur ou égal à chaque élément du tableau. -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0; contract Max { - function max(uint[] memory _a) public pure returns (uint) { + function max(uint[] memory a) public pure returns (uint) { uint m = 0; - for (uint i = 0; i < _a.length; ++i) - if (_a[i] > m) - m = _a[i]; + for (uint i = 0; i < a.length; ++i) + if (a[i] > m) + m = a[i]; - for (uint i = 0; i < _a.length; ++i) - assert(m >= _a[i]); + for (uint i = 0; i < a.length; ++i) + assert(m >= a[i]); return m; } @@ -216,21 +234,21 @@ Toutes les propriétés sont correctement prouvées sûres. N'hésitez pas à mo et/ou d'ajouter des restrictions sur le tableau pour obtenir des résultats différents. Par exemple, en changeant le code en -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0; contract Max { - function max(uint[] memory _a) public pure returns (uint) { - require(_a.length >= 5); + function max(uint[] memory a) public pure returns (uint) { + require(a.length >= 5); uint m = 0; - for (uint i = 0; i < _a.length; ++i) - if (_a[i] > m) - m = _a[i]; + for (uint i = 0; i < a.length; ++i) + if (a[i] > m) + m = a[i]; - for (uint i = 0; i < _a.length; ++i) - assert(m > _a[i]); + for (uint i = 0; i < a.length; ++i) + assert(m > a[i]); return m; } @@ -243,7 +261,7 @@ nous donne : Warning: CHC: Assertion violation happens here. Counterexample: - _a = [0, 0, 0, 0, 0] + a = [0, 0, 0, 0, 0] = 0 Transaction trace: @@ -251,7 +269,7 @@ nous donne : Test.max([0, 0, 0, 0, 0]) --> max.sol:14:4: | - 14 | assert(m > _a[i]); + 14 | assert(m > a[i]); Propriétés de l'État @@ -268,7 +286,7 @@ Plaçons un robot à la position (0, 0). Le robot ne peut se déplacer qu'en dia et ne peut pas se déplacer en dehors de la grille. La machine à états du robot peut être représentée par le contrat intelligent ci-dessous. -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0; @@ -318,7 +336,7 @@ Nous pouvons aussi tromper le SMTChecker pour qu'il nous donne un chemin vers un position que nous pensons être atteignable. Nous pouvons ajouter la propriété que (2, 4) est *non* accessible, en ajoutant la fonction suivante. -.. code-block:: Solidity +.. code-block:: solidity function reach_2_4() public view { assert(!(x == 2 && y == 4)); @@ -366,7 +384,7 @@ Dans certains cas, il est possible de déduire automatiquement des propriétés variables d'état qui restent vraies même si le code appelé de l'extérieur peut faire n'importe quoi, y compris réintroduire le contrat de l'appelant. -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0; @@ -381,9 +399,9 @@ n'importe quoi, y compris réintroduire le contrat de l'appelant. Unknown immutable unknown; - constructor(Unknown _u) { - require(address(_u) != address(0)); - unknown = _u; + constructor(Unknown u) { + require(address(u) != address(0)); + unknown = u; } modifier mutex { @@ -393,8 +411,8 @@ n'importe quoi, y compris réintroduire le contrat de l'appelant. lock = false; } - function set(uint _x) mutex public { - x = _x; + function set(uint x_) mutex public { + x = x_; } function run() mutex public { @@ -409,9 +427,15 @@ Le solveur est capable de déduire que lorsque ``unknown.run()`` est appelé, le est déjà "verrouillé", donc il ne serait pas possible de changer la valeur de ``x``, indépendamment de ce que fait le code appelé inconnu. +<<<<<<< HEAD Si nous "oublions" d'utiliser le modificateur ``mutex`` sur la fonction ``set``, le SMTChecker est capable de synthétiser le comportement du code appelé de manière externe que l'assertion échoue : +======= +If we "forget" to use the ``mutex`` modifier on function ``set``, the +SMTChecker is able to synthesize the behavior of the externally called code so +that the assertion fails: +>>>>>>> english/develop .. code-block:: text @@ -480,7 +504,19 @@ Toutes les cibles sont vérifiées par défaut, sauf underflow et overflow pour Il n'y a pas d'heuristique précise sur comment et quand diviser les cibles de vérification, mais cela peut être utile, surtout lorsqu'il s'agit de grands contrats. +<<<<<<< HEAD Cibles non vérifiées +======= +Proved Targets +============== + +If there are any proved targets, the SMTChecker issues one warning per engine stating +how many targets were proved. If the user wishes to see all the specific +proved targets, the CLI option ``--model-checker-show-proved`` and +the JSON option ``settings.modelChecker.showProved = true`` can be used. + +Unproved Targets +>>>>>>> english/develop ================ S'il existe des cibles non vérifiées, le SMTChecker émet un avertissement indiquant @@ -488,7 +524,28 @@ combien de cibles non vérifiées il y a. Si l'utilisateur souhaite voir toutes cibles non corrigées, l'option CLI ``--model-checker-show-unproved`` et l'option JSON ``settings.modelChecker.showUnproved = true`` peuvent être utilisées. +<<<<<<< HEAD Contrats vérifiés +======= +Unsupported Language Features +============================= + +Certain Solidity language features are not completely supported by the SMT +encoding that the SMTChecker applies, for example assembly blocks. +The unsupported construct is abstracted via overapproximation to preserve +soundness, meaning any properties reported safe are safe even though this +feature is unsupported. +However such abstraction may cause false positives when the target properties +depend on the precise behavior of the unsupported feature. +If the encoder encounters such cases it will by default report a generic warning +stating how many unsupported features it has seen. +If the user wishes to see all the specific unsupported features, the CLI option +``--model-checker-show-unsupported`` and the JSON option +``settings.modelChecker.showUnsupported = true`` can be used, where their default +value is ``false``. + +Verified Contracts +>>>>>>> english/develop ================== Par défaut, tous les contrats déployables dans les sources données sont analysés séparément en tant que @@ -515,6 +572,7 @@ qui a la forme suivante : "source2.sol": ["contract2", "contract3"] } +<<<<<<< HEAD Invariants inductifs rapportés et inférés ====================================== @@ -522,6 +580,198 @@ Pour les propriétés qui ont été prouvées sûres avec le moteur CHC, le SMTChecker peut récupérer les invariants inductifs qui ont été inférés par le solveur de Horn dans le cadre de la preuve. Actuellement, deux types d'invariants peuvent être rapportés à l'utilisateur : +======= +Trusted External Calls +====================== + +By default, the SMTChecker does not assume that compile-time available code +is the same as the runtime code for external calls. Take the following contracts +as an example: + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.8.0; + + contract Ext { + uint public x; + function setX(uint _x) public { x = _x; } + } + contract MyContract { + function callExt(Ext _e) public { + _e.setX(42); + assert(_e.x() == 42); + } + } + +When ``MyContract.callExt`` is called, an address is given as the argument. +At deployment time, we cannot know for sure that address ``_e`` actually +contains a deployment of contract ``Ext``. +Therefore, the SMTChecker will warn that the assertion above can be violated, +which is true, if ``_e`` contains another contract than ``Ext``. + +However, it can be useful to treat these external calls as trusted, for example, +to test that different implementations of an interface conform to the same property. +This means assuming that address ``_e`` indeed was deployed as contract ``Ext``. +This mode can be enabled via the CLI option ``--model-checker-ext-calls=trusted`` +or the JSON field ``settings.modelChecker.extCalls: "trusted"``. + +Please be aware that enabling this mode can make the SMTChecker analysis much more +computationally costly. + +An important part of this mode is that it is applied to contract types and high +level external calls to contracts, and not low level calls such as ``call`` and +``delegatecall``. The storage of an address is stored per contract type, and +the SMTChecker assumes that an externally called contract has the type of the +caller expression. Therefore, casting an ``address`` or a contract to +different contract types will yield different storage values and can give +unsound results if the assumptions are inconsistent, such as the example below: + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.8.0; + + contract D { + constructor(uint _x) { x = _x; } + uint public x; + function setX(uint _x) public { x = _x; } + } + + contract E { + constructor() { x = 2; } + uint public x; + function setX(uint _x) public { x = _x; } + } + + contract C { + function f() public { + address d = address(new D(42)); + + // `d` was deployed as `D`, so its `x` should be 42 now. + assert(D(d).x() == 42); // should hold + assert(D(d).x() == 43); // should fail + + // E and D have the same interface, so the following + // call would also work at runtime. + // However, the change to `E(d)` is not reflected in `D(d)`. + E(d).setX(1024); + + // Reading from `D(d)` now will show old values. + // The assertion below should fail at runtime, + // but succeeds in this mode's analysis (unsound). + assert(D(d).x() == 42); + // The assertion below should succeed at runtime, + // but fails in this mode's analysis (false positive). + assert(D(d).x() == 1024); + } + } + +Due to the above, make sure that the trusted external calls to a certain +variable of ``address`` or ``contract`` type always have the same caller +expression type. + +It is also helpful to cast the called contract's variable as the type of the +most derived type in case of inheritance. + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.8.0; + + interface Token { + function balanceOf(address _a) external view returns (uint); + function transfer(address _to, uint _amt) external; + } + + contract TokenCorrect is Token { + mapping (address => uint) balance; + constructor(address _a, uint _b) { + balance[_a] = _b; + } + function balanceOf(address _a) public view override returns (uint) { + return balance[_a]; + } + function transfer(address _to, uint _amt) public override { + require(balance[msg.sender] >= _amt); + balance[msg.sender] -= _amt; + balance[_to] += _amt; + } + } + + contract Test { + function property_transfer(address _token, address _to, uint _amt) public { + require(_to != address(this)); + + TokenCorrect t = TokenCorrect(_token); + + uint xPre = t.balanceOf(address(this)); + require(xPre >= _amt); + uint yPre = t.balanceOf(_to); + + t.transfer(_to, _amt); + uint xPost = t.balanceOf(address(this)); + uint yPost = t.balanceOf(_to); + + assert(xPost == xPre - _amt); + assert(yPost == yPre + _amt); + } + } + +Note that in function ``property_transfer``, the external calls are +performed on variable ``t``. + +Another caveat of this mode are calls to state variables of contract type +outside the analyzed contract. In the code below, even though ``B`` deploys +``A``, it is also possible for the address stored in ``B.a`` to be called by +anyone outside of ``B`` in between transactions to ``B`` itself. To reflect the +possible changes to ``B.a``, the encoding allows an unbounded number of calls +to be made to ``B.a`` externally. The encoding will keep track of ``B.a``'s +storage, therefore assertion (2) should hold. However, currently the encoding +allows such calls to be made from ``B`` conceptually, therefore assertion (3) +fails. Making the encoding stronger logically is an extension of the trusted +mode and is under development. Note that the encoding does not keep track of +storage for ``address`` variables, therefore if ``B.a`` had type ``address`` +the encoding would assume that its storage does not change in between +transactions to ``B``. + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.8.0; + + contract A { + uint public x; + address immutable public owner; + constructor() { + owner = msg.sender; + } + function setX(uint _x) public { + require(msg.sender == owner); + x = _x; + } + } + + contract B { + A a; + constructor() { + a = new A(); + assert(a.x() == 0); // (1) should hold + } + function g() public view { + assert(a.owner() == address(this)); // (2) should hold + assert(a.x() == 0); // (3) should hold, but fails due to a false positive + } + } + +Reported Inferred Inductive Invariants +====================================== + +For properties that were proved safe with the CHC engine, +the SMTChecker can retrieve inductive invariants that were inferred by the Horn +solver as part of the proof. +Currently only two types of invariants can be reported to the user: +>>>>>>> english/develop - Invariants de contrat : ce sont des propriétés sur les variables d'état du contrat qui sont vraies avant et après chaque transaction possible que le contrat peut exécuter. @@ -538,6 +788,7 @@ Par défaut, le SMTChecker ne rapporte pas les invariants. Division et modulo avec des variables muettes ======================================== +<<<<<<< HEAD Spacer, le solveur de Corne par défaut utilisé par le SMTChecker, n'aime souvent pas les opérations de division et de modulation dans les règles de Horn. Pour cette raison, par défaut, les opérations de division et de modulo de Solidity sont codées en utilisant la contrainte suivante @@ -546,6 +797,16 @@ Cependant, d'autres solveurs, comme Eldarica, préfèrent les opérations syntax L'indicateur de ligne de commande ``--model-checker-div-mod-no-slacks`` et l'option JSON ``settings.modelChecker.divModNoSlacks`` peuvent être utilisés pour basculer le codage en fonction des préférences du solveur utilisé. +======= +Spacer, the default Horn solver used by the SMTChecker, often dislikes division +and modulo operations inside Horn rules. Because of that, by default the +Solidity division and modulo operations are encoded using the constraint +``a = b * d + m`` where ``d = a / b`` and ``m = a % b``. +However, other solvers, such as Eldarica, prefer the syntactically precise operations. +The command-line flag ``--model-checker-div-mod-no-slacks`` and the JSON option +``settings.modelChecker.divModNoSlacks`` can be used to toggle the encoding +depending on the used solver preferences. +>>>>>>> english/develop Abstraction des fonctions Natspec ============================ @@ -613,6 +874,7 @@ qui est principalement un solveur SMT et qui rend `Spacer `_ disponible comme solveur de Horn, et `Eldarica `_ qui fait les deux. +<<<<<<< HEAD L'utilisateur peut choisir quels solveurs doivent être utilisés, s'ils sont disponibles, via l'option CLI ``--model-checker-solvers {all,cvc4,smtlib2,z3}`` ou l'option JSON ``settings.modelChecker.solvers=[smtlib2,z3]``, où : @@ -628,6 +890,29 @@ L'utilisateur peut choisir quels solveurs doivent être utilisés, s'ils sont di - si ``solc`` est compilé avec lui ; - si une bibliothèque dynamique ``z3`` de version 4.8.x est installée dans un système Linux (à partir de Solidity 0.7.6) ; - statiquement dans ``soljson.js`` (à partir de Solidity 0.6.9), c'est-à-dire le binaire Javascript du compilateur. +======= +The user can choose which solvers should be used, if available, via the CLI +option ``--model-checker-solvers {all,cvc4,eld,smtlib2,z3}`` or the JSON option +``settings.modelChecker.solvers=[smtlib2,z3]``, where: + +- ``cvc4`` is only available if the ``solc`` binary is compiled with it. Only BMC uses ``cvc4``. +- ``eld`` is used via its binary which must be installed in the system. Only CHC uses ``eld``, and only if ``z3`` is not enabled. +- ``smtlib2`` outputs SMT/Horn queries in the `smtlib2 `_ format. + These can be used together with the compiler's `callback mechanism `_ so that + any solver binary from the system can be employed to synchronously return the results of the queries to the compiler. + This can be used by both BMC and CHC depending on which solvers are called. +- ``z3`` is available + + - if ``solc`` is compiled with it; + - if a dynamic ``z3`` library of version >=4.8.x is installed in a Linux system (from Solidity 0.7.6); + - statically in ``soljson.js`` (from Solidity 0.6.9), that is, the JavaScript binary of the compiler. + +.. note:: + z3 version 4.8.16 broke ABI compatibility with previous versions and cannot + be used with solc <=0.8.13. If you are using z3 >=4.8.16 please use solc + >=0.8.14, and conversely, only use older z3 with older solc releases. + We also recommend using the latest z3 release which is what SMTChecker also does. +>>>>>>> english/develop Étant donné que BMC et CHC utilisent tous deux ``z3``, et que ``z3`` est disponible dans une plus grande variété d'environnements, y compris dans le navigateur, la plupart des utilisateurs n'auront presque jamais à se @@ -678,8 +963,13 @@ comme le montre le tableau ci-dessous. Les types qui ne sont pas encore pris en charge sont abstraits par un seul entier non signé de 256 bits, où leurs opérations non supportées sont ignorées. +<<<<<<< HEAD Pour plus de détails sur la façon dont l'encodage SMT fonctionne en interne, voir l'article `Vérification basée sur SMT des contrats intelligents Solidity `_. +======= +For more details on how the SMT encoding works internally, see the paper +`SMT-based Verification of Solidity Smart Contracts `_. +>>>>>>> english/develop Appels de fonction ============== @@ -759,15 +1049,15 @@ ne signifie pas une perte de puissance de preuve. { function f( bytes32 hash, - uint8 _v1, uint8 _v2, - bytes32 _r1, bytes32 _r2, - bytes32 _s1, bytes32 _s2 + uint8 v1, uint8 v2, + bytes32 r1, bytes32 r2, + bytes32 s1, bytes32 s2 ) public pure returns (address) { - address a1 = ecrecover(hash, _v1, _r1, _s1); - require(_v1 == _v2); - require(_r1 == _r2); - require(_s1 == _s2); - address a2 = ecrecover(hash, _v2, _r2, _s2); + address a1 = ecrecover(hash, v1, r1, s1); + require(v1 == v2); + require(r1 == r2); + require(s1 == s2); + address a2 = ecrecover(hash, v2, r2, s2); assert(a1 == a2); return a1; } diff --git a/docs/solidity_logo.svg b/docs/solidity_logo.svg new file mode 100644 index 0000000000..86b9f4995b --- /dev/null +++ b/docs/solidity_logo.svg @@ -0,0 +1,27 @@ + + + + +Vector 1 +Created with Sketch. + + + + + + + + + + + + + diff --git a/docs/structure-of-a-contract.rst b/docs/structure-of-a-contract.rst index d22fb07fbb..bc21d518a1 100644 --- a/docs/structure-of-a-contract.rst +++ b/docs/structure-of-a-contract.rst @@ -112,11 +112,16 @@ Les événements sont des interfaces pratiques avec les fonctions de journalisat .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.4.21 <0.9.0; + pragma solidity ^0.8.22; + + event HighestBidIncreased(address bidder, uint amount); // Event contract SimpleAuction { +<<<<<<< HEAD event HighestBidIncreased(address bidder, uint amount); // Événement +======= +>>>>>>> english/develop function bid() public payable { // ... emit HighestBidIncreased(msg.sender, msg.value); // Événement déclencheur diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 7a07bc8ce6..37bcfd13eb 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -8,13 +8,20 @@ Guide de style Introduction ************ +<<<<<<< HEAD Ce guide est destiné à fournir des conventions de codage pour l'écriture du code Solidity. Ce guide doit être considéré comme un document évolutif qui changera au fur et à mesure que des conventions utiles seront trouvées et que les anciennes conventions seront rendues obsolètes. +======= +This guide is intended to provide coding conventions for writing Solidity code. +This guide should be thought of as an evolving document that will change over +time as useful conventions are found and old conventions are rendered obsolete. +>>>>>>> english/develop De nombreux projets mettront en place leurs propres guides de style. En cas de conflits, les guides de style spécifiques au projet sont prioritaires. +<<<<<<< HEAD La structure et un grand nombre de recommandations de ce guide de style ont été tirées du guide de style de python `pep8 style guide `_. @@ -23,14 +30,28 @@ Le but de ce guide n'est *pas* d'être la bonne ou la meilleure façon d'écrire code Solidity. Le but de ce guide est la *consistance*. Une citation de python `pep8 `_ résume bien ce concept. +======= +The structure and many of the recommendations within this style guide were +taken from Python's +`pep8 style guide `_. + +The goal of this guide is *not* to be the right way or the best way to write +Solidity code. The goal of this guide is *consistency*. A quote from Python's +`pep8 `_ +captures this concept well. +>>>>>>> english/develop .. note:: Un guide de style est une question de cohérence. La cohérence avec ce guide de style est importante. La cohérence au sein d'un module ou d'une fonction est la plus importante. +<<<<<<< HEAD Mais le plus important : **savoir quand être incohérent** - parfois le guide de style ne s'applique tout simplement pas. En cas de doute, utilisez votre meilleur jugement. Regardez d'autres exemples et décidez de ce qui vous semble le mieux. Et n'hésitez pas à demander ! +======= + But most importantly: **know when to be inconsistent** -- sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best. And do not hesitate to ask! +>>>>>>> english/develop ******************** @@ -55,7 +76,18 @@ Lignes vierges Entourer les déclarations de haut niveau dans le code source de solidity de deux lignes vides. +<<<<<<< HEAD Oui : +======= +Mixing tabs and spaces should be avoided. + +Blank Lines +=========== + +Surround top level declarations in Solidity source with two blank lines. + +Yes: +>>>>>>> english/develop .. code-block:: solidity @@ -148,8 +180,12 @@ Non : Longueur maximale de la ligne ============================= +<<<<<<< HEAD Garder les lignes sous la recommandation `PEP 8 `_ à un maximum de 79 (ou 99) caractères aide les lecteurs à analyser facilement le code. +======= +Maximum suggested line length is 120 characters. +>>>>>>> english/develop Les lignes enveloppées doivent se conformer aux directives suivantes. @@ -206,7 +242,7 @@ Oui : .. code-block:: solidity - thisIsALongNestedMapping[being][set][to_some_value] = someFunction( + thisIsALongNestedMapping[being][set][toSomeValue] = someFunction( argument1, argument2, argument3, @@ -217,7 +253,7 @@ Non : .. code-block:: solidity - thisIsALongNestedMapping[being][set][to_some_value] = someFunction(argument1, + thisIsALongNestedMapping[being][set][toSomeValue] = someFunction(argument1, argument2, argument3, argument4); @@ -236,7 +272,7 @@ Oui : bytes32[] options ); - LongAndLotsOfArgs( + emit LongAndLotsOfArgs( sender, recipient, publicKey, @@ -254,7 +290,7 @@ Non " uint256 amount, bytes32[] options); - LongAndLotsOfArgs(sender, + emit LongAndLotsOfArgs(sender, recipient, publicKey, amount, @@ -440,17 +476,21 @@ Yes: x = 1; y = 2; - long_variable = 3; + longVariable = 3; Non : .. code-block:: solidity - x = 1; - y = 2; - long_variable = 3; + x = 1; + y = 2; + longVariable = 3; +<<<<<<< HEAD Ne pas inclure d'espace dans les fonctions de réception et de repli : +======= +Do not include a whitespace in the receive and fallback functions: +>>>>>>> english/develop Oui : @@ -680,10 +720,17 @@ Non : selfdestruct(owner); } +<<<<<<< HEAD Pour les longues déclarations de fonctions, il est recommandé de déposer chaque argument sur sa propre ligne au même niveau d'indentation que le corps de la fonction. La parenthèse fermante et la parenthèse ouvrante doivent être placées sur leur propre ligne au même niveau d'indentation que la déclaration de fonction. +======= +For long function declarations, it is recommended to drop each argument onto +its own line at the same indentation level as the function body. The closing +parenthesis and opening bracket should be placed on their own line as well at +the same indentation level as the function declaration. +>>>>>>> english/develop Oui : @@ -928,9 +975,15 @@ C'est autorisé : function shortFunction() public { doSomething(); } +<<<<<<< HEAD Ces directives pour les déclarations de fonctions sont destinées à améliorer la lisibilité. Les auteurs doivent faire preuve de discernement car ce guide ne prétend pas couvrir toutes les permutations possibles pour les déclarations de fonctions. +======= +These guidelines for function declarations are intended to improve readability. +Authors should use their best judgment as this guide does not try to cover all +possible permutations for function declarations. +>>>>>>> english/develop Mappages ======== @@ -1017,10 +1070,17 @@ Non : x += 3+4; x |= y&&z; +<<<<<<< HEAD * Les opérateurs ayant une priorité plus élevée que les autres peuvent exclure les espaces afin d'indiquer la préséance. Ceci a pour but de permettre d'améliorer la lisibilité d'une déclaration complexe. Vous devez toujours utiliser la même quantité d'espaces blancs de part et d'autre d'un opérateur : +======= +* Operators with a higher priority than others can exclude surrounding + whitespace in order to denote precedence. This is meant to allow for + improved readability for complex statements. You should always use the same + amount of whitespace on either side of an operator: +>>>>>>> english/develop Oui : @@ -1042,6 +1102,7 @@ Non : Ordre de mise en page ********************* +<<<<<<< HEAD Disposez les éléments du contrat dans l'ordre suivant : 1. Déclarations de pragmatisme @@ -1049,22 +1110,73 @@ Disposez les éléments du contrat dans l'ordre suivant : 3. Interfaces 4. Bibliothèques 5. Contrats +======= +Contract elements should be laid out in the following order: + +1. Pragma statements +2. Import statements +3. Events +4. Errors +5. Interfaces +6. Libraries +7. Contracts +>>>>>>> english/develop À l'intérieur de chaque contrat, bibliothèque ou interface, utilisez l'ordre suivant : +<<<<<<< HEAD 1. Les déclarations de type 2. Variables d'état 3. Événements 4. Fonctions +======= +1. Type declarations +2. State variables +3. Events +4. Errors +5. Modifiers +6. Functions +>>>>>>> english/develop .. note:: Il peut être plus clair de déclarer les types à proximité de leur utilisation dans les événements ou les variables d'état. +<<<<<<< HEAD ************************* Conventions d'appellation ************************* +======= +Yes: + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.8.4 <0.9.0; + + abstract contract Math { + error DivideByZero(); + function divide(int256 numerator, int256 denominator) public virtual returns (uint256); + } + +No: + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.8.4 <0.9.0; + + abstract contract Math { + function divide(int256 numerator, int256 denominator) public virtual returns (uint256); + error DivideByZero(); + } + + +****************** +Naming Conventions +****************** +>>>>>>> english/develop Les conventions de dénomination sont puissantes lorsqu'elles sont adoptées et utilisées à grande échelle. L'utilisation de différentes conventions peut véhiculer des informations *méta* significatives @@ -1104,8 +1216,20 @@ Noms à éviter * ``O`` - Lettre majuscule oh * ``I`` - Lettre majuscule eye +<<<<<<< HEAD N'utilisez jamais l'un de ces noms pour des noms de variables à une seule lettre. Elles sont souvent impossibles à distinguer des chiffres un et zéro. +======= +* ``b`` (single lowercase letter) +* ``B`` (single uppercase letter) +* ``lowercase`` +* ``UPPERCASE`` +* ``UPPER_CASE_WITH_UNDERSCORES`` +* ``CapitalizedWords`` (or CapWords) +* ``mixedCase`` (differs from CapitalizedWords by initial lowercase character!) + +.. note:: When using initialisms in CapWords, capitalize all the letters of the initialisms. Thus HTTPServerError is better than HttpServerError. When using initialisms in mixedCase, capitalize all the letters of the initialisms, except keep the first one lower case if it is the beginning of the name. Thus xmlHTTPRequest is better than XMLHTTPRequest. +>>>>>>> english/develop Noms de contrats et de bibliothèques @@ -1128,15 +1252,15 @@ Oui : contract Owned { address public owner; - constructor() { - owner = msg.sender; - } - modifier onlyOwner { require(msg.sender == owner); _; } + constructor() { + owner = msg.sender; + } + function transferOwnership(address newOwner) public onlyOwner { owner = newOwner; } @@ -1167,15 +1291,15 @@ Non : contract owned { address public owner; - constructor() { - owner = msg.sender; - } - modifier onlyOwner { require(msg.sender == owner); _; } + constructor() { + owner = msg.sender; + } + function transferOwnership(address newOwner) public onlyOwner { owner = newOwner; } @@ -1251,10 +1375,30 @@ Les Enums, dans le style des déclarations de type simples, doivent être nommé Éviter les collisions de noms ============================= -* ``single_trailing_underscore_`` +* ``singleTrailingUnderscore_`` +<<<<<<< HEAD Cette convention est suggérée lorsque le nom souhaité entre en collision avec celui d'un nom intégré ou autrement réservé. +======= +This convention is suggested when the desired name collides with that of +an existing state variable, function, built-in or otherwise reserved name. + +Underscore Prefix for Non-external Functions and Variables +========================================================== + +* ``_singleLeadingUnderscore`` + +This convention is suggested for non-external functions and state variables (``private`` or ``internal``). State variables without a specified visibility are ``internal`` by default. + +When designing a smart contract, the public-facing API (functions that can be called by any account) +is an important consideration. +Leading underscores allow you to immediately recognize the intent of such functions, +but more importantly, if you change a function from non-external to external (including ``public``) +and rename it accordingly, this forces you to review every call site while renaming. +This can be an important manual check against unintended external functions +and a common source of security vulnerabilities (avoid find-replace-all tooling for this change). +>>>>>>> english/develop .. _style_guide_natspec: diff --git a/docs/types/conversion.rst b/docs/types/conversion.rst index fba87ace30..790de1d32b 100644 --- a/docs/types/conversion.rst +++ b/docs/types/conversion.rst @@ -42,11 +42,19 @@ est effectué après l'addition. Conversions explicites -------------------- +<<<<<<< HEAD Si le compilateur n'autorise pas la conversion implicite mais que vous êtes sûr qu'une conversion fonctionnera, une conversion de type explicite est parfois possible. Ceci peut entraîner un comportement inattendu et vous permet de contourner certaines mesures de sécurité fonctionnalités du compilateur, assurez-vous donc de tester que le le résultat est ce que vous voulez et attendez! +======= +If the compiler does not allow implicit conversion but you are confident a conversion will work, +an explicit type conversion is sometimes possible. This may +result in unexpected behavior and allows you to bypass some security +features of the compiler, so be sure to test that the +result is what you want and expect! +>>>>>>> english/develop Prenons l'exemple suivant qui convertit un ``int`` négatif en un ``uint`` : @@ -130,6 +138,7 @@ Si le tableau est plus court que le type cible, il sera complété par des zéro } } +.. index:: ! literal;conversion, literal;rational, literal;hexadecimal number .. _types-conversion-literals: Conversions entre littéraux et types élémentaires @@ -152,7 +161,13 @@ suffisamment grand pour le représenter sans troncature : converti en un type entier. Depuis la version 0.8.0, ces conversions explicites sont aussi strictes qu'implicites conversions, c'est-à-dire qu'elles ne sont autorisées que si le littéral correspond à la plage résultante. +<<<<<<< HEAD Tableaux d'octets de taille fixe +======= +.. index:: literal;string, literal;hexadecimal + +Fixed-Size Byte Arrays +>>>>>>> english/develop ---------------------- Les littéraux décimaux ne peuvent pas être implicitement convertis en tableaux d'octets de taille fixe. Hexadécimal @@ -182,12 +197,24 @@ si leur nombre de caractères correspond à la taille du type d'octets : bytes2 e = "x"; // Interdit bytes2 f = "xyz"; // Interdit +.. index:: literal;address + Addresses --------- Comme décrit dans :ref:`address_literals`, les littéraux hexadécimaux de la taille correcte qui passent la somme de contrôle test sont de type ``addresse``. Aucun autre littéral ne peut être implicitement converti en type ``addresse``. +<<<<<<< HEAD Les conversions explicites de ``bytes20`` ou de n'importe quel type d'entier en ``address`` résultent en ``address payable``. Une ``address a`` peut être convertie en ``address payable`` via ``payable(a)``. +======= +Explicit conversions to ``address`` are allowed only from ``bytes20`` and ``uint160``. + +An ``address a`` can be converted explicitly to ``address payable`` via ``payable(a)``. + +.. note:: + Prior to version 0.8.0, it was possible to explicitly convert from any integer type (of any size, signed or unsigned) to ``address`` or ``address payable``. + Starting with in 0.8.0 only conversion from ``uint160`` is allowed. +>>>>>>> english/develop diff --git a/docs/types/mapping-types.rst b/docs/types/mapping-types.rst index dd706fcdd9..f3577f85b5 100644 --- a/docs/types/mapping-types.rst +++ b/docs/types/mapping-types.rst @@ -4,12 +4,22 @@ Type Mapping ============= +<<<<<<< HEAD Les types de mappage utilisent la syntaxe ``mapping(_KeyType => _ValueType)`` et des variables de type mapping sont déclarés en utilisant la syntaxe ``mapping(_KeyType => _ValueType) _VariableName``. Le ``_KeyType`` peut être n'importe quel type de valeur intégré, ``bytes``, ``string``, ou tout type de contrat ou d'énumération. Autre défini par l'utilisateur ou les types complexes, tels que les mappages, les structures ou les types de tableau ne sont pas autorisés. ``_ValueType`` peut être n'importe quel type, y compris les mappages, les tableaux et les structures. +======= +Mapping types use the syntax ``mapping(KeyType KeyName? => ValueType ValueName?)`` and variables of +mapping type are declared using the syntax ``mapping(KeyType KeyName? => ValueType ValueName?) +VariableName``. The ``KeyType`` can be any built-in value type, ``bytes``, ``string``, or any +contract or enum type. Other user-defined or complex types, such as mappings, structs or array types +are not allowed. ``ValueType`` can be any type, including mappings, arrays and structs. ``KeyName`` +and ``ValueName`` are optional (so ``mapping(KeyType => ValueType)`` works as well) and can be any +valid identifier that is not a type. +>>>>>>> english/develop Vous pouvez considérer les mappages comme des `tables de hachage `_, qui sont virtuellement initialisées telle que chaque clé possible existe et est mappée à une valeur dont @@ -28,11 +38,21 @@ Ils ne peuvent pas être utilisés comme paramètres ou paramètres de retour (r des fonctions contractuelles qui sont publiquement visibles. Ces restrictions s'appliquent également aux tableaux et structures contenant des mappages. +<<<<<<< HEAD Vous pouvez marquer les variables d'état de type mappage comme ``public`` et Solidity crée un :ref:`getter ` pour vous. Le ``_KeyType`` devient un paramètre pour le getter. Si ``_ValueType`` est un type valeur ou une structure, le getter renvoie ``_ValueType``. Si ``_ValueType`` est un tableau ou un mappage, le getter a un paramètre pour chaque ``_KeyType``, récursivement. +======= +You can mark state variables of mapping type as ``public`` and Solidity creates a +:ref:`getter ` for you. The ``KeyType`` becomes a parameter +with name ``KeyName`` (if specified) for the getter. +If ``ValueType`` is a value type or a struct, the getter returns ``ValueType`` with +name ``ValueName`` (if specified). +If ``ValueType`` is an array or a mapping, the getter has one parameter for +each ``KeyType``, recursively. +>>>>>>> english/develop Dans l'exemple ci-dessous, le contrat ``MappingExample`` définit un ``balances`` public mappage, avec le type de clé une ``adresse``, et un type de valeur un ``uint``, map @@ -61,10 +81,36 @@ contrat qui renvoie la valeur à l'adresse spécifiée. } } +<<<<<<< HEAD L'exemple ci-dessous est une version simplifiée d'un `Jeton ERC20 `_. ``_allowances`` est un exemple de type de mappage à l'intérieur d'un autre type de mappage. L'exemple ci-dessous utilise ``_allowances`` pour enregistrer le montant que quelqu'un d'autre est autorisé à retirer de votre compte. +======= +The example below is a simplified version of an +`ERC20 token `_. +``_allowances`` is an example of a mapping type inside another mapping type. + +In the example below, the optional ``KeyName`` and ``ValueName`` are provided for the mapping. +It does not affect any contract functionality or bytecode, it only sets the ``name`` field +for the inputs and outputs in the ABI for the mapping's getter. + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity ^0.8.18; + + contract MappingExampleWithNames { + mapping(address user => uint balance) public balances; + + function update(uint newBalance) public { + balances[msg.sender] = newBalance; + } + } + + +The example below uses ``_allowances`` to record the amount someone else is allowed to withdraw from your account. +>>>>>>> english/develop .. code-block:: solidity @@ -73,8 +119,8 @@ L'exemple ci-dessous utilise ``_allowances`` pour enregistrer le montant que que contract MappingExample { - mapping (address => uint256) private _balances; - mapping (address => mapping (address => uint256)) private _allowances; + mapping(address => uint256) private _balances; + mapping(address => mapping(address => uint256)) private _allowances; event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); @@ -116,16 +162,24 @@ L'exemple ci-dessous utilise ``_allowances`` pour enregistrer le montant que que Mapping itérables ----------------- +<<<<<<< HEAD Vous ne pouvez pas itérer les mappages, c'est-à-dire que vous ne pouvez pas énumérer leurs clés. Il est cependant possible d'implémenter une structure de données par dessus d'eux et itérer dessus. Par exemple, le code ci-dessous implémente un bibliothèque ``IterableMapping`` que le contrat ``User`` ajoute également des données, et la fonction ``sum`` effectue une itération pour additionner toutes les valeurs. +======= +You cannot iterate over mappings, i.e. you cannot enumerate their keys. +It is possible, though, to implement a data structure on +top of them and iterate over that. For example, the code below implements an +``IterableMapping`` library that the ``User`` contract then adds data to, and +the ``sum`` function iterates over to sum all the values. +>>>>>>> english/develop .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.6.8 <0.9.0; + pragma solidity ^0.8.8; struct IndexValue { uint keyIndex; uint value; } struct KeyFlag { uint key; bool deleted; } @@ -136,6 +190,8 @@ la fonction ``sum`` effectue une itération pour additionner toutes les valeurs. uint size; } + type Iterator is uint; + library IterableMapping { function insert(itmap storage self, uint key, uint value) internal returns (bool replaced) { uint keyIndex = self.data[key].keyIndex; @@ -165,25 +221,29 @@ la fonction ``sum`` effectue une itération pour additionner toutes les valeurs. return self.data[key].keyIndex > 0; } - function iterate_start(itmap storage self) internal view returns (uint keyIndex) { - return iterate_next(self, type(uint).max); + function iterateStart(itmap storage self) internal view returns (Iterator) { + return iteratorSkipDeleted(self, 0); } - function iterate_valid(itmap storage self, uint keyIndex) internal view returns (bool) { - return keyIndex < self.keys.length; + function iterateValid(itmap storage self, Iterator iterator) internal view returns (bool) { + return Iterator.unwrap(iterator) < self.keys.length; } - function iterate_next(itmap storage self, uint keyIndex) internal view returns (uint r_keyIndex) { - keyIndex++; - while (keyIndex < self.keys.length && self.keys[keyIndex].deleted) - keyIndex++; - return keyIndex; + function iterateNext(itmap storage self, Iterator iterator) internal view returns (Iterator) { + return iteratorSkipDeleted(self, Iterator.unwrap(iterator) + 1); } - function iterate_get(itmap storage self, uint keyIndex) internal view returns (uint key, uint value) { + function iterateGet(itmap storage self, Iterator iterator) internal view returns (uint key, uint value) { + uint keyIndex = Iterator.unwrap(iterator); key = self.keys[keyIndex].key; value = self.data[key].value; } + + function iteratorSkipDeleted(itmap storage self, uint keyIndex) private view returns (Iterator) { + while (keyIndex < self.keys.length && self.keys[keyIndex].deleted) + keyIndex++; + return Iterator.wrap(keyIndex); + } } // Comme l'utiliser @@ -205,11 +265,11 @@ la fonction ``sum`` effectue une itération pour additionner toutes les valeurs. // Calcule la somme de toutes les données stockées. function sum() public view returns (uint s) { for ( - uint i = data.iterate_start(); - data.iterate_valid(i); - i = data.iterate_next(i) + Iterator i = data.iterateStart(); + data.iterateValid(i); + i = data.iterateNext(i) ) { - (, uint value) = data.iterate_get(i); + (, uint value) = data.iterateGet(i); s += value; } } diff --git a/docs/types/operator-precedence-table.rst b/docs/types/operator-precedence-table.rst new file mode 100644 index 0000000000..65034045bb --- /dev/null +++ b/docs/types/operator-precedence-table.rst @@ -0,0 +1,57 @@ +The following is the order of precedence for operators, listed in order of evaluation. + ++------------+-------------------------------------+--------------------------------------------+ +| Precedence | Description | Operator | ++============+=====================================+============================================+ +| *1* | Postfix increment and decrement | ``++``, ``--`` | ++ +-------------------------------------+--------------------------------------------+ +| | New expression | ``new `` | ++ +-------------------------------------+--------------------------------------------+ +| | Array subscripting | ``[]`` | ++ +-------------------------------------+--------------------------------------------+ +| | Member access | ``.`` | ++ +-------------------------------------+--------------------------------------------+ +| | Function-like call | ``()`` | ++ +-------------------------------------+--------------------------------------------+ +| | Parentheses | ``()`` | ++------------+-------------------------------------+--------------------------------------------+ +| *2* | Prefix increment and decrement | ``++``, ``--`` | ++ +-------------------------------------+--------------------------------------------+ +| | Unary minus | ``-`` | ++ +-------------------------------------+--------------------------------------------+ +| | Unary operations | ``delete`` | ++ +-------------------------------------+--------------------------------------------+ +| | Logical NOT | ``!`` | ++ +-------------------------------------+--------------------------------------------+ +| | Bitwise NOT | ``~`` | ++------------+-------------------------------------+--------------------------------------------+ +| *3* | Exponentiation | ``**`` | ++------------+-------------------------------------+--------------------------------------------+ +| *4* | Multiplication, division and modulo | ``*``, ``/``, ``%`` | ++------------+-------------------------------------+--------------------------------------------+ +| *5* | Addition and subtraction | ``+``, ``-`` | ++------------+-------------------------------------+--------------------------------------------+ +| *6* | Bitwise shift operators | ``<<``, ``>>`` | ++------------+-------------------------------------+--------------------------------------------+ +| *7* | Bitwise AND | ``&`` | ++------------+-------------------------------------+--------------------------------------------+ +| *8* | Bitwise XOR | ``^`` | ++------------+-------------------------------------+--------------------------------------------+ +| *9* | Bitwise OR | ``|`` | ++------------+-------------------------------------+--------------------------------------------+ +| *10* | Inequality operators | ``<``, ``>``, ``<=``, ``>=`` | ++------------+-------------------------------------+--------------------------------------------+ +| *11* | Equality operators | ``==``, ``!=`` | ++------------+-------------------------------------+--------------------------------------------+ +| *12* | Logical AND | ``&&`` | ++------------+-------------------------------------+--------------------------------------------+ +| *13* | Logical OR | ``||`` | ++------------+-------------------------------------+--------------------------------------------+ +| *14* | Ternary operator | `` ? : `` | ++ +-------------------------------------+--------------------------------------------+ +| | Assignment operators | ``=``, ``|=``, ``^=``, ``&=``, ``<<=``, | +| | | ``>>=``, ``+=``, ``-=``, ``*=``, ``/=``, | +| | | ``%=`` | ++------------+-------------------------------------+--------------------------------------------+ +| *15* | Comma operator | ``,`` | ++------------+-------------------------------------+--------------------------------------------+ diff --git a/docs/types/operators.rst b/docs/types/operators.rst index e910004493..694f9ad688 100644 --- a/docs/types/operators.rst +++ b/docs/types/operators.rst @@ -3,11 +3,19 @@ Les opérateurs (arithmetique) ========= +<<<<<<< HEAD Les opérateurs arithmétiques et binaires peuvent être appliqués même si les deux opérandes n'ont pas le même type. Par exemple, vous pouvez calculer ``y = x + z``, où ``x`` est un ``uint8`` et ``z`` a le type ``int32``. Dans ces cas, le mécanisme suivant sera utilisé pour déterminer le type dans lequel l'opération est calculée (c'est important en cas de débordement) et le type du résultat de l'opérateur : +======= +Arithmetic and bit operators can be applied even if the two operands do not have the same type. +For example, you can compute ``y = x + z``, where ``x`` is a ``uint8`` and ``z`` has +the type ``uint32``. In these cases, the following mechanism will be used to determine +the type in which the operation is computed (this is important in case of overflow) +and the type of the operator's result: +>>>>>>> english/develop 1. Si le type de l'opérande droit peut être implicitement converti en type de l'opérande gauche utilisez le type de l'opérande de gauche, @@ -15,10 +23,19 @@ et le type du résultat de l'opérateur : utilisez le type de l'opérande de droite, 3. Sinon, l'opération n'est pas autorisée. +<<<<<<< HEAD Dans le cas où l'un des opérandes est un :ref:`literal number ` il est d'abord converti en son "type mobile", qui est le plus petit type pouvant contenir la valeur (les types non signés de même largeur de bit sont considérés comme "plus petits" que les types signés). Si les deux sont des nombres littéraux, l'opération est calculée avec une précision arbitraire. +======= +In case one of the operands is a :ref:`literal number ` it is first converted to its +"mobile type", which is the smallest type that can hold the value +(unsigned types of the same bit-width are considered "smaller" than the signed types). +If both are literal numbers, the operation is computed with effectively unlimited precision in +that the expression is evaluated to whatever precision is necessary so that none is lost +when the result is used with a non-literal type. +>>>>>>> english/develop Le type de résultat de l'opérateur est le même que le type dans lequel l'opération est effectuée, sauf pour les opérateurs de comparaison où le résultat est toujours ``bool``. @@ -26,6 +43,23 @@ sauf pour les opérateurs de comparaison où le résultat est toujours ``bool``. Les opérateurs ``**`` (exponentiation), ``<<`` and ``>>`` utilisent le type du opérande de gauche pour l'opération et le résultat. +Ternary Operator +---------------- +The ternary operator is used in expressions of the form `` ? : ``. +It evaluates one of the latter two given expressions depending upon the result of the evaluation of the main ````. +If ```` evaluates to ``true``, then ```` will be evaluated, otherwise ```` is evaluated. + +The result of the ternary operator does not have a rational number type, even if all of its operands are rational number literals. +The result type is determined from the types of the two operands in the same way as above, converting to their mobile type first if required. + +As a consequence, ``255 + (true ? 1 : 0)`` will revert due to arithmetic overflow. +The reason is that ``(true ? 1 : 0)`` is of ``uint8`` type, which forces the addition to be performed in ``uint8`` as well, +and 256 exceeds the range allowed for this type. + +Another consequence is that an expression like ``1.5 + 1.5`` is valid but ``1.5 + (true ? 1.5 : 2.5)`` is not. +This is because the former is a rational expression evaluated in unlimited precision and only its final value matters. +The latter involves a conversion of a fractional rational number to an integer, which is currently disallowed. + .. index:: assignment, lvalue, ! compound operators Opérateurs composés et d'incrémentation/décrémentation @@ -91,3 +125,11 @@ valeur à laquelle il se référait précédemment. assert(y.length == 0); } } + +.. index:: ! operator; precedence +.. _order: + +Order of Precedence of Operators +-------------------------------- + +.. include:: types/operator-precedence-table.rst diff --git a/docs/types/reference-types.rst b/docs/types/reference-types.rst index 126440321c..d2e9300e64 100644 --- a/docs/types/reference-types.rst +++ b/docs/types/reference-types.rst @@ -47,8 +47,8 @@ non-persistent area where function arguments are stored, and behaves mostly like .. _data-location-assignment: -Data location and assignment behaviour -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Data location and assignment behavior +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data locations are not only relevant for persistency of data, but also for the semantics of assignments: @@ -85,8 +85,10 @@ Data locations are not only relevant for persistency of data, but also for the s // The following does not work; it would need to create a new temporary / // unnamed array in storage, but storage is "statically" allocated: // y = memoryArray; - // This does not work either, since it would "reset" the pointer, but there - // is no sensible location it could point to. + // Similarly, "delete y" is not valid, as assignments to local variables + // referencing storage objects can only be made from existing storage objects. + // It would "reset" the pointer, but there is no sensible location it could point to. + // For more details see the documentation of the "delete" operator. // delete y; g(x); // calls g, handing over a reference to x h(x); // calls h and creates an independent, temporary copy in memory @@ -131,9 +133,13 @@ It is possible to mark state variable arrays ``public`` and have Solidity create The numeric index becomes a required parameter for the getter. Accessing an array past its end causes a failing assertion. Methods ``.push()`` and ``.push(value)`` can be used -to append a new element at the end of the array, where ``.push()`` appends a zero-initialized element and returns +to append a new element at the end of a dynamically-sized array, where ``.push()`` appends a zero-initialized element and returns a reference to it. +.. note:: + Dynamically-sized arrays can only be resized in storage. + In memory, such arrays can be of arbitrary size but the size cannot be changed once an array is allocated. + .. index:: ! string, ! bytes .. _strings: @@ -150,7 +156,7 @@ length or index access. Solidity does not have string manipulation functions, but there are third-party string libraries. You can also compare two strings by their keccak256-hash using ``keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2))`` and -concatenate two strings using ``bytes.concat(bytes(s1), bytes(s2))``. +concatenate two strings using ``string.concat(s1, s2)``. You should use ``bytes`` over ``bytes1[]`` because it is cheaper, since using ``bytes1[]`` in ``memory`` adds 31 padding bytes between the elements. Note that in ``storage``, the @@ -165,31 +171,40 @@ always use one of the value types ``bytes1`` to ``bytes32`` because they are muc that you are accessing the low-level bytes of the UTF-8 representation, and not the individual characters. -.. index:: ! bytes-concat +.. index:: ! bytes-concat, ! string-concat .. _bytes-concat: +.. _string-concat: + +The functions ``bytes.concat`` and ``string.concat`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -``bytes.concat`` function -^^^^^^^^^^^^^^^^^^^^^^^^^ +You can concatenate an arbitrary number of ``string`` values using ``string.concat``. +The function returns a single ``string memory`` array that contains the contents of the arguments without padding. +If you want to use parameters of other types that are not implicitly convertible to ``string``, you need to convert them to ``string`` first. -You can concatenate a variable number of ``bytes`` or ``bytes1 ... bytes32`` using ``bytes.concat``. +Analogously, the ``bytes.concat`` function can concatenate an arbitrary number of ``bytes`` or ``bytes1 ... bytes32`` values. The function returns a single ``bytes memory`` array that contains the contents of the arguments without padding. -If you want to use string parameters or other types, you need to convert them to ``bytes`` or ``bytes1``/.../``bytes32`` first. +If you want to use string parameters or other types that are not implicitly convertible to ``bytes``, you need to convert them to ``bytes`` or ``bytes1``/.../``bytes32`` first. + .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity ^0.8.4; + pragma solidity ^0.8.12; contract C { - bytes s = "Storage"; - function f(bytes calldata c, string memory m, bytes16 b) public view { - bytes memory a = bytes.concat(s, c, c[:2], "Literal", bytes(m), b); - assert((s.length + c.length + 2 + 7 + bytes(m).length + 16) == a.length); + string s = "Storage"; + function f(bytes calldata bc, string memory sm, bytes16 b) public view { + string memory concatString = string.concat(s, string(bc), "Literal", sm); + assert((bytes(s).length + bc.length + 7 + bytes(sm).length) == bytes(concatString).length); + + bytes memory concatBytes = bytes.concat(bytes(s), bc, bc[:2], "Literal", bytes(sm), b); + assert((bytes(s).length + bc.length + 2 + 7 + bytes(sm).length + b.length) == concatBytes.length); } } -If you call ``bytes.concat`` without arguments it will return an empty ``bytes`` array. +If you call ``string.concat`` or ``bytes.concat`` without arguments they return an empty array. .. index:: ! array;allocating, new @@ -220,7 +235,7 @@ with the :ref:`default value`. } } -.. index:: ! array;literals, ! inline;arrays +.. index:: ! literal;array, ! inline;arrays Array Literals ^^^^^^^^^^^^^^ @@ -337,10 +352,10 @@ Array Members Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``push(x)`` that you can use to append a given element at the end of the array. The function returns nothing. -**pop**: +**pop()**: Dynamic storage arrays and ``bytes`` (not ``string``) have a member - function called ``pop`` that you can use to remove an element from the - end of the array. This also implicitly calls :ref:`delete` on the removed element. + function called ``pop()`` that you can use to remove an element from the + end of the array. This also implicitly calls :ref:`delete` on the removed element. The function returns nothing. .. note:: Increasing the length of a storage array by calling ``push()`` @@ -357,7 +372,7 @@ Array Members .. note:: In EVM versions before Byzantium, it was not possible to access - dynamic arrays return from function calls. If you call functions + dynamic arrays returned from function calls. If you call functions that return dynamic arrays, make sure to use an EVM that is set to Byzantium mode. @@ -367,20 +382,22 @@ Array Members pragma solidity >=0.6.0 <0.9.0; contract ArrayContract { - uint[2**20] m_aLotOfIntegers; + uint[2**20] aLotOfIntegers; // Note that the following is not a pair of dynamic arrays but a // dynamic array of pairs (i.e. of fixed size arrays of length two). - // Because of that, T[] is always a dynamic array of T, even if T - // itself is an array. + // In Solidity, T[k] and T[] are always arrays with elements of type T, + // even if T itself is an array. + // Because of that, bool[2][] is a dynamic array of elements + // that are bool[2]. This is different from other languages, like C. // Data location for all state variables is storage. - bool[2][] m_pairsOfFlags; + bool[2][] pairsOfFlags; // newPairs is stored in memory - the only possibility // for public contract function arguments function setAllFlagPairs(bool[2][] memory newPairs) public { // assignment to a storage array performs a copy of ``newPairs`` and - // replaces the complete array ``m_pairsOfFlags``. - m_pairsOfFlags = newPairs; + // replaces the complete array ``pairsOfFlags``. + pairsOfFlags = newPairs; } struct StructType { @@ -402,45 +419,45 @@ Array Members function setFlagPair(uint index, bool flagA, bool flagB) public { // access to a non-existing index will throw an exception - m_pairsOfFlags[index][0] = flagA; - m_pairsOfFlags[index][1] = flagB; + pairsOfFlags[index][0] = flagA; + pairsOfFlags[index][1] = flagB; } function changeFlagArraySize(uint newSize) public { // using push and pop is the only way to change the // length of an array - if (newSize < m_pairsOfFlags.length) { - while (m_pairsOfFlags.length > newSize) - m_pairsOfFlags.pop(); - } else if (newSize > m_pairsOfFlags.length) { - while (m_pairsOfFlags.length < newSize) - m_pairsOfFlags.push(); + if (newSize < pairsOfFlags.length) { + while (pairsOfFlags.length > newSize) + pairsOfFlags.pop(); + } else if (newSize > pairsOfFlags.length) { + while (pairsOfFlags.length < newSize) + pairsOfFlags.push(); } } function clear() public { // these clear the arrays completely - delete m_pairsOfFlags; - delete m_aLotOfIntegers; + delete pairsOfFlags; + delete aLotOfIntegers; // identical effect here - m_pairsOfFlags = new bool[2][](0); + pairsOfFlags = new bool[2][](0); } - bytes m_byteData; + bytes byteData; function byteArrays(bytes memory data) public { // byte arrays ("bytes") are different as they are stored without padding, // but can be treated identical to "uint8[]" - m_byteData = data; + byteData = data; for (uint i = 0; i < 7; i++) - m_byteData.push(); - m_byteData[3] = 0x08; - delete m_byteData[2]; + byteData.push(); + byteData[3] = 0x08; + delete byteData[2]; } function addFlag(bool[2] memory flag) public returns (uint) { - m_pairsOfFlags.push(flag); - return m_pairsOfFlags.length; + pairsOfFlags.push(flag); + return pairsOfFlags.length; } function createMemoryArray(uint size) public pure returns (bytes memory) { @@ -459,6 +476,120 @@ Array Members } } +.. index:: ! array;dangling storage references + +Dangling References to Storage Array Elements +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When working with storage arrays, you need to take care to avoid dangling references. +A dangling reference is a reference that points to something that no longer exists or has been +moved without updating the reference. A dangling reference can for example occur, if you store a +reference to an array element in a local variable and then ``.pop()`` from the containing array: + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.8.0 <0.9.0; + + contract C { + uint[][] s; + + function f() public { + // Stores a pointer to the last array element of s. + uint[] storage ptr = s[s.length - 1]; + // Removes the last array element of s. + s.pop(); + // Writes to the array element that is no longer within the array. + ptr.push(0x42); + // Adding a new element to ``s`` now will not add an empty array, but + // will result in an array of length 1 with ``0x42`` as element. + s.push(); + assert(s[s.length - 1][0] == 0x42); + } + } + +The write in ``ptr.push(0x42)`` will **not** revert, despite the fact that ``ptr`` no +longer refers to a valid element of ``s``. Since the compiler assumes that unused storage +is always zeroed, a subsequent ``s.push()`` will not explicitly write zeroes to storage, +so the last element of ``s`` after that ``push()`` will have length ``1`` and contain +``0x42`` as its first element. + +Note that Solidity does not allow to declare references to value types in storage. These kinds +of explicit dangling references are restricted to nested reference types. However, dangling references +can also occur temporarily when using complex expressions in tuple assignments: + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.8.0 <0.9.0; + + contract C { + uint[] s; + uint[] t; + constructor() { + // Push some initial values to the storage arrays. + s.push(0x07); + t.push(0x03); + } + + function g() internal returns (uint[] storage) { + s.pop(); + return t; + } + + function f() public returns (uint[] memory) { + // The following will first evaluate ``s.push()`` to a reference to a new element + // at index 1. Afterwards, the call to ``g`` pops this new element, resulting in + // the left-most tuple element to become a dangling reference. The assignment still + // takes place and will write outside the data area of ``s``. + (s.push(), g()[0]) = (0x42, 0x17); + // A subsequent push to ``s`` will reveal the value written by the previous + // statement, i.e. the last element of ``s`` at the end of this function will have + // the value ``0x42``. + s.push(); + return s; + } + } + +It is always safer to only assign to storage once per statement and to avoid +complex expressions on the left-hand-side of an assignment. + +You need to take particular care when dealing with references to elements of +``bytes`` arrays, since a ``.push()`` on a bytes array may switch :ref:`from short +to long layout in storage`. + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.8.0 <0.9.0; + + // This will report a warning + contract C { + bytes x = "012345678901234567890123456789"; + + function test() external returns(uint) { + (x.push(), x.push()) = (0x01, 0x02); + return x.length; + } + } + +Here, when the first ``x.push()`` is evaluated, ``x`` is still stored in short +layout, thereby ``x.push()`` returns a reference to an element in the first storage slot of +``x``. However, the second ``x.push()`` switches the bytes array to large layout. +Now the element that ``x.push()`` referred to is in the data area of the array while +the reference still points at its original location, which is now a part of the length field +and the assignment will effectively garble the length of ``x``. +To be safe, only enlarge bytes arrays by at most one element during a single +assignment and do not simultaneously index-access the array in the same statement. + +While the above describes the behavior of dangling storage references in the +current version of the compiler, any code with dangling references should be +considered to have *undefined behavior*. In particular, this means that +any future version of the compiler may change the behavior of code that +involves dangling references. + +Be sure to avoid dangling references in your code! + .. index:: ! array;slice .. _array-slices: @@ -502,21 +633,21 @@ Array slices are useful to ABI-decode secondary data passed in function paramete /// @dev Address of the client contract managed by proxy i.e., this contract address client; - constructor(address _client) { - client = _client; + constructor(address client_) { + client = client_; } /// Forward call to "setOwner(address)" that is implemented by client /// after doing basic validation on the address argument. - function forward(bytes calldata _payload) external { - bytes4 sig = bytes4(_payload[:4]); - // Due to truncating behaviour, bytes4(_payload) performs identically. - // bytes4 sig = bytes4(_payload); + function forward(bytes calldata payload) external { + bytes4 sig = bytes4(payload[:4]); + // Due to truncating behavior, bytes4(payload) performs identically. + // bytes4 sig = bytes4(payload); if (sig == bytes4(keccak256("setOwner(address)"))) { - address owner = abi.decode(_payload[4:], (address)); + address owner = abi.decode(payload[4:], (address)); require(owner != address(0), "Address of owner cannot be zero."); } - (bool status,) = client.delegatecall(_payload); + (bool status,) = client.delegatecall(payload); require(status, "Forwarded call failed."); } } @@ -555,11 +686,11 @@ shown in the following example: uint fundingGoal; uint numFunders; uint amount; - mapping (uint => Funder) funders; + mapping(uint => Funder) funders; } uint numCampaigns; - mapping (uint => Campaign) campaigns; + mapping(uint => Campaign) campaigns; function newCampaign(address payable beneficiary, uint goal) public returns (uint campaignID) { campaignID = numCampaigns++; // campaignID is return variable diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 49e35d9eae..403457111c 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -4,8 +4,7 @@ Value Types =========== -The following types are also called value types because variables of these -types will always be passed by value, i.e. they are always copied when they +The following are called value types because their variables will always be passed by value, i.e. they are always copied when they are used as function arguments or in assignments. .. index:: ! bool, ! true, ! false @@ -47,7 +46,7 @@ access the minimum and maximum value representable by the type. Integers in Solidity are restricted to a certain range. For example, with ``uint32``, this is ``0`` up to ``2**32 - 1``. There are two modes in which arithmetic is performed on these types: The "wrapping" or "unchecked" mode and the "checked" mode. - By default, arithmetic is always "checked", which mean that if the result of an operation falls outside the value range + By default, arithmetic is always "checked", meaning that if an operation's result falls outside the value range of the type, the call is reverted through a :ref:`failing assertion`. You can switch to "unchecked" mode using ``unchecked { ... }``. More details can be found in the section about :ref:`unchecked `. @@ -141,7 +140,7 @@ Exponentiation Exponentiation is only available for unsigned types in the exponent. The resulting type of an exponentiation is always equal to the type of the base. Please take care that it is -large enough to hold the result and prepare for potential assertion failures or wrapping behaviour. +large enough to hold the result and prepare for potential assertion failures or wrapping behavior. .. note:: In checked mode, exponentiation only uses the comparatively cheap ``exp`` opcode for small bases. @@ -182,13 +181,14 @@ Operators: Address ------- -The address type comes in two flavours, which are largely identical: +The address type comes in two largely identical flavors: - ``address``: Holds a 20 byte value (size of an Ethereum address). - ``address payable``: Same as ``address``, but with the additional members ``transfer`` and ``send``. The idea behind this distinction is that ``address payable`` is an address you can send Ether to, -while a plain ``address`` cannot be sent Ether. +while you are not supposed to send Ether to a plain ``address``, for example because it might be a smart contract +that was not built to accept Ether. Type conversions: @@ -209,22 +209,25 @@ an exception to this rule. declare its type as ``address payable`` to make this requirement visible. Also, try to make this distinction or conversion as early as possible. + The distinction between ``address`` and ``address payable`` was introduced with version 0.5.0. + Also starting from that version, contracts are not implicitly convertible to the ``address`` type, but can still be explicitly converted to + ``address`` or to ``address payable``, if they have a receive or payable fallback function. + + Operators: * ``<=``, ``<``, ``==``, ``!=``, ``>=`` and ``>`` .. warning:: If you convert a type that uses a larger byte size to an ``address``, for example ``bytes32``, then the ``address`` is truncated. - To reduce conversion ambiguity version 0.4.24 and higher of the compiler force you make the truncation explicit in the conversion. + To reduce conversion ambiguity, starting with version 0.4.24, the compiler will force you to make the truncation explicit in the conversion. Take for example the 32-byte value ``0x111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFFCCCC``. You can use ``address(uint160(bytes20(b)))``, which results in ``0x111122223333444455556666777788889999aAaa``, or you can use ``address(uint160(uint256(b)))``, which results in ``0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc``. .. note:: - The distinction between ``address`` and ``address payable`` was introduced with version 0.5.0. - Also starting from that version, contracts do not derive from the address type, but can still be explicitly converted to - ``address`` or to ``address payable``, if they have a receive or payable fallback function. + Mixed-case hexadecimal numbers conforming to `EIP-55 `_ are automatically treated as literals of the ``address`` type. See :ref:`Address Literals`. .. _members-of-addresses: @@ -254,13 +257,13 @@ reverts on failure. * ``send`` -Send is the low-level counterpart of ``transfer``. If the execution fails, the current contract will not stop with an exception, but ``send`` will return ``false``. +``send`` is the low-level counterpart of ``transfer``. If the execution fails, the current contract will not stop with an exception, but ``send`` will return ``false``. .. warning:: There are some dangers in using ``send``: The transfer fails if the call stack depth is at 1024 (this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better: - use a pattern where the recipient withdraws the money. + use a pattern where the recipient withdraws the Ether. * ``call``, ``delegatecall`` and ``staticcall`` @@ -329,6 +332,15 @@ on ``call``. regardless of whether state is read from or written to, as this can have many pitfalls. Also, access to gas might change in the future. +<<<<<<< HEAD +======= +* ``code`` and ``codehash`` + +You can query the deployed code for any smart contract. Use ``.code`` to get the EVM bytecode as a +``bytes memory``, which might be empty. Use ``.codehash`` to get the Keccak-256 hash of that code +(as a ``bytes32``). Note that ``addr.codehash`` is cheaper than using ``keccak256(addr.code)``. + +>>>>>>> english/develop .. note:: All contracts can be converted to ``address`` type, so it is possible to query the balance of the current contract using ``address(this).balance``. @@ -406,15 +418,7 @@ Members: .. note:: Prior to version 0.8.0, ``byte`` used to be an alias for ``bytes1``. -Dynamically-sized byte array ----------------------------- - -``bytes``: - Dynamically-sized byte array, see :ref:`arrays`. Not a value-type! -``string``: - Dynamically-sized UTF-8-encoded string, see :ref:`arrays`. Not a value-type! - -.. index:: address, literal;address +.. index:: address, ! literal;address .. _address_literals: @@ -430,7 +434,7 @@ an error. You can prepend (for integer types) or append (for bytesNN types) zero .. note:: The mixed-case address checksum format is defined in `EIP-55 `_. -.. index:: literal, literal;rational +.. index:: integer, rational number, ! literal;rational .. _rational_literals: @@ -441,8 +445,8 @@ Integer literals are formed from a sequence of digits in the range 0-9. They are interpreted as decimals. For example, ``69`` means sixty nine. Octal literals do not exist in Solidity and leading zeros are invalid. -Decimal fractional literals are formed by a ``.`` with at least one number on -one side. Examples include ``1.``, ``.1`` and ``1.3``. +Decimal fractional literals are formed by a ``.`` with at least one number after the decimal point. +Examples include ``.1`` and ``1.3`` (but not ``1.``). Scientific notation in the form of ``2e10`` is also supported, where the mantissa can be fractional but the exponent has to be an integer. @@ -456,7 +460,7 @@ There is no additional semantic meaning added to a number literal containing und the underscores are ignored. Number literal expressions retain arbitrary precision until they are converted to a non-literal type (i.e. by -using them together with a non-literal expression or by explicit conversion). +using them together with anything other than a number literal expression (like boolean literals) or by explicit conversion). This means that computations do not overflow and divisions do not truncate in number literal expressions. @@ -464,6 +468,15 @@ For example, ``(2**800 + 1) - 2**800`` results in the constant ``1`` (of type `` although intermediate results would not even fit the machine word size. Furthermore, ``.5 * 8`` results in the integer ``4`` (although non-integers were used in between). +.. warning:: + While most operators produce a literal expression when applied to literals, there are certain operators that do not follow this pattern: + + - Ternary operator (``... ? ... : ...``), + - Array subscript (``[]``). + + You might expect expressions like ``255 + (true ? 1 : 0)`` or ``255 + [1, 2, 3][0]`` to be equivalent to using the literal 256 + directly, but in fact they are computed within the type ``uint8`` and can overflow. + Any operator that can be applied to integers can also be applied to number literal expressions as long as the operands are integers. If any of the two is fractional, bit operations are disallowed and exponentiation is disallowed if the exponent is fractional (because that might result in @@ -499,7 +512,7 @@ regardless of the type of the right (exponent) operand. uint128 a = 1; uint128 b = 2.5 + a + 0.5; -.. index:: literal, literal;string, string +.. index:: ! literal;string, string .. _string_literals: String Literals and Types @@ -546,6 +559,8 @@ character sequence ``abcdef``. Any Unicode line terminator which is not a newline (i.e. LF, VF, FF, CR, NEL, LS, PS) is considered to terminate the string literal. Newline only terminates the string literal if it is not preceded by a ``\``. +.. index:: ! literal;unicode + Unicode Literals ---------------- @@ -556,7 +571,7 @@ They also support the very same escape sequences as regular string literals. string memory a = unicode"Hello 😃"; -.. index:: literal, bytes +.. index:: ! literal;hexadecimal, bytes Hexadecimal Literals -------------------- @@ -570,7 +585,8 @@ of the hexadecimal sequence. Multiple hexadecimal literals separated by whitespace are concatenated into a single literal: ``hex"00112233" hex"44556677"`` is equivalent to ``hex"0011223344556677"`` -Hexadecimal literals behave like :ref:`string literals ` and have the same convertibility restrictions. +Hexadecimal literals in some ways behave like :ref:`string literals ` but are not +implicitly convertible to the ``string`` type. .. index:: enum @@ -634,18 +650,18 @@ smallest and respectively largest value of the given enum. .. _user-defined-value-types: -User Defined Value Types +User-defined Value Types ------------------------ -A user defined value type allows creating a zero cost abstraction over an elementary value type. +A user-defined value type allows creating a zero cost abstraction over an elementary value type. This is similar to an alias, but with stricter type requirements. -A user defined value type is defined using ``type C is V``, where ``C`` is the name of the newly +A user-defined value type is defined using ``type C is V``, where ``C`` is the name of the newly introduced type and ``V`` has to be a built-in value type (the "underlying type"). The function ``C.wrap`` is used to convert from the underlying type to the custom type. Similarly, the function ``C.unwrap`` is used to convert from the custom type to the underlying type. -The type ``C`` does not have any operators or bound member functions. In particular, even the +The type ``C`` does not have any operators or attached member functions. In particular, even the operator ``==`` is not defined. Explicit and implicit conversions to and from other types are disallowed. @@ -661,7 +677,7 @@ type with 18 decimals and a minimal library to do arithmetic operations on the t // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.8; - // Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type. + // Represent a 18 decimal, 256 bit wide fixed point type using a user-defined value type. type UFixed256x18 is uint256; /// A minimal library to do fixed point operations on UFixed256x18. @@ -751,6 +767,16 @@ confusing, but in essence, if a function is ``payable``, this means that it also accepts a payment of zero Ether, so it also is ``non-payable``. On the other hand, a ``non-payable`` function will reject Ether sent to it, so ``non-payable`` functions cannot be converted to ``payable`` functions. +To clarify, rejecting ether is more restrictive than not rejecting ether. +This means you can override a payable function with a non-payable but not the +other way around. + +Additionally, When you define a ``non-payable`` function pointer, +the compiler does not enforce that the pointed function will actually reject ether. +Instead, it enforces that the function pointer is never used to send ether. +Which makes it possible to assign a ``payable`` function pointer to a ``non-payable`` +function pointer ensuring both types behave the same way, i.e, both cannot be used +to send ether. If a function type variable is not initialised, calling it results in a :ref:`Panic error`. The same happens if you call a function after using ``delete`` @@ -770,6 +796,24 @@ This includes private, internal and public functions of both contracts and libra functions. External function types, on the other hand, are only compatible with public and external contract functions. + +.. note:: + External functions with ``calldata`` parameters are incompatible with external function types with ``calldata`` parameters. + They are compatible with the corresponding types with ``memory`` parameters instead. + For example, there is no function that can be pointed at by a value of type ``function (string calldata) external`` while + ``function (string memory) external`` can point at both ``function f(string memory) external {}`` and + ``function g(string calldata) external {}``. + This is because for both locations the arguments are passed to the function in the same way. + The caller cannot pass its calldata directly to an external function and always ABI-encodes the arguments into memory. + Marking the parameters as ``calldata`` only affects the implementation of the external function and is + meaningless in a function pointer on the caller's side. + +.. warning:: + Comparison of internal function pointers can have unexpected results in the legacy pipeline with the optimizer enabled, + as it can collapse identical functions into one, which will then lead to said function pointers comparing as equal instead of not. + Such comparisons are not advised, and will lead to the compiler issuing a warning, until the next breaking release (0.9.0), + when the warning will be upgraded to an error, thereby making such comparisons disallowed. + Libraries are excluded because they require a ``delegatecall`` and use :ref:`a different ABI convention for their selectors `. Functions declared in interfaces do not have definitions so pointing at them does not make sense either. diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index f0cf6b50b7..7023e75f1d 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -1,8 +1,16 @@ +<<<<<<< HEAD **************************************************** Unités et variables disponibles dans le monde entier **************************************************** +======= +.. index:: ! denomination -.. index:: wei, finney, szabo, gwei, ether +************************************** +Units and Globally Available Variables +************************************** +>>>>>>> english/develop + +.. index:: ! wei, ! finney, ! szabo, ! gwei, ! ether, ! denomination;ether Unités d'éther =========== @@ -21,7 +29,7 @@ Le seul effet du suffixe de sous-dénomination est une multiplication par une pu .. note:: Les dénominations ``finney`` et ``szabo`` ont été supprimées dans la version 0.7.0. -.. index:: time, seconds, minutes, hours, days, weeks, years +.. index:: ! seconds, ! minutes, ! hours, ! days, ! weeks, ! years, ! denomination;time Unités de temps ========== @@ -52,7 +60,7 @@ interpréter un paramètre de fonction en jours, vous pouvez le faire de la mani function f(uint start, uint daysAfter) public { if (block.timestamp >= start + daysAfter * 1 days) { - // ... + // ... } } @@ -65,12 +73,13 @@ Certaines variables et fonctions spéciales existent toujours dans l'espace de n et sont principalement utilisées pour fournir des informations sur la blockchain, ou sont des fonctions utilitaires d'usage général. -.. index:: abi, block, coinbase, difficulty, encode, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, gas price, origin +.. index:: abi, block, coinbase, difficulty, prevrandao, encode, number, block;number, timestamp, block;timestamp, block;basefee, block;blobbasefee, msg, data, gas, sender, value, gas price, origin Propriétés des blocs et des transactions ---------------------------------------- +<<<<<<< HEAD - ``blockhash(uint blockNumber) retourne (bytes32)``: hachage du bloc donné si ``blocknumber`` est l'un des 256 blocs les plus récents ; sinon retourne zéro. - ``block.basefee`` (``uint``): la redevance de base du bloc actuel (`EIP-3198 `_ et `EIP-1559 `_) - ``block.chainid`` (``uint``): identifiant de la chaîne actuelle @@ -86,6 +95,28 @@ Propriétés des blocs et des transactions - ``msg.value`` (``uint``): nombre de wei envoyés avec le message - ``tx.gasprice`` (``uint``): prix du gaz de la transaction - ``tx.origin`` (``address``): expéditeur de la transaction (chaîne d'appel complète) +======= +- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block when ``blocknumber`` is one of the 256 most recent blocks; otherwise returns zero +- ``blobhash(uint index) returns (bytes32)``: versioned hash of the ``index``-th blob associated with the current transaction. + A versioned hash consists of a single byte representing the version (currently ``0x01``), followed by the last 31 bytes + of the SHA256 hash of the KZG commitment (`EIP-4844 `_). +- ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 `_ and `EIP-1559 `_) +- ``block.blobbasefee`` (``uint``): current block's blob base fee (`EIP-7516 `_ and `EIP-4844 `_) +- ``block.chainid`` (``uint``): current chain id +- ``block.coinbase`` (``address payable``): current block miner's address +- ``block.difficulty`` (``uint``): current block difficulty (``EVM < Paris``). For other EVM versions it behaves as a deprecated alias for ``block.prevrandao`` (`EIP-4399 `_ ) +- ``block.gaslimit`` (``uint``): current block gaslimit +- ``block.number`` (``uint``): current block number +- ``block.prevrandao`` (``uint``): random number provided by the beacon chain (``EVM >= Paris``) +- ``block.timestamp`` (``uint``): current block timestamp as seconds since unix epoch +- ``gasleft() returns (uint256)``: remaining gas +- ``msg.data`` (``bytes calldata``): complete calldata +- ``msg.sender`` (``address``): sender of the message (current call) +- ``msg.sig`` (``bytes4``): first four bytes of the calldata (i.e. function identifier) +- ``msg.value`` (``uint``): number of wei sent with the message +- ``tx.gasprice`` (``uint``): gas price of the transaction +- ``tx.origin`` (``address``): sender of the transaction (full call chain) +>>>>>>> english/develop .. note:: Les valeurs de tous les membres de ``msg``, y compris ``msg.sender`` et @@ -102,9 +133,15 @@ Propriétés des blocs et des transactions Ne comptez pas sur ``block.timestamp`` ou ``blockhash`` comme source d'aléatoire, à moins que vous ne sachiez ce que vous faites. +<<<<<<< HEAD L'horodatage et le hachage du bloc peuvent tous deux être influencés par les mineurs dans une certaine mesure. De mauvais acteurs dans la communauté minière peuvent par exemple exécuter une fonction de paiement de casino sur un hash choisi et réessayer un autre hash s'ils n'ont pas reçu d'argent. +======= + Both the timestamp and the block hash can be influenced by miners to some degree. + Bad actors in the mining community can for example run a casino payout function on a chosen hash + and just retry a different hash if they did not receive any compensation, e.g. Ether. +>>>>>>> english/develop L'horodatage du bloc actuel doit être strictement plus grand que l'horodatage du dernier bloc, mais la seule garantie est qu'il se situera quelque part entre les horodatages de deux @@ -154,6 +191,14 @@ Membres des octets - ``bytes.concat(...) retourne (bytes memory)``: :ref:`Concatène un nombre variable d'octets et les arguments bytes1, ..., bytes32 dans un tableau d'octets.` +.. index:: string members + +Members of string +----------------- + +- ``string.concat(...) returns (string memory)``: :ref:`Concatenates variable number of string arguments to one string array` + + .. index:: assert, revert, require Traitement des erreurs @@ -223,10 +268,15 @@ Fonctions mathématiques et cryptographiques pour les signatures _transaction_ (voir `EIP-2 `_), mais la fonction ecrecover est restée inchangée. +<<<<<<< HEAD Ce n'est généralement pas un problème, à moins que vous n'exigiez que les signatures soient uniques ou que vous les utilisiez pour identifier des éléments. OpenZeppelin a une `ECDSA helper library `_ que vous pouvez utiliser comme un wrapper pour ``ecrecover`` sans ce problème. +======= + This is usually not a problem unless you require signatures to be unique or use them to identify items. + OpenZeppelin has an `ECDSA helper library `_ that you can use as a wrapper for ``ecrecover`` without this issue. +>>>>>>> english/develop .. note:: @@ -270,10 +320,17 @@ Pour plus d'informations, consultez la section sur :ref:`adress`. la vérification de type le contrôle d'existence de la fonction et l'emballage des arguments. .. warning:: +<<<<<<< HEAD Il y a quelques dangers à utiliser ``send`` : Le transfert échoue si la profondeur de la pile d'appel est à 1024 (ceci peut toujours être forcé par l'appelant) et il échoue également si le destinataire tombe en panne sèche. Donc, afin de de faire des transferts d'Ether sûrs, vérifiez toujours la valeur de retour de ``send``, utilisez ``transfer`` ou encore mieux : Utilisez un modèle où le destinataire retire l'argent. +======= + There are some dangers in using ``send``: The transfer fails if the call stack depth is at 1024 + (this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order + to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better: + Use a pattern where the recipient withdraws the Ether. +>>>>>>> english/develop .. warning:: En raison du fait que l'EVM considère qu'un appel à un contrat inexistant réussit toujours, @@ -304,13 +361,24 @@ Pour plus d'informations, consultez la section sur :ref:`adress`. sémantique similaire mais légèrement différente de celle de ``delegatecall``. -.. index:: this, selfdestruct +.. index:: this, selfdestruct, super +<<<<<<< HEAD Concernant les contrats ----------------------- ``this`` (le type du contrat actuel) le contrat actuel, explicitement convertible en :ref:`address`. +======= +Contract-related +---------------- + +``this`` (current contract's type) + The current contract, explicitly convertible to :ref:`address` + +``super`` + A contract one level higher in the inheritance hierarchy +>>>>>>> english/develop ``selfdestruct(address payable recipient)`` Détruit le contrat actuel, en envoyant ses fonds à l'adresse :ref:`address` donnée @@ -320,10 +388,19 @@ Concernant les contrats - la fonction de réception du contrat récepteur n'est pas exécutée. - le contrat n'est réellement détruit qu'à la fin de la transaction et les ``revert`` peuvent "annuler" la destruction. +<<<<<<< HEAD En outre, toutes les fonctions du contrat en cours sont appelables directement, y compris la fonction en cours. +======= +Furthermore, all functions of the current contract are callable directly including the current function. +>>>>>>> english/develop + +.. warning:: + From version 0.8.18 and up, the use of ``selfdestruct`` in both Solidity and Yul will trigger a + deprecation warning, since the ``SELFDESTRUCT`` opcode will eventually undergo breaking changes in behavior + as stated in `EIP-6049 `_. .. note:: Avant la version 0.5.0, il existait une fonction appelée ``suicide`` ayant la même @@ -365,10 +442,17 @@ Les propriétés suivantes sont disponibles pour un type de contrat ``C`` : En plus des propriétés ci-dessus, les propriétés suivantes sont disponibles pour une interface de type ``I`` : +<<<<<<< HEAD ``type(I).interfaceId``: Une valeur ``bytes4`` contenant le `EIP-165 `_ de l'interface ``I`` donnée. Cet identificateur est défini comme étant le ``XOR`` de tous les sélecteurs de fonctions définis dans l'interface elle-même - à l'exclusion de toutes les fonctions héritées. +======= +``type(I).interfaceId`` + A ``bytes4`` value containing the `EIP-165 `_ + interface identifier of the given interface ``I``. This identifier is defined as the ``XOR`` of all + function selectors defined within the interface itself - excluding all inherited functions. +>>>>>>> english/develop Les propriétés suivantes sont disponibles pour un type entier ``T`` : @@ -376,4 +460,19 @@ Les propriétés suivantes sont disponibles pour un type entier ``T`` : La plus petite valeur représentable par le type ``T``. ``type(T).max`` +<<<<<<< HEAD La plus grande valeur représentable par le type ``T``. +======= + The largest value representable by type ``T``. + +Reserved Keywords +================= + +These keywords are reserved in Solidity. They might become part of the syntax in the future: + +``after``, ``alias``, ``apply``, ``auto``, ``byte``, ``case``, ``copyof``, ``default``, +``define``, ``final``, ``implements``, ``in``, ``inline``, ``let``, ``macro``, ``match``, +``mutable``, ``null``, ``of``, ``partial``, ``promise``, ``reference``, ``relocatable``, +``sealed``, ``sizeof``, ``static``, ``supports``, ``switch``, ``typedef``, ``typeof``, +``var``. +>>>>>>> english/develop diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 3019479221..ad519af0b3 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -15,9 +15,15 @@ Utilisation du compilateur en ligne de commande Utilisation de base ------------------- +<<<<<<< HEAD L'une des cibles de construction du référentiel Solidity est ``solc``, le compilateur en ligne de commande de Solidity. L'utilisation de ``solc --help`` vous fournit une explication de toutes les options. Le compilateur peut produire diverses sorties, allant de simples binaires et assemblages sur un arbre syntaxique abstrait (parse tree) à des estimations de l'utilisation du gaz. Si vous voulez seulement compiler un seul fichier, vous le lancez comme ``solc --bin sourceFile.sol`` et il imprimera le binaire. Si vous voulez obtenir certaines des variantes de sortie plus avancées de ``solc``, il est probablement préférable de lui dire de tout sortir dans des fichiers séparés en utilisant ``solc -o outputDirectory --bin --ast-compact-json --asm sourceFile.sol``. +======= +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-compact-json --asm sourceFile.sol``. +>>>>>>> english/develop Options de l'optimiseur ----------------------- @@ -53,6 +59,7 @@ sont traités comme relatifs aux répertoires spécifiés en utilisant les optio (ou le répertoire de travail actuel si le chemin de base n'est pas spécifié). De plus, la partie du chemin ajoutée via ces options n'apparaîtra pas dans les métadonnées du contrat. +<<<<<<< HEAD Pour des raisons de sécurité, le compilateur a des :ref:`restrictions sur les répertoires auxquels il peut accéder `. Les répertoires des fichiers sources spécifiés sur la ligne de commande et les chemins cibles des remappings sont automatiquement autorisés à être accédés par le lecteur de fichiers, mais @@ -60,6 +67,15 @@ tout le reste est rejeté par défaut. Des chemins supplémentaires (et leurs sous-répertoires) peuvent être autorisés via la commande ``--allow-paths /sample/path,/another/sample/path``. Tout ce qui se trouve à l'intérieur du chemin spécifié par ``--base-path`` est toujours autorisé. +======= +For security reasons the compiler has :ref:`restrictions on what directories it can access `. +Directories of source files specified on the command-line and target paths of +remappings are automatically allowed to be accessed by the file reader, but everything +else is rejected by default. +Additional paths (and their subdirectories) can be allowed via the +``--allow-paths /sample/path,/another/sample/path`` switch. +Everything inside the path specified via ``--base-path`` is always allowed. +>>>>>>> english/develop Ce qui précède n'est qu'une simplification de la façon dont le compilateur gère les chemins d'importation. Pour une explication détaillée avec des exemples et une discussion des cas de coin, veuillez vous référer à la section sur @@ -113,6 +129,7 @@ Si ``solc`` est appelé avec l'option ``--link``, tous les fichiers d'entrée so Réglage de la version de l'EVM sur la cible ******************************************* +<<<<<<< HEAD Lorsque vous compilez le code de votre contrat, vous pouvez spécifier la version de la machine virtuelle d'Ethereum pour laquelle compiler afin d'éviter des caractéristiques ou des comportements particuliers. @@ -123,6 +140,18 @@ pour laquelle compiler afin d'éviter des caractéristiques ou des comportements utilisez les versions EVM correspondantes. Sur la ligne de commande, vous pouvez sélectionner la version EVM comme suit : +======= +When you compile your contract code you can specify the Ethereum virtual machine +version to compile for to avoid particular features or behaviors. + +.. warning:: + + Compiling for the wrong EVM version can result in wrong, strange and failing + behavior. Please ensure, especially if running a private chain, that you + use matching EVM versions. + +On the command-line, you can select the EVM version as follows: +>>>>>>> english/develop .. code-block:: shell @@ -147,6 +176,7 @@ Options de la cible Vous trouverez ci-dessous une liste des versions EVM cibles et des modifications relatives au compilateur introduites à chaque version. La rétrocompatibilité n'est pas garantie entre chaque version. +<<<<<<< HEAD - ``homestead`` - (version la plus ancienne) - ``tangerineWhistle`` @@ -162,17 +192,51 @@ Vous trouverez ci-dessous une liste des versions EVM cibles et des modifications - ``constantinople`` - Les opcodes ``create2``, ``extcodehash'', ``shl``, ``shr`` et ``sar`` sont disponibles en assembleur. - Les opérateurs de décalage utilisent des opcodes de décalage et nécessitent donc moins de gaz. +======= +- ``homestead`` (*support deprecated*) + - (oldest version) +- ``tangerineWhistle`` (*support deprecated*) + - Gas cost for access to other accounts increased, relevant for gas estimation and the optimizer. + - All gas sent by default for external calls, previously a certain amount had to be retained. +- ``spuriousDragon`` (*support deprecated*) + - Gas cost for the ``exp`` opcode increased, relevant for gas estimation and the optimizer. +- ``byzantium`` (*support deprecated*) + - Opcodes ``returndatacopy``, ``returndatasize`` and ``staticcall`` are available in assembly. + - The ``staticcall`` opcode is used when calling non-library view or pure functions, which prevents the functions from modifying state at the EVM level, i.e., even applies when you use invalid type conversions. + - It is possible to access dynamic data returned from function calls. + - ``revert`` opcode introduced, which means that ``revert()`` will not waste gas. +- ``constantinople`` + - Opcodes ``create2``, ``extcodehash``, ``shl``, ``shr`` and ``sar`` are available in assembly. + - Shifting operators use shifting opcodes and thus need less gas. +>>>>>>> english/develop - ``petersburg`` - Le compilateur se comporte de la même manière qu'avec constantinople. - ``istanbul`` - Les opcodes ``chainid`` et ``selfbalance`' sont disponibles en assemblage. - ``berlin`` +<<<<<<< HEAD - Les coûts du gaz pour ``LOAD``, ``*CALL``, ``BALANCE``, ``EXT`` et ``SELFDESTRUCT`` ont augmenté. Le compilateur suppose des coûts de gaz froid pour de telles opérations. Ceci est pertinent pour l'estimation des gaz et l'optimiseur. - ``london`` (**default**) - Le tarif de base du bloc (`EIP-3198 `_ et `EIP-1559 `_) est accessible via le global ``block.basefee`` ou ``basefee()`` en assemblage inline. +======= + - Gas costs for ``SLOAD``, ``*CALL``, ``BALANCE``, ``EXT*`` and ``SELFDESTRUCT`` increased. The + compiler assumes cold gas costs for such operations. This is relevant for gas estimation and + the optimizer. +- ``london`` + - The block's base fee (`EIP-3198 `_ and `EIP-1559 `_) can be accessed via the global ``block.basefee`` or ``basefee()`` in inline assembly. +- ``paris`` + - Introduces ``prevrandao()`` and ``block.prevrandao``, and changes the semantics of the now deprecated ``block.difficulty``, disallowing ``difficulty()`` in inline assembly (see `EIP-4399 `_). +- ``shanghai`` (**default**) + - Smaller code size and gas savings due to the introduction of ``push0`` (see `EIP-3855 `_). +- ``cancun`` + - The block's blob base fee (`EIP-7516 `_ and `EIP-4844 `_) can be accessed via the global ``block.blobbasefee`` or ``blobbasefee()`` in inline assembly. + - Introduces ``blobhash()`` in inline assembly and a corresponding global function to retrieve versioned hashes of blobs associated with the transaction (see `EIP-4844 `_). + - Opcode ``mcopy`` is available in assembly (see `EIP-5656 `_). + - Opcodes ``tstore`` and ``tload`` are available in assembly (see `EIP-1153 `_). +>>>>>>> english/develop .. index:: ! standard JSON, ! --standard-json .. _compiler-api: @@ -200,7 +264,11 @@ Description de l'entrée .. code-block:: javascript { +<<<<<<< HEAD // Requis : Langue du code source. Les langages actuellement pris en charge sont "Solidity" et "Yul". +======= + // Required: Source code language. Currently supported are "Solidity", "Yul", "SolidityAST" (experimental), "EVMAssembly" (experimental). +>>>>>>> english/develop "language": "Solidity", // Requis "sources": @@ -224,7 +292,11 @@ Description de l'entrée "bzzr://56ab...", "ipfs://Qma...", "/tmp/path/to/file.sol" +<<<<<<< HEAD // Si des fichiers sont utilisés, leurs répertoires doivent être ajoutés à la ligne de commande via +======= + // If files are used, their directories should be added to the command-line via +>>>>>>> english/develop // `--allow-paths `. ] }, @@ -234,6 +306,33 @@ Description de l'entrée "keccak256": "0x234...", // Obligatoire (sauf si "urls" est utilisé) : contenu littéral du fichier source "content": "contract destructible is owned { function shutdown() { if (msg.sender == owner) selfdestruct(owner); } }" + }, + "myFile.sol_json.ast": + { + // If language is set to "SolidityAST", an AST needs to be supplied under the "ast" key + // and there can be only one source file present. + // The format is the same as used by the `ast` output. + // Note that importing ASTs is experimental and in particular that: + // - importing invalid ASTs can produce undefined results and + // - no proper error reporting is available on invalid ASTs. + // Furthermore, note that the AST import only consumes the fields of the AST as + // produced by the compiler in "stopAfter": "parsing" mode and then re-performs + // analysis, so any analysis-based annotations of the AST are ignored upon import. + "ast": { ... } + }, + "myFile_evm.json": + { + // If language is set to "EVMAssembly", an EVM Assembly JSON object needs to be supplied + // under the "assemblyJson" key and there can be only one source file present. + // The format is the same as used by the `evm.legacyAssembly` output or `--asm-json` + // output on the command line. + // Note that importing EVM assembly is experimental. + "assemblyJson": + { + ".code": [ ... ], + ".data": { ... }, // optional + "sourceList": [ ... ] // optional (if no `source` node was defined in any `.code` object) + } } }, // Optionnel @@ -262,11 +361,19 @@ Description de l'entrée // L'optimiseur de trou d'homme est toujours activé si aucun détail n'est donné, // utilisez les détails pour le désactiver. "peephole": true, +<<<<<<< HEAD // L'inliner est toujours activé si aucun détail n'est donné, // utilisez les détails pour le désactiver. "inliner": true, // L'enlèvement du jumpdest inutilisé est toujours activé si aucun détail n'est donné, // utilisez les détails pour le désactiver. +======= + // The inliner is always off if no details are given, + // use details to switch it on. + "inliner": false, + // The unused jumpdest remover is always on if no details are given, + // use details to switch it off. +>>>>>>> english/develop "jumpdestRemover": true, // Réorganise parfois les littéraux dans les opérations commutatives. "orderLiterals": false, @@ -277,29 +384,65 @@ Description de l'entrée "cse": false, // Optimiser la représentation des nombres littéraux et des chaînes de caractères dans le code. "constantOptimizer": false, +<<<<<<< HEAD // Le nouvel optimiseur Yul. Opère principalement sur le code du codeur ABI v2 // et de l'assemblage en ligne. // Il est activé en même temps que le réglage de l'optimiseur global // et peut être désactivé ici. // Avant Solidity 0.6.0, il devait être activé par ce commutateur. +======= + // Use unchecked arithmetic when incrementing the counter of for loops + // under certain circumstances. It is always on if no details are given. + "simpleCounterForLoopUncheckedIncrement": true, + // The new Yul optimizer. Mostly operates on the code of ABI coder v2 + // and inline assembly. + // It is activated together with the global optimizer setting + // and can be deactivated here. + // Before Solidity 0.6.0 it had to be activated through this switch. +>>>>>>> english/develop "yul": false, // Tuning options for the Yul optimizer. "yulDetails": { // Améliore l'allocation des emplacements de pile pour les variables, peut libérer les emplacements de pile plus tôt. // Activé par défaut si l'optimiseur Yul est activé. "stackAllocation": true, +<<<<<<< HEAD // Sélectionnez les étapes d'optimisation à appliquer. // Facultatif, l'optimiseur utilisera la séquence par défaut si elle est omise. +======= + // Select optimization steps to be applied. It is also possible to modify both the + // optimization sequence and the clean-up sequence. Instructions for each sequence + // are separated with the ":" delimiter and the values are provided in the form of + // optimization-sequence:clean-up-sequence. For more information see + // "The Optimizer > Selecting Optimizations". + // This field is optional, and if not provided, the default sequences for both + // optimization and clean-up are used. If only one of the sequences is provided + // the other will not be run. + // If only the delimiter ":" is provided then neither the optimization nor the clean-up + // sequence will be run. + // If set to an empty value, only the default clean-up sequence is used and + // no optimization steps are applied. +>>>>>>> english/develop "optimizerSteps": "dhfoDgvulfnTUtnIf..." } } }, +<<<<<<< HEAD // Version de l'EVM pour laquelle il faut compiler. // Affecte la vérification de type et la génération de code. Peut être homestead, // tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg, istanbul ou berlin. "evmVersion": "byzantium", // Facultatif : Modifier le pipeline de compilation pour passer par la représentation intermédiaire de Yul. // Il s'agit d'une fonctionnalité hautement EXPERIMENTALE, à ne pas utiliser en production. Elle est désactivée par défaut. +======= + // Version of the EVM to compile for. + // Affects type checking and code generation. Can be homestead, + // tangerineWhistle, spuriousDragon, byzantium, constantinople, + // petersburg, istanbul, berlin, london, paris or shanghai (default) + "evmVersion": "shanghai", + // Optional: Change compilation pipeline to go through the Yul intermediate representation. + // This is false by default. +>>>>>>> english/develop "viaIR": true, // Facultatif : Paramètres de débogage "debug": { @@ -324,7 +467,14 @@ Description de l'entrée }, // Paramètres des métadonnées (facultatif) "metadata": { +<<<<<<< HEAD // Utiliser uniquement le contenu littéral et non les URL (faux par défaut) +======= + // The CBOR metadata is appended at the end of the bytecode by default. + // Setting this to false omits the metadata from the runtime and deploy time code. + "appendCBOR": true, + // Use only literal content and not URLs (false by default) +>>>>>>> english/develop "useLiteralContent": true, // Utilisez la méthode de hachage donnée pour le hachage des métadonnées qui est ajouté au bytecode. // Le hachage des métadonnées peut être supprimé du bytecode via l'option "none". @@ -335,10 +485,17 @@ Description de l'entrée // Adresses des bibliothèques. Si toutes les bibliothèques ne sont pas données ici, // il peut en résulter des objets non liés dont les données de sortie sont différentes. "libraries": { +<<<<<<< HEAD // La clé de premier niveau est le nom du fichier source dans lequel la bibliothèque est utilisée. // Si des remappages sont utilisés, ce fichier source doit correspondre au chemin global // après que les remappages aient été appliqués. // Si cette clé est une chaîne vide, cela fait référence à un niveau global. +======= + // The top level key is the name of the source file where the library is used. + // If remappings are used, this source file should match the global path + // after remappings were applied. + // If this key is an empty string, that refers to a global level. +>>>>>>> english/develop "myFile.sol": { "MyLib": "0x123123..." } @@ -384,8 +541,36 @@ Description de l'entrée // ewasm.wast - Ewasm au format S-expressions de WebAssembly // ewasm.wasm - Ewasm au format binaire WebAssembly // +<<<<<<< HEAD // Notez que l'utilisation d'un `evm`, `evm.bytecode`, `ewasm`, etc. sélectionnera chaque // partie cible de cette sortie. De plus, `*` peut être utilisé comme un joker pour tout demander. +======= + // Contract level (needs the contract name or "*"): + // abi - ABI + // devdoc - Developer documentation (natspec) + // userdoc - User documentation (natspec) + // metadata - Metadata + // ir - Yul intermediate representation of the code before optimization + // irAst - AST of Yul intermediate representation of the code before optimization + // irOptimized - Intermediate representation after optimization + // irOptimizedAst - AST of intermediate representation after optimization + // storageLayout - Slots, offsets and types of the contract's state variables. + // evm.assembly - New assembly format + // evm.legacyAssembly - Old-style assembly format in JSON + // evm.bytecode.functionDebugData - Debugging information at function level + // evm.bytecode.object - Bytecode object + // evm.bytecode.opcodes - Opcodes list + // evm.bytecode.sourceMap - Source mapping (useful for debugging) + // evm.bytecode.linkReferences - Link references (if unlinked object) + // evm.bytecode.generatedSources - Sources generated by the compiler + // evm.deployedBytecode* - Deployed bytecode (has all the options that evm.bytecode has) + // evm.deployedBytecode.immutableReferences - Map from AST ids to bytecode ranges that reference immutables + // evm.methodIdentifiers - The list of function hashes + // evm.gasEstimates - Function gas estimates + // + // Note that using `evm`, `evm.bytecode`, etc. will select every + // target part of that output. Additionally, `*` can be used as a wildcard to request everything. +>>>>>>> english/develop // "outputSelection": { "*": { @@ -411,6 +596,7 @@ Description de l'entrée "source1.sol": ["contract1"], "source2.sol": ["contract2", "contract3"] }, +<<<<<<< HEAD // Choisir si les opérations de division et de modulo doivent être remplacées par // multiplication avec des variables de type slack. La valeur par défaut est `true`. // L'utilisation de `false` ici est recommandée si vous utilisez le moteur CHC @@ -425,6 +611,31 @@ Description de l'entrée "showUnproved": true, // Choisissez les solveurs à utiliser, s'ils sont disponibles. // Voir la section Vérification formelle pour la description des solveurs. +======= + // Choose how division and modulo operations should be encoded. + // When using `false` they are replaced by multiplication with slack + // variables. This is the default. + // Using `true` here is recommended if you are using the CHC engine + // and not using Spacer as the Horn solver (using Eldarica, for example). + // See the Formal Verification section for a more detailed explanation of this option. + "divModNoSlacks": false, + // Choose which model checker engine to use: all (default), bmc, chc, none. + "engine": "chc", + // Choose whether external calls should be considered trusted in case the + // code of the called function is available at compile-time. + // For details see the SMTChecker section. + "extCalls": "trusted", + // Choose which types of invariants should be reported to the user: contract, reentrancy. + "invariants": ["contract", "reentrancy"], + // Choose whether to output all proved targets. The default is `false`. + "showProved": true, + // Choose whether to output all unproved targets. The default is `false`. + "showUnproved": true, + // Choose whether to output all unsupported language features. The default is `false`. + "showUnsupported": true, + // Choose which solvers should be used, if available. + // See the Formal Verification section for the solvers description. +>>>>>>> english/develop "solvers": ["cvc4", "smtlib2", "z3"], // Choisissez les cibles à vérifier : constantCondition, // underflow, overflow, divByZero, balance, assert, popEmptyArray, outOfBounds. @@ -469,7 +680,11 @@ Description de la sortie // Obligatoire : Type d'erreur, tel que "TypeError", "InternalCompilerError", "Exception", etc. // Voir ci-dessous pour la liste complète des types. "type": "TypeError", +<<<<<<< HEAD // Obligatoire : Composant d'où provient l'erreur, tel que "general", "ewasm", etc. +======= + // Mandatory: Component where the error originated, such as "general" etc. +>>>>>>> english/develop "component": "general", // Obligatoire ("error", "warning" ou "info", mais veuillez noter que cela pourrait être étendu à l'avenir) "severity": "error", @@ -506,9 +721,21 @@ Description de la sortie "userdoc": {}, // Documentation pour les développeurs (natspec) "devdoc": {}, +<<<<<<< HEAD // Représentation intermédiaire (chaîne de caractères) "ir": "", // Voir la documentation sur l'agencement du stockage. +======= + // Intermediate representation before optimization (string) + "ir": "", + // AST of intermediate representation before optimization + "irAst": {/* ... */}, + // Intermediate representation after optimization (string) + "irOptimized": "", + // AST of intermediate representation after optimization + "irOptimizedAst": {/* ... */}, + // See the Storage Layout documentation. +>>>>>>> english/develop "storageLayout": {"storage": [/* ... */], "types": {/* ... */} }, // Sorties liées à l'EVM "evm": { @@ -585,6 +812,7 @@ Description de la sortie "heavyLifting()": "infinite" } } +<<<<<<< HEAD }, // Sorties liées à l'Ewasm "ewasm": { @@ -592,6 +820,8 @@ Description de la sortie "wast": "", // Format binaire (chaîne hexagonale) "wasm": "" +======= +>>>>>>> english/develop } } } @@ -602,6 +832,7 @@ Description de la sortie Types d'erreurs ~~~~~~~~~~~~~~~ +<<<<<<< HEAD 1. ``JSONError`` : L'entrée JSON n'est pas conforme au format requis, par exemple, l'entrée n'est pas un objet JSON, la langue n'est pas supportée, etc. 2. ``IOError`` : Erreurs de traitement des entrées/sorties et des importations, telles qu'une URL non résoluble ou une erreur de hachage dans les sources fournies. 3. ``ParserError`` : Le code source n'est pas conforme aux règles du langage. @@ -842,3 +1073,20 @@ have to be updated manually.) d.f{value: 5}(); } } +======= +1. ``JSONError``: JSON input doesn't conform to the required format, e.g. input is not a JSON object, the language is not supported, etc. +2. ``IOError``: IO and import processing errors, such as unresolvable URL or hash mismatch in supplied sources. +3. ``ParserError``: Source code doesn't conform to the language rules. +4. ``DocstringParsingError``: The NatSpec tags in the comment block cannot be parsed. +5. ``SyntaxError``: Syntactical error, such as ``continue`` is used outside of a ``for`` loop. +6. ``DeclarationError``: Invalid, unresolvable or clashing identifier names. e.g. ``Identifier not found`` +7. ``TypeError``: Error within the type system, such as invalid type conversions, invalid assignments, etc. +8. ``UnimplementedFeatureError``: Feature is not supported by the compiler, but is expected to be supported in future versions. +9. ``InternalCompilerError``: Internal bug triggered in the compiler - this should be reported as an issue. +10. ``Exception``: Unknown failure during compilation - this should be reported as an issue. +11. ``CompilerError``: Invalid use of the compiler stack - this should be reported as an issue. +12. ``FatalError``: Fatal error not processed correctly - this should be reported as an issue. +13. ``YulException``: Error during Yul code generation - this should be reported as an issue. +14. ``Warning``: A warning, which didn't stop the compilation, but should be addressed if possible. +15. ``Info``: Information that the compiler thinks the user might find useful, but is not dangerous and does not necessarily need to be addressed. +>>>>>>> english/develop diff --git a/docs/yul.rst b/docs/yul.rst index c000e516c3..e47ec64ff3 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -9,6 +9,7 @@ Yul Yul (précédemment aussi appelé JULIA ou IULIA) est un langage intermédiaire qui peut être compilé en bytecode pour différents backends. +<<<<<<< HEAD Le support d'EVM 1.0, EVM 1.5 et Ewasm est prévu, et il est conçu pour être un dénominateur commun utilisable pour ces trois plateformes. Il peut déjà être utilisé en mode autonome et @@ -16,6 +17,11 @@ pour "l'assemblage en ligne" dans Solidity et il existe une implémentation expérimentale du compilateur Solidity qui utilise Yul comme langage intermédiaire. Le Yul est une bonne cible pour étapes d'optimisation de haut niveau qui peuvent bénéficier à toutes les plates-formes cibles de manière égale. +======= +It can be used in stand-alone mode and for "inline assembly" inside Solidity. +The compiler uses Yul as an intermediate language in the IR-based code generator ("new codegen" or "IR-based codegen"). +Yul is a good target for high-level optimisation stages that can benefit all target platforms equally. +>>>>>>> english/develop Motivation et description de haut niveau ======================================== @@ -87,9 +93,14 @@ Il peut être compilé en utilisant ``solc --strict-assembly``. Les fonctions in } } +<<<<<<< HEAD Le programme d'exemple suivant est écrit dans le dialecte EVM et calcule l'exponentiation. Il peut être compilé en utilisant ``solc --strict-assembly``. Les fonctions intégrées ``mul`` et ``div`` calculent le produit et la division, respectivement. +======= +It is also possible to implement the same function using a for-loop +instead of with recursion. Here, ``lt(a, b)`` computes whether ``a`` is less than ``b``. +>>>>>>> english/develop .. code-block:: yul @@ -157,6 +168,7 @@ où un objet est attendu. Inside a code block, the following elements can be used (see the later sections for more details): +<<<<<<< HEAD - des littéraux, par exemple ``0x123``, ``42`` ou ``"abc"`` (chaînes de caractères jusqu'à 32 caractères) - les appels à des fonctions intégrées, par exemple ``add(1, mload(0))`` - les déclarations de variables, par exemple ``let x := 7``, "let x := add(y, 3)`` ou ``let x`` (la valeur initiale de 0 est attribuée) @@ -167,12 +179,31 @@ Inside a code block, the following elements can be used - les instructions switch, par exemple : ``switch mload(0) case 0 { revert() } default { mstore(0, 1) }`` - Boucles for, par exemple : ``for { let i := 0} lt(i, 10) { i := add(i, 1) } { mstore(i, 7) }`` - des définitions de fonctions, par exemple : ``fonction f(a, b) -> c { c := add(a, b) }`` +======= +- literals, e.g. ``0x123``, ``42`` or ``"abc"`` (strings up to 32 characters) +- calls to builtin functions, e.g. ``add(1, mload(0))`` +- variable declarations, e.g. ``let x := 7``, ``let x := add(y, 3)`` or ``let x`` (initial value of 0 is assigned) +- identifiers (variables), e.g. ``add(3, x)`` +- assignments, e.g. ``x := add(y, 3)`` +- blocks where local variables are scoped inside, e.g. ``{ let x := 3 { let y := add(x, 1) } }`` +- if statements, e.g. ``if lt(a, b) { sstore(0, 1) }`` +- switch statements, e.g. ``switch mload(0) case 0 { revert() } default { mstore(0, 1) }`` +- for loops, e.g. ``for { let i := 0} lt(i, 10) { i := add(i, 1) } { mstore(i, 7) }`` +- function definitions, e.g. ``function f(a, b) -> c { c := add(a, b) }`` +>>>>>>> english/develop Plusieurs éléments syntaxiques peuvent se succéder en étant simplement séparés par un espace, c'est-à-dire qu'il n'est pas nécessaire de mettre un ``;`` ou un saut de ligne à la fin. +<<<<<<< HEAD Littéraux --------- +======= +.. index:: ! literal;in Yul + +Literals +-------- +>>>>>>> english/develop En tant que littéraux, vous pouvez utiliser : @@ -240,11 +271,19 @@ elles doivent être assignées à des variables locales. // Ici, la fonction définie par l'utilisateur `f` renvoie deux valeurs. let x, y := f(1, mload(0)) +<<<<<<< HEAD Pour les fonctions intégrées de l'EVM, les expressions fonctionnelles peuvent être directement traduites en un flux d'opcodes : Il suffit de lire l'expression de droite à gauche pour obtenir les opcodes. Dans le cas de la première ligne de l'exemple, il s'agit de ``PUSH1 3 PUSH1 0x80 MLOAD ADD PUSH1 0x80 MSTORE``. +======= +For built-in functions of the EVM, functional expressions +can be directly translated to a stream of opcodes: +You just read the expression from right to left to obtain the +opcodes. In the case of the second line in the example, this +is ``PUSH1 3 PUSH1 0x80 MLOAD ADD PUSH1 0x80 MSTORE``. +>>>>>>> english/develop Pour les appels aux fonctions définies par l'utilisateur, les arguments sont également placés sur la pile de droite à gauche et c'est dans cet ordre @@ -661,11 +700,16 @@ Nous utiliserons une notation de déstructuration pour les noeuds de l'AST. E(G, L, : Assignment) = let G1, L1, v1, ..., vn = E(G, L, rhs) let L2 be a copy of L1 where L2[$var_i] = vi for i = 1, ..., n - G, L2, regular + G1, L2, regular E(G, L, : ForLoop) = if n >= 1: +<<<<<<< HEAD let G1, L, mode = E(G, L, i1, ..., in) // le mode doit être régulier ou congé en raison des restrictions syntaxiques +======= + let G1, L1, mode = E(G, L, i1, ..., in) + // mode has to be regular or leave due to the syntactic restrictions +>>>>>>> english/develop if mode is leave then G1, L1 restricted to variables of L, leave otherwise @@ -684,7 +728,7 @@ Nous utiliserons une notation de déstructuration pour les noeuds de l'AST. else: G3, L3, mode = E(G2, L2, post) if mode is leave: - G2, L3, leave + G3, L3, leave otherwise E(G3, L3, for {} condition post body) E(G, L, break: BreakContinue) = @@ -741,10 +785,17 @@ Nous utiliserons une notation de déstructuration pour les noeuds de l'AST. Dialecte EVM ------------ +<<<<<<< HEAD Le dialecte par défaut de Yul est actuellement le dialecte EVM avec une version de l'EVM. Le seul type disponible dans ce dialecte est ``u256``, le type natif 256 bits de la machine virtuelle Ethereum. Comme il s'agit du type par défaut de ce dialecte, il peut être omis. +======= +The default dialect of Yul currently is the EVM dialect for the currently selected version of the EVM. +The only type available in this dialect +is ``u256``, the 256-bit native type of the Ethereum Virtual Machine. +Since it is the default type of this dialect, it can be omitted. +>>>>>>> english/develop Le tableau suivant liste toutes les fonctions intégrées (selon la version de la machine virtuelle Ethereum) et fournit une brève description de la @@ -752,17 +803,28 @@ sémantique de la fonction / opcode. Ce document ne veut pas être une description complète de la machine virtuelle Ethereum. Veuillez vous référer à un autre document si vous êtes intéressé par la sémantique précise. +<<<<<<< HEAD Les opcodes marqués avec ``-`` ne retournent pas de résultat et tous les autres retournent exactement une valeur. Les opcodes marqués par ``F``, ``H``, ``B``, ``C``, ``I`` et ``L`` sont présents depuis Frontier, Homestead, Byzance, Constantinople, Istanbul ou Londres respectivement. Dans ce qui suit, ``mem[a...b]`` signifie les octets de mémoire commençant à la position `a`` et allant jusqu'à mais sans inclure la position ``b`` et ``storage[p]`` signifie le contenu de la mémoire à l'emplacement ``p``. +======= +Opcodes marked with ``-`` do not return a result and all others return exactly one value. +Opcodes marked with ``F``, ``H``, ``B``, ``C``, ``I``, ``L``, ``P`` and ``N`` are present since Frontier, +Homestead, Byzantium, Constantinople, Istanbul, London, Paris or Cancun respectively. + +In the following, ``mem[a...b)`` signifies the bytes of memory starting at position ``a`` up to +but not including position ``b``, ``storage[p]`` signifies the storage contents at slot ``p``, and +similarly, ``transientStorage[p]`` signifies the transient storage contents at slot ``p``. +>>>>>>> english/develop Puisque Yul gère les variables locales et le flux de contrôle, les opcodes qui interfèrent avec ces fonctionnalités ne sont pas disponibles. Ceci inclut les instructions ``dup`` et ``swap`` ainsi que les instructions ``jump``, les labels et les instructions ``push``. +<<<<<<< HEAD +-------------------------+-----+---+-------------------------------------------------------------------------------------------------------------------+ | Instruction | | | Explication | +=========================+=====+===+===================================================================================================================+ @@ -935,6 +997,193 @@ les instructions ``dup`` et ``swap`` ainsi que les instructions ``jump``, les la +-------------------------+-----+---+-------------------------------------------------------------------------------------------------------------------+ | gaslimit() | | F | limite de gaz du bloc en cours | +-------------------------+-----+---+-------------------------------------------------------------------------------------------------------------------+ +======= ++-------------------------+-----+---+-----------------------------------------------------------------+ +| Instruction | | | Explanation | ++=========================+=====+===+=================================================================+ +| stop() | `-` | F | stop execution, identical to return(0, 0) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| add(x, y) | | F | x + y | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| sub(x, y) | | F | x - y | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| mul(x, y) | | F | x * y | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| div(x, y) | | F | x / y or 0 if y == 0 | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| sdiv(x, y) | | F | x / y, for signed numbers in two's complement, 0 if y == 0 | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| mod(x, y) | | F | x % y, 0 if y == 0 | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| smod(x, y) | | F | x % y, for signed numbers in two's complement, 0 if y == 0 | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| exp(x, y) | | F | x to the power of y | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| not(x) | | F | bitwise "not" of x (every bit of x is negated) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| lt(x, y) | | F | 1 if x < y, 0 otherwise | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| gt(x, y) | | F | 1 if x > y, 0 otherwise | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| slt(x, y) | | F | 1 if x < y, 0 otherwise, for signed numbers in two's complement | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| sgt(x, y) | | F | 1 if x > y, 0 otherwise, for signed numbers in two's complement | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| eq(x, y) | | F | 1 if x == y, 0 otherwise | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| iszero(x) | | F | 1 if x == 0, 0 otherwise | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| and(x, y) | | F | bitwise "and" of x and y | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| or(x, y) | | F | bitwise "or" of x and y | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| xor(x, y) | | F | bitwise "xor" of x and y | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| byte(n, x) | | F | nth byte of x, where the most significant byte is the 0th byte | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| shl(x, y) | | C | logical shift left y by x bits | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| shr(x, y) | | C | logical shift right y by x bits | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| sar(x, y) | | C | signed arithmetic shift right y by x bits | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| addmod(x, y, m) | | F | (x + y) % m with arbitrary precision arithmetic, 0 if m == 0 | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| mulmod(x, y, m) | | F | (x * y) % m with arbitrary precision arithmetic, 0 if m == 0 | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| signextend(i, x) | | F | sign extend from (i*8+7)th bit counting from least significant | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| keccak256(p, n) | | F | keccak(mem[p...(p+n))) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| pc() | | F | current position in code | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| pop(x) | `-` | F | discard value x | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| mload(p) | | F | mem[p...(p+32)) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| mstore(p, v) | `-` | F | mem[p...(p+32)) := v | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| mstore8(p, v) | `-` | F | mem[p] := v & 0xff (only modifies a single byte) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| sload(p) | | F | storage[p] | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| sstore(p, v) | `-` | F | storage[p] := v | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| tload(p) | | N | transientStorage[p] | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| tstore(p, v) | `-` | N | transientStorage[p] := v | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| msize() | | F | size of memory, i.e. largest accessed memory index | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| gas() | | F | gas still available to execution | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| address() | | F | address of the current contract / execution context | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| balance(a) | | F | wei balance at address a | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| selfbalance() | | I | equivalent to balance(address()), but cheaper | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| caller() | | F | call sender (excluding ``delegatecall``) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| callvalue() | | F | wei sent together with the current call | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| calldataload(p) | | F | call data starting from position p (32 bytes) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| calldatasize() | | F | size of call data in bytes | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| calldatacopy(t, f, s) | `-` | F | copy s bytes from calldata at position f to mem at position t | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| codesize() | | F | size of the code of the current contract / execution context | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| codecopy(t, f, s) | `-` | F | copy s bytes from code at position f to mem at position t | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| extcodesize(a) | | F | size of the code at address a | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| extcodecopy(a, t, f, s) | `-` | F | like codecopy(t, f, s) but take code at address a | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| returndatasize() | | B | size of the last returndata | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| returndatacopy(t, f, s) | `-` | B | copy s bytes from returndata at position f to mem at position t | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| mcopy(t, f, s) | `-` | N | copy s bytes from mem at position f to mem at position t | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| extcodehash(a) | | C | code hash of address a | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| create(v, p, n) | | F | create new contract with code mem[p...(p+n)) and send v wei | +| | | | and return the new address; returns 0 on error | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| create2(v, p, n, s) | | C | create new contract with code mem[p...(p+n)) at address | +| | | | keccak256(0xff . this . s . keccak256(mem[p...(p+n))) | +| | | | and send v wei and return the new address, where ``0xff`` is a | +| | | | 1 byte value, ``this`` is the current contract's address | +| | | | as a 20 byte value and ``s`` is a big-endian 256-bit value; | +| | | | returns 0 on error | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| call(g, a, v, in, | | F | call contract at address a with input mem[in...(in+insize)) | +| insize, out, outsize) | | | providing g gas and v wei and output area | +| | | | mem[out...(out+outsize)) returning 0 on error (eg. out of gas) | +| | | | and 1 on success | +| | | | :ref:`See more ` | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| callcode(g, a, v, in, | | F | identical to ``call`` but only use the code from a and stay | +| insize, out, outsize) | | | in the context of the current contract otherwise | +| | | | :ref:`See more ` | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| delegatecall(g, a, in, | | H | identical to ``callcode`` but also keep ``caller`` | +| insize, out, outsize) | | | and ``callvalue`` | +| | | | :ref:`See more ` | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| staticcall(g, a, in, | | B | identical to ``call(g, a, 0, in, insize, out, outsize)`` but do | +| insize, out, outsize) | | | not allow state modifications | +| | | | :ref:`See more ` | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| return(p, s) | `-` | F | end execution, return data mem[p...(p+s)) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| revert(p, s) | `-` | B | end execution, revert state changes, return data mem[p...(p+s)) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| selfdestruct(a) | `-` | F | end execution, destroy current contract and send funds to a | +| | | | (deprecated) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| invalid() | `-` | F | end execution with invalid instruction | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| log0(p, s) | `-` | F | log data mem[p...(p+s)) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| log1(p, s, t1) | `-` | F | log data mem[p...(p+s)) with topic t1 | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| log2(p, s, t1, t2) | `-` | F | log data mem[p...(p+s)) with topics t1, t2 | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| log3(p, s, t1, t2, t3) | `-` | F | log data mem[p...(p+s)) with topics t1, t2, t3 | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| log4(p, s, t1, t2, t3, | `-` | F | log data mem[p...(p+s)) with topics t1, t2, t3, t4 | +| t4) | | | | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| chainid() | | I | ID of the executing chain (EIP-1344) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| basefee() | | L | current block's base fee (EIP-3198 and EIP-1559) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| blobbasefee() | | N | current block's blob base fee (EIP-7516 and EIP-4844) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| origin() | | F | transaction sender | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| gasprice() | | F | gas price of the transaction | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| blockhash(b) | | F | hash of block nr b - only for last 256 blocks excluding current | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| blobhash(i) | | N | versioned hash of transaction's i-th blob | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| coinbase() | | F | current mining beneficiary | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| timestamp() | | F | timestamp of the current block in seconds since the epoch | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| number() | | F | current block number | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| difficulty() | | F | difficulty of the current block (see note below) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| prevrandao() | | P | randomness provided by the beacon chain (see note below) | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| gaslimit() | | F | block gas limit of the current block | ++-------------------------+-----+---+-----------------------------------------------------------------+ +>>>>>>> english/develop .. _yul-call-return-area: @@ -946,6 +1195,20 @@ les instructions ``dup`` et ``swap`` ainsi que les instructions ``jump``, les la Vous devez utiliser l'opcode ``returndatasize`' pour vérifier quelle partie de cette zone mémoire contient les données retournées. Les autres octets conserveront leurs valeurs d'avant l'appel. +.. note:: + The ``difficulty()`` instruction is disallowed in EVM version >= Paris. + With the Paris network upgrade the semantics of the instruction that was previously called + ``difficulty`` have been changed and the instruction was renamed to ``prevrandao``. + It can now return arbitrary values in the full 256-bit range, whereas the highest recorded + difficulty value within Ethash was ~54 bits. + This change is described in `EIP-4399 `_. + Please note that irrelevant to which EVM version is selected in the compiler, the semantics of + instructions depend on the final chain of deployment. + +.. warning:: + From version 0.8.18 and up, the use of ``selfdestruct`` in both Solidity and Yul will trigger a + deprecation warning, since the ``SELFDESTRUCT`` opcode will eventually undergo breaking changes in behavior + as stated in `EIP-6049 `_. Dans certains dialectes internes, il existe des fonctions supplémentaires : @@ -973,6 +1236,7 @@ toutes les positions en mémoire (par rapport à ``offset`') qui contiennent le linkersymbol ^^^^^^^^^^^^ +<<<<<<< HEAD La fonction ``linkersymbol("library_id")`` est un espace réservé pour un littéral d'adresse à substituer par l'éditeur de liens. Son premier et seul argument doit être une chaîne de caractères et représente de manière unique l'adresse à insérer. @@ -980,6 +1244,15 @@ Les identifiants peuvent être arbitraires mais lorsque le compilateur produit d il utilise un nom de bibliothèque qualifié avec le nom de l'unité source qui définit cette bibliothèque. Pour lier le code avec une adresse de bibliothèque particulière, le même identifiant doit être fourni à la commande ``--libraries`` sur la ligne de commande. +======= +The function ``linkersymbol("library_id")`` is a placeholder for an address literal to be substituted +by the linker. +Its first and only argument must be a string literal and uniquely represents the address to be inserted. +Identifiers can be arbitrary but when the compiler produces Yul code from Solidity sources, +it uses a library name qualified with the name of the source unit that defines that library. +To link the code with a particular library address, the same identifier must be provided to the +``--libraries`` option on the command-line. +>>>>>>> english/develop Par exemple, ce code @@ -1054,6 +1327,7 @@ avec l'argument le plus à gauche en haut, tandis que les valeurs de retour sont supposées être disposées de telle sorte que la variable la plus à droite se trouve en haut de la pile. +<<<<<<< HEAD Puisque ``verbatim`` peut être utilisé pour générer des opcodes arbitraires ou même des opcodes inconnus du compilateur Solidity, il faut être prudent lorsqu'on utilise ``verbatim`` avec l'optimiseur. Même lorsque @@ -1065,6 +1339,19 @@ La liste suivante est une liste non exhaustive des restrictions sur le bytecode verbatim qui ne sont pas vérifiées par le compilateur. La violation de ces restrictions peut entraîner un comportement non défini. +======= +Since ``verbatim`` can be used to generate arbitrary opcodes +or even opcodes unknown to the Solidity compiler, care has to be taken +when using ``verbatim`` together with the optimizer. Even when the +optimizer is switched off, the code generator has to determine +the stack layout, which means that e.g. using ``verbatim`` to modify +the stack height can lead to undefined behavior. + +The following is a non-exhaustive list of restrictions on +verbatim bytecode that are not checked by +the compiler. Violations of these restrictions can result in +undefined behavior. +>>>>>>> english/develop - Le flux de contrôle ne doit pas sauter dans ou hors des blocs verbatim, mais il peut sauter à l'intérieur d'un même bloc verbatim @@ -1123,10 +1410,22 @@ Ci-dessus, ``Block`` fait référence à ``Block`` dans la grammaire de code Yul .. note:: +<<<<<<< HEAD Les objets de données ou les sous-objets dont le nom contient un ``.`` peuvent être définis mais il n'est pas possible d'y accéder via ``datasize``, ``dataoffset`` ou ``datacopy`` parce que ``.`` est utilisé comme un séparateur pour accéder à des objets à l'intérieur d'un autre objet. +======= + An object with a name that ends in ``_deployed`` is treated as deployed code by the Yul optimizer. + The only consequence of this is a different gas cost heuristic in the optimizer. + +.. note:: + + Data objects or sub-objects whose names contain a ``.`` can be defined + but it is not possible to access them through ``datasize``, + ``dataoffset`` or ``datacopy`` because ``.`` is used as a separator + to access objects inside another object. +>>>>>>> english/develop .. note:: @@ -1154,6 +1453,7 @@ Un exemple d'objet Yul est présenté ci-dessous : code { function allocate(size) -> ptr { ptr := mload(0x40) + // Note that Solidity generated IR code reserves memory offset ``0x60`` as well, but a pure Yul object is free to use memory as it chooses. if iszero(ptr) { ptr := 0x60 } mstore(0x40, add(ptr, size)) } @@ -1165,8 +1465,9 @@ Un exemple d'objet Yul est présenté ci-dessous : datacopy(offset, dataoffset("Contract2"), size) // le paramètre du constructeur est un seul nombre 0x1234 mstore(add(offset, size), 0x1234) - pop(create(offset, add(size, 32), 0)) + pop(create(0, offset, add(size, 32))) +<<<<<<< HEAD // retourne maintenant l'objet d'exécution (le code // actuellement exécuté est le code du constructeur) size := datasize("runtime") @@ -1174,15 +1475,24 @@ Un exemple d'objet Yul est présenté ci-dessous : // Cela se transformera en une copie mémoire->mémoire pour Ewasm et // une codecopie pour EVM datacopy(offset, dataoffset("runtime"), size) +======= + // now return the runtime object (the currently + // executing code is the constructor code) + size := datasize("Contract1_deployed") + offset := allocate(size) + // This will turn into a codecopy for EVM + datacopy(offset, dataoffset("Contract1_deployed"), size) +>>>>>>> english/develop return(offset, size) } data "Table2" hex"4123" - object "runtime" { + object "Contract1_deployed" { code { function allocate(size) -> ptr { ptr := mload(0x40) + // Note that Solidity generated IR code reserves memory offset ``0x60`` as well, but a pure Yul object is free to use memory as it chooses. if iszero(ptr) { ptr := 0x60 } mstore(0x40, add(ptr, size)) } @@ -1201,7 +1511,7 @@ Un exemple d'objet Yul est présenté ci-dessous : // code ici ... } - object "runtime" { + object "Contract2_deployed" { code { // code ici ... } @@ -1230,6 +1540,7 @@ et spécifiez éventuellement le :ref:`nombre attendu d'exécutions de contrats En mode Solidity, l'optimiseur Yul est activé en même temps que l'optimiseur normal. +<<<<<<< HEAD Séquence des étapes d'optimisation ---------------------------------- @@ -1292,6 +1603,15 @@ Le ReasoningBasedSimplifier est une étape de l'optimiseur qui n'est actuellemen dans le jeu d'étapes par défaut. Elle utilise un solveur SMT pour simplifier les expressions arithmétiques et les conditions booléennes. Il n'a pas encore été testé ou validé de manière approfondie et peut produire des résultats non reproductibles, veuillez donc l'utiliser avec précaution ! +======= +.. _optimization-step-sequence: + +Optimization Step Sequence +-------------------------- + +Detailed information regarding the optimization sequence as well as a list of abbreviations is +available in the :ref:`optimizer docs `. +>>>>>>> english/develop .. _erc20yul: