diff --git a/CMakeLists.txt b/CMakeLists.txt index adb646fcda..89c1dc87fc 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.10") +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,17 @@ 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) -set(LATEST_Z3_VERSION "4.8.12") -set(MINIMUM_Z3_VERSION "4.8.0") +set(LATEST_Z3_VERSION "4.12.1") +set(MINIMUM_Z3_VERSION "4.8.16") find_package(Z3) if (${Z3_FOUND}) if (${STRICT_Z3_VERSION}) @@ -130,6 +140,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 e7daab021e..817dc7dd7e 100644 --- a/docs/050-breaking-changes.rst +++ b/docs/050-breaking-changes.rst @@ -72,11 +72,21 @@ * اکنون مشاهده عملکرد صریح اجباری است. عمومی ``public`` را به هر تابع و سازنده اضافه کنید، و به هر توابع بازگشتی یا رابطی که نمایان بودن آن را قبلاً مشخص نکرده است، خارجی ``external`` اضافه کنید. +<<<<<<< HEAD * مکان داده صریح برای همه متغیرهای ساختار، آرایه یا انواع نگاشت اکنون اجباری است. این همچنین برای پارامترهای تابع و متغیرهای بازگشتی اعمال می شود. برای مثال، ``uint[] x = m_x`` را به ``uint[]`` ذخیره سازی x = m_x، و تابع ``function f(uint[][] x)`` را به تابع ``function f(uint[][] memory x)`` تغییر دهید که در آن حافظه ``memory`` مکان داده است و ممکن است بر این اساس با ذخیره سازی یا ``calldata`` جایگزین شود. توجه داشته باشید که توابع خارجی به پارامترهایی با مکان داده ``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 * انواع قراردادها دیگر شامل اعضای آدرس ``address``نمی شوند تا فضاهای نام جدا شوند. بنابراین، اکنون لازم است که قبل از استفاده از یک عضو آدرس، مقادیر نوع قرارداد را به صراحت به آدرس تبدیل کنیم. @@ -105,10 +115,15 @@ دریافت می کنید. قبل از نسخه 0.5.0 هر تبدیل بین ``bytesX`` و ``uintY`` از طریق ``uint8X`` انجام می شد. به عنوان مثال ``uint8(bytes3(0x291807))`` به ``uint8(uint24(bytes3(0x291807)))`` تبدیل می شود (نتیجه ``0x07`` است). +<<<<<<< HEAD * استفاده از ``msg.value`` در توابع غیر قابل پرداخت (یا معرفی آن از طریق یک modifier) به عنوان یک ویژگی امنیتی مجاز نیست. تابع را به قابل پرداخت ``payable`` تبدیل کنید یا یک تابع داخلی جدید برای منطق برنامه ایجاد کنید که از ``msg.value`` استفاده می کند. +======= +* For clarity reasons, the command-line interface now requires ``-`` if the + standard input is used as source. +>>>>>>> english/develop * به دلایل وضوح، رابط خط فرمان اکنون نیاز دارد، ``-`` اگر ورودی استاندارد به عنوان منبع استفاده شود. @@ -118,6 +133,7 @@ این بخش تغییراتی را لیست می کند که ویژگی ها یا نحو قبلی را منسوخ می کند. توجه داشته باشید که بسیاری از این تغییرات قبلاً در حالت آزمایشی نسخه ``v0.5.0`` فعال شده بودند. +<<<<<<< HEAD خط فرمان(کامند لاین) و رابط های JSON ------------------------------------- @@ -128,6 +144,21 @@ * گزینه خط فرمان ``--julia`` به دلیل تغییر نام زبان میانی ``Julia`` به ``Yul`` به ``--yul`` تغییر نام داد. * گزینه های خط فرمان ``--clone-bin`` و ``--combined-json clone-bin`` حذف شدند. +======= +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 * مپینگ مجدد با پیشوند خالی مجاز نیست. @@ -434,7 +465,7 @@ 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. @@ -451,7 +482,7 @@ // '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), @@ -467,8 +498,8 @@ // 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 38e0ceb12b..74fe847639 100644 --- a/docs/060-breaking-changes.rst +++ b/docs/060-breaking-changes.rst @@ -10,8 +10,13 @@ تغییراتی که کامپایلر ممکن است در مورد آن هشدار ندهد ==================================================== +<<<<<<< HEAD این بخش تغییراتی را لیست می کند که در آن رفتار کد شما ممکن است تغییر کند بدون اینکه کامپایلر در مورد آن به شما بگوید. +======= +This section lists changes where the behavior of your code might +change without the compiler telling you about it. +>>>>>>> english/develop * نوع حاصل از یک توان، نوع پایه است. قبلاً کوچکترین نوع بود که می تواند هم نوع پایه و هم نوع توان را مانند عملیات متقارن نگه دارد. علاوه بر این، انواع علامت‌دار برای پایه قدرت مجاز هستند. @@ -49,7 +54,51 @@ مشاهده با همان نام در هیچ یک از پایه های آن وجود نداشته باشد. +<<<<<<< HEAD تغییرات معنایی و نحوی +======= +Explicitness Requirements +========================= + +This section lists changes where the code now needs to be more explicit, +but the semantics do not change. +For most of the topics the compiler will provide suggestions. + +* Functions can now only be overridden when they are either marked with the + ``virtual`` keyword or defined in an interface. Functions without + implementation outside an interface have to be marked ``virtual``. + When overriding a function or modifier, the new keyword ``override`` + must be used. When overriding a function or modifier defined in multiple + parallel bases, all bases must be listed in parentheses after the keyword + like so: ``override(Base1, Base2)``. + +* Member-access to ``length`` of arrays is now always read-only, even for storage arrays. It is no + longer possible to resize storage arrays by assigning a new value to their length. Use ``push()``, + ``push(value)`` or ``pop()`` instead, or assign a full array, which will of course overwrite the existing content. + The reason behind this is to prevent storage collisions of gigantic + storage arrays. + +* The new keyword ``abstract`` can be used to mark contracts as abstract. It has to be used + if a contract does not implement all its functions. Abstract contracts cannot be created using the ``new`` operator, + and it is not possible to generate bytecode for them during compilation. + +* Libraries have to implement all their functions, not only the internal ones. + +* The names of variables declared in inline assembly may no longer end in ``_slot`` or ``_offset``. + +* Variable declarations in inline assembly may no longer shadow any declaration outside the inline assembly block. + If the name contains a dot, its prefix up to the dot may not conflict with any declaration outside the inline + assembly block. + +* 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. + + +Semantic and Syntactic Changes +>>>>>>> english/develop ============================== این بخش تغییراتی را لیست می کند که در آن باید کد خود را تغییر دهید و پس از آن کار دیگری انجام می دهد. @@ -87,22 +136,42 @@ تغییرات رابط یا همان اینترفیس ================= +<<<<<<< HEAD این بخش تغییراتی را لیست می‌کند که به خود زبان ارتباطی ندارند، اما روی رابط‌های کامپایلر تأثیر دارند. اینها ممکن است نحوه استفاده از کامپایلر را در خط فرمان یا همان کامند لاین، نحوه استفاده از رابط قابل برنامه ریزی آن، یا نحوه تجزیه و تحلیل خروجی تولید شده توسط آن را تغییر دهند. +======= +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 گزارشگر خطای جدید ~~~~~~~~~~~~~~~~~~ +<<<<<<< HEAD گزارشگر خطای جدیدی معرفی شد که هدف آن تولید پیام های خطا در دسترس تر در خط فرمان است. به طور پیش فرض فعال است، اما ارسال ``--old-reporter`` به گزارشگر خطای قدیمی منسوخ برمی گردد. +======= +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 گزینه های هش متادیتا ~~~~~~~~~~~~~~~~~~~~~ +<<<<<<< HEAD کامپایلر اکنون هش `IPFS `_ فایل فراداده را به‌طور پیش‌فرض به انتهای بایت کد اضافه می‌کند (برای جزئیات، مستندات مربوط به :doc:`contract metadata ` را ببینید). قبل از ورژن 0.6.0، کامپایلر هش سوارم `Swarm `_ را به طور پیش‌فرض اضافه می‌کرد و برای اینکه همچنان از این رفتار پشتیبانی کند، گزینه جدید خط فرمان ``--metadata-hash`` معرفی شد که به شما اجازه می دهد تا با ارسال ``ipfs`` یا ``swarm`` به عنوان مقدار به گزینه خط فرمان ``--metadata-hash`` هش مورد نظر برای تولید و الحاق را انتخاب کنید. ارسال مقدار ``none`` به طور کامل هش را حذف می کند. +======= +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 این تغییرات همچنین می تواند از طریق رابط :ref:`Standard JSON Interface` مورد استفاده قرار گیرد و فراداده JSON تولید شده توسط کامپایلر را تحت تأثیر قرار @@ -151,4 +220,15 @@ this change consistent, ``solidity_free`` was renamed to ``solidity_reset``, the * شناسه‌های منحصربه‌فرد را برای اعلان‌های متغیر در مجموعه درون خطی انتخاب کنید که با اعلان‌های خارج از بلوک اسمبلی درون خطی تضاد ندارند. +<<<<<<< HEAD * مجازی ``virtual`` را به هر تابع غیر رابطی که قصد لغو آن را دارید اضافه کنید. ``virtual`` را به همه توابع بدون اجرای رابط های خارجی اضافه کنید. برای وراثت تکی، به هر تابع نادیده ``override`` اضافه کنید. برای وراثت چندگانه، ``override(A, B, ..)`` را اضافه کنید، جایی که تمام قراردادهایی را که تابع لغو را در پرانتز تعریف می کنند، لیست می کنید. هنگامی که چندین پایه یک تابع را تعریف می کنند، قرارداد ارثی باید همه عملکردهای متضاد را لغو کند. +======= +* 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 b322d2a489..524d12ac3b 100644 --- a/docs/080-breaking-changes.rst +++ b/docs/080-breaking-changes.rst @@ -10,18 +10,18 @@ For the full list check Silent Changes of the Semantics =============================== -This section lists changes where existing code changes its behaviour without +This section lists changes where existing code changes its behavior without the compiler notifying you about it. * Arithmetic operations revert on underflow and overflow. You can use ``unchecked { ... }`` to use - the previous wrapping behaviour. + the previous wrapping behavior. Checks for overflow are very common, so we made them the default to increase readability of code, even if it comes at a slight increase of gas costs. * ABI coder v2 is activated by default. - You can choose to use the old behaviour using ``pragma abicoder v1;``. + 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. @@ -57,7 +57,7 @@ New Restrictions This section lists changes that might cause existing contracts to not compile anymore. -* There are new restrictions related to explicit conversions of literals. The previous behaviour in +* There are new restrictions related to explicit conversions of literals. The previous behavior in the following cases was likely ambiguous: 1. Explicit conversions from negative literals and literals larger than ``type(uint160).max`` to @@ -106,7 +106,7 @@ This section lists changes that might cause existing contracts to not compile an * The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed. - These are low-level functions that were largely unused. Their behaviour can be accessed from inline assembly. + These are low-level functions that were largely unused. Their behavior can be accessed from inline assembly. * ``enum`` definitions cannot contain more than 256 members. @@ -173,4 +173,4 @@ How to update your code - 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) +- 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) 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 e11b9ac7b6..024ffa8ff6 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -1,3 +1,4 @@ +<<<<<<< HEAD h1,h2,h3,h4,h5,h6{ direction: rtl; unicode-bidi: normal; @@ -30,20 +31,190 @@ pre { white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ word-wrap: break-word; +======= +/* 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; +>>>>>>> english/develop +} + +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; } -.wy-table-responsive table td, .wy-table-responsive table th { +span.pre, +pre { + /* 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; +} + +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; } @@ -53,60 +224,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); +} + +.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 { - 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::before { + content: ""; + position: absolute; + inset: 0; + opacity: 95%; + background: var(--color-f); + z-index: -1; + backdrop-filter: blur(3px); } -a.remix-link .link-icon { - background: url("../img/solid-share-arrow.svg") no-repeat; +.unified-header .home-link { display: block; - width: 1.5em; - height: 1.5em; - margin: auto; + text-decoration: none; + width: 25px; + height: 40px; +} + +.unified-header .home-link:hover .solidity-logo { + transform: scale(1.1); + transition: transform 100ms ease-in-out; +} + +.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); } -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; +.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); } -a.remix-link:hover { +.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/_templates/versions.html b/docs/_templates/versions.html index f680b6506d..a2432e3703 100644 --- a/docs/_templates/versions.html +++ b/docs/_templates/versions.html @@ -13,13 +13,13 @@
-
{{ _('Versions') }}
{% for slug, url in versions %} -
{{ slug }}
+
{{ _('Downloads') }}
{% for type, url in downloads %} +
{{ type }}
{% endfor %}
-
{{ _('Downloads') }}
{% for type, url in downloads %} -
{{ type }}
+
{{ _('Versions') }}
{% for slug, url in versions %} +
{{ slug }}
{% endfor %}
@@ -33,4 +33,4 @@
- \ No newline at end of file + diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 6f50c70d9e..0d48b51dd7 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -13,13 +13,13 @@ The Contract Application Binary Interface (ABI) is the standard way to interact from outside the blockchain and for contract-to-contract interaction. Data is encoded according to its type, as described in this specification. The encoding is not self describing and thus requires a schema in order to decode. -We assume the interface functions of a contract are strongly typed, known at compilation time and static. +We assume that the interface functions of a contract are strongly typed, known at compilation time and static. We assume that all contracts will have the interface definitions of any contracts they call available at compile-time. This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. .. _abi_function_selector: -.. index:: selector +.. index:: ! selector; of a function Function Selector ================= @@ -29,7 +29,7 @@ first (left, high-order in big-endian) four bytes of the Keccak-256 hash of the 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. +comma — no spaces are used. .. note:: The return type of a function is not part of this signature. In @@ -133,7 +133,7 @@ The encoding is designed to have the following properties, which are especially previous version of the ABI, the number of reads scaled linearly with the total number of dynamic parameters in the worst case. -2. The data of a variable or array element is not interleaved with other data and it is +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". @@ -191,9 +191,9 @@ on the type of ``X`` being - ``T[]`` where ``X`` has ``k`` elements (``k`` is assumed to be of type ``uint256``): - ``enc(X) = enc(k) enc([X[0], ..., X[k-1]])`` + ``enc(X) = enc(k) enc((X[0], ..., X[k-1]))`` - i.e. it is encoded as if it were an array of static size ``k``, prefixed with + 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. - ``bytes``, of length ``k`` (which is assumed to be of type ``uint256``): @@ -252,7 +252,21 @@ Given the contract: } -Thus for our ``Foo`` example if we wanted to call ``baz`` with the parameters ``69`` and +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: - ``0xcdcd77c0``: the Method ID. This is derived as the first 4 bytes of the Keccak hash of @@ -271,20 +285,6 @@ In total: It returns a single ``bool``. If, for example, it were to return ``false``, its output would be the single byte array ``0x0000000000000000000000000000000000000000000000000000000000000000``, a single bool. -If we wanted to call ``bar`` with the argument ``["abc", "def"]``, we would pass 68 bytes total, broken down into: - -- ``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 ``sam`` with the arguments ``"dave"``, ``true`` and ``[1,2,3]``, we would pass 292 bytes total, broken down into: @@ -308,10 +308,10 @@ In total: Use of Dynamic Types ==================== -A call to a function with the signature ``f(uint,uint32[],bytes10,bytes)`` with values +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 ``sha3("f(uint256,uint32[],bytes10,bytes)")``, i.e. ``0x8be65246``. +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 @@ -348,7 +348,7 @@ All together, the encoding is (newline after function selector and each 32-bytes 000000000000000000000000000000000000000000000000000000000000000d 48656c6c6f2c20776f726c642100000000000000000000000000000000000000 -Let us apply the same principle to encode the data for a function with a signature ``g(uint[][],string[])`` +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: First we encode the length and data of the first embedded dynamic array ``[1, 2]`` of the first root array ``[[1, 2], [3]]``: @@ -417,7 +417,7 @@ thus ``e = 0x00000000000000000000000000000000000000000000000000000000000000e0``. Note that the encodings of the embedded elements of the root arrays are not dependent on each other -and have the same encodings for a function with a signature ``g(string[],uint[][])``. +and have the same encodings for a function with a signature ``g(string[],uint256[][])``. Then we encode the length of the first root array: @@ -503,6 +503,7 @@ efficient search and arbitrary legibility by defining events with two arguments indexed, one not — intended to hold the same value. .. _abi_errors: +.. index:: error, selector; of an error Errors ====== @@ -562,7 +563,7 @@ A function description is a JSON object with the fields: blockchain state `), ``view`` (:ref:`specified to not modify the blockchain state `), ``nonpayable`` (function does not accept Ether - the default) and ``payable`` (function accepts Ether). -Constructor and fallback function never have ``name`` or ``outputs``. Fallback function doesn't have ``inputs`` either. +Constructor, receive, and fallback never have ``name`` or ``outputs``. Receive and fallback do not have ``inputs`` either. .. note:: Sending non-zero Ether to non-payable function will revert the transaction. @@ -580,7 +581,7 @@ An event description is a JSON object with fairly similar fields: * ``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 one of the log's data segment. + * ``indexed``: ``true`` if the field is part of the log's topics, ``false`` if it is one of the log's data segments. - ``anonymous``: ``true`` if the event was declared as ``anonymous``. @@ -596,7 +597,7 @@ Errors look as follows: .. note:: 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 + 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. @@ -645,7 +646,7 @@ would result in the JSON: Handling tuple types -------------------- -Despite that names are intentionally not part of the ABI encoding they do make a lot of sense to be included +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. @@ -653,7 +654,7 @@ The canonical type is determined until a tuple type is reached and the string de 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 array type and has the same structure as the top-level object except that +which is of an array type and has the same structure as the top-level object except that ``indexed`` is not allowed there. As an example, the code @@ -737,10 +738,10 @@ Strict Encoding Mode ==================== Strict encoding mode is the mode that leads to exactly the same encoding as defined in the formal specification above. -This means offsets have to be as small as possible while still not creating overlaps in the data areas and thus no gaps are +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 just following offset pointers, but some decoders +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. @@ -749,7 +750,7 @@ Non-standard Packed Mode Through ``abi.encodePacked()``, Solidity supports a non-standard packed mode where: -- types shorter than 32 bytes are neither zero padded nor sign extended and +- types shorter than 32 bytes are concatenated directly, without padding or sign extension - dynamic types are encoded in-place and without the length. - array elements are padded, but still encoded in-place @@ -776,7 +777,7 @@ More specifically: 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 +- 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). @@ -804,7 +805,7 @@ Encoding of Indexed Event Parameters ==================================== Indexed event parameters that are not value types, i.e. arrays and structs are not -stored directly but instead a keccak256-hash of an encoding is stored. This encoding +stored directly but instead a Keccak-256 hash of an encoding is stored. This encoding is defined as follows: - the encoding of a ``bytes`` and ``string`` value is just the string contents diff --git a/docs/analysing-compilation-output.rst b/docs/analysing-compilation-output.rst index 892b18b957..183f773223 100644 --- a/docs/analysing-compilation-output.rst +++ b/docs/analysing-compilation-output.rst @@ -11,7 +11,7 @@ visual diff of the assembly before and after a change is often very enlightening Consider the following contract (named, say ``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 5f2fb09560..631193c1c3 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -7,6 +7,7 @@ .. index:: ! assembly, ! asm, ! evmasm +<<<<<<< HEAD می‌توانید دستورات سالیدیتی را با اسمبلی درون خطی به زبانی نزدیک به ماشین مجازی اتریوم جا دهید. این به شما کنترل دقیق‌تری می‌دهد، که به ویژه هنگامی که با نوشتن کتابخانه‌ها زبان را تقویت می‌کنید مفید است. @@ -14,6 +15,11 @@ زبانی که برای مونتاژ خطی در سالیدیتی استفاده می‌شود :ref:`Yul ` نام دارد و در بخش مخصوص خود مستند شده است. این بخش فقط نحوه ارتباط کد مونتاژ درون خطی با کد سالیدیتی را پوشش می‌دهد. +======= +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 @@ -50,19 +56,19 @@ 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) } } } @@ -79,49 +85,49 @@ 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 دسترسی به متغیرها، توابع و کتابخانه‌های خارجی ----------------------------------------------------- @@ -129,12 +135,29 @@ با استفاده از نام متغیرهای سالیدیتی و سایر identifier ها می‌توانید به آنها دسترسی پیدا کنید. +<<<<<<< HEAD متغیرهای محلی از نوع ارزش به طور مستقیم در اسمبلی درون خطی قابل استفاده هستند. متغیرهای محلی که به مِمُوری اشاره می‌کنند به آدرس متغیر موجود در مِمُوری ارزیابی می‌شوند نه خود مقدار. چنین متغیرهایی را می‌توان به آن‌ها نیز اختصاص داد، اما توجه داشته باشید که یک انتساب فقط نشانگر را تغییر می‌دهد و نه داده‌ها را و این مسئولیت شماست که به مدیریت مِمُوری سالیدیتی توجه کنید. قسمت :ref:`Conventions in Solidity ` را مشاهده کنید. +======= +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 به طور مشابه، متغیرهای محلی که به آرایه‌های calldata با اندازه استاتیک یا ساختارهای calldata اشاره می‌کنند، به آدرس متغیر در calldata، نه خود مقدار، ارزیابی می‌شوند. همچنین می‌توان یک آفست جدید به متغیر اختصاص داد، اما توجه داشته @@ -181,8 +204,14 @@ mappingها)، قسمت ``offset.`` همیشه صفر است. با این حال کردن signed typeها استفاده کنید، می‌توانید از آپکد ``signextend`` استفاده کنید: ``assembly { signextend(, x) }`` +<<<<<<< HEAD از نسخه 0.6.0 سالیدیتی نام یک متغیر اسمبلی درون خطی ممکن است هیچ اعلان قابل مشاهده در محدوده بلوک اسمبلی درون خطی (شامل اعلان‌های متغیر، قرارداد و تابع) را تحت الشعاع قرار ندهد. +======= +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 از نسخه 0.7.0 سالیدیتی، متغیرها و توابع اعلام شده در داخل بلوک اسمبلی درون خطی ممکن است حاوی ``.`` نباشند، اما @@ -204,6 +233,7 @@ mappingها)، قسمت ``offset.`` همیشه صفر است. با این حال کنوانسیون‌ها در سالیدیتی (Conventions in Solidity) ----------------------- +<<<<<<< HEAD بر خلاف اسمبلیEVM ، سالیدیتی دارای انواع کوتاه‌تر از 256 بیت است، به عنوان مثال ``uint24`` .برای کارآیی، اکثر عملیات حسابی این واقعیت را نادیده می‌گیرند که نوع آنها می‌تواند کوتاه‌تر از 256 بیت باشد و بیت‌های مرتبه بالاتر در صورت لزوم پاک می‌شوند، یعنی کمی قبل از اینکه در مِمُوری نوشته شوند یا قبل از @@ -219,6 +249,34 @@ mappingها)، قسمت ``offset.`` همیشه صفر است. با این حال ندارد. در اینجا یک قطعه اسمبلی وجود دارد که می‌توانید برای تخصیص مِمُوری از فرایند ذکر شده در بالا استفاده کنید: +======= +.. _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 @@ -238,8 +296,112 @@ mappingها)، قسمت ``offset.`` همیشه صفر است. با این حال .. warning:: +<<<<<<< HEAD آرایه‌های مِمُوری با اندازه استاتیک دارای length field نیستند، اما ممکن است بعداً اضافه شوند تا قابلیت تبدیل بهتری بین آرایه‌های اندازه استاتیک و پویا ایجاد شود، بنابراین به این موضوع اتکا نکنید. - \ No newline at end of file + +======= + 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 fc03f35d93..cf471c5e3c 100644 --- a/docs/brand-guide.rst +++ b/docs/brand-guide.rst @@ -59,7 +59,7 @@ Under the following terms: - **Attribution** — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any - reasonable manner, but not in any way that suggests the the Solidity + reasonable manner, but not in any way that suggests that the Solidity core team endorses you or your use. When using the Solidity logo, please respect the Solidity logo guidelines. @@ -67,7 +67,7 @@ When using the Solidity logo, please respect the Solidity logo guidelines. Solidity Logo Guidelines ======================== -.. image:: logo.svg +.. image:: solidity_logo.svg :width: 256 *(Right click on the logo to download it.)* 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 a751a138be..a7c50a79da 100644 --- a/docs/bugs.rst +++ b/docs/bugs.rst @@ -34,6 +34,7 @@ uid Unique identifier given to the bug in the form of ``SOL--``. It is possible that multiple entries exists with the same uid. This means multiple version ranges are affected by the same bug. +<<<<<<< HEAD نام نام اختصاری داده شده به اشکال(bug) خلاصه @@ -71,6 +72,50 @@ uid فشرده برنامه سالیدتی اعمال کرد.(“ast-compact-json-path”). عبارت مشخص شده جستجو عبارتی از نوع `JsonPath `_ است. اگر حداقل یک مسیر از AST سالیدتی با عبارت جستجو شده تطابق کند، اشکال به احتمال زیاد وجود دارد. +======= +name + Unique name given to the bug +summary + Short description of the bug +description + Detailed description of the bug +link + URL of a website with more detailed information, optional +introduced + The first published compiler version that contained the bug, optional +fixed + The first published compiler version that did not contain the bug anymore +publish + The date at which the bug became known publicly, optional +severity + Severity of the bug: very low, low, medium, high. Takes into account + discoverability in contract tests, likelihood of occurrence and + potential damage by exploits. +conditions + Conditions that have to be met to trigger the bug. The following + keys can be used: + ``optimizer``, Boolean value which + means that the optimizer has to be switched on to enable the bug. + ``evmVersion``, a string that indicates which EVM version compiler + settings trigger the bug. The string can contain comparison + operators. For example, ``">=constantinople"`` means that the bug + is present when the EVM version is set to ``constantinople`` or + later. + If no conditions are given, assume that the bug is present. +check + 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 4324b8339e..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,22 +1729,175 @@ }, "0.8.1": { "bugs": [ + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation", "SignedImmutables", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching" ], "released": "2021-01-27" }, + "0.8.10": { + "bugs": [ + "VerbatimInvalidDeduplication", + "FullInlinerNonExpressionSplitArgumentEvaluationOrder", + "MissingSideEffectsOnSelectorAccess", + "AbiReencodingHeadOverflowWithStaticArrayCleanup", + "DirtyBytesArrayToStorage", + "DataLocationChangeInInternalOverride", + "NestedCalldataArrayAbiReencodingSizeValidation" + ], + "released": "2021-11-09" + }, + "0.8.11": { + "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" ], @@ -1561,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 6b2f367c51..ad3c3b9071 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -2,71 +2,20 @@ برگه تقلب (Cheatsheet) ********** -.. index:: precedence - -.. _order: +.. index:: operator;precedence ترتیب اولویت اپراتورها (Order of Precedence of Operators) ================================ +<<<<<<< HEAD در زیر ترتیب اولویت عملگرها آمده است که به ترتیب ارزیابی لیست شده‌اند. +======= +.. include:: types/operator-precedence-table.rst +>>>>>>> english/develop -+------------+-------------------------------------+--------------------------------------------+ -| 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 | ``,`` | -+------------+-------------------------------------+--------------------------------------------+ +.. index:: abi;decode, abi;encode, abi;encodePacked, abi;encodeWithSelector, abi;encodeCall, abi;encodeWithSignature +<<<<<<< HEAD .. index:: assert, block, coinbase, difficulty, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, gas price, origin, revert, require, keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, codehash, send متغیرهای جهانی @@ -158,6 +107,129 @@ .. note:: در نسخه 0.7.0 ، نام مستعار ``now`` (برای ``block.timestamp``) حذف شده‌است. +======= +ABI Encoding and Decoding Functions +=================================== + +- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: :ref:`ABI `-decodes + the provided data. The types are given in parentheses as second argument. + Example: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))`` +- ``abi.encode(...) returns (bytes memory)``: :ref:`ABI `-encodes the given arguments +- ``abi.encodePacked(...) returns (bytes memory)``: Performs :ref:`packed encoding ` of + the given arguments. Note that this encoding can be ambiguous! +- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: :ref:`ABI `-encodes + the given arguments starting from the second and prepends the given four-byte selector +- ``abi.encodeCall(function functionPointer, (...)) returns (bytes memory)``: ABI-encodes a call to ``functionPointer`` with the arguments found in the + tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, (...))`` +- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent + 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, external, internal @@ -184,6 +256,7 @@ اصلاح کننده ها ========= +<<<<<<< HEAD - ``pure`` برای توابع: اجازه تغییر یا دسترسی به حالت را نمی دهد. - ``view`` برای توابع: تغییر حالت را ممنوع می کند. - ``payable`` برای توابع: به آنها اجازه می دهد تا اتر را به همراه یک call دریافت کنند. @@ -207,3 +280,17 @@ ``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 9a328a0f49..69c0b2d60b 100644 --- a/docs/common-patterns.rst +++ b/docs/common-patterns.rst @@ -15,9 +15,16 @@ توصیه نمی شود زیرا خطر بالقوه امنیتی ایجاد می کند. ممکن است در مورد این موضوع در صفحه ی ملاحظات امنیتی :ref:`security_considerations` بیشتر مطالعه کنید. +<<<<<<< HEAD در زیر نمونه کاربردی از الگوی برداشت در یک قرارداد است که هدف آن ارسال بیشترین مبلغ به قرارداد جهت تبدیل شدن به "ثروتمندترین" است. که از `King of the Ether `_ الهام گرفته شده است. +======= +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 +`King of the Ether `_. +>>>>>>> english/develop در قرارداد ذیل ، اگر شما دیگر ثروتمند ترین نباشید، شما بودجه شخصی را دریافت می کنید که @@ -32,7 +39,7 @@ address public richest; uint public mostSent; - mapping (address => uint) pendingWithdrawals; + mapping(address => uint) pendingWithdrawals; /// The amount of Ether sent was not higher than /// the currently highest amount. @@ -53,7 +60,7 @@ function withdraw() public { uint amount = pendingWithdrawals[msg.sender]; // Remember to zero the pending refund before - // sending to prevent re-entrancy attacks + // sending to prevent reentrancy attacks pendingWithdrawals[msg.sender] = 0; payable(msg.sender).transfer(amount); } @@ -155,9 +162,9 @@ // prepend a check that only passes // if the function is called from // a certain address. - modifier onlyBy(address _account) + modifier onlyBy(address account) { - if (msg.sender != _account) + if (msg.sender != account) revert Unauthorized(); // Do not forget the "_;"! It will // be replaced by the actual function @@ -165,17 +172,17 @@ _; } - /// Make `_newOwner` the new owner of this + /// Make `newOwner` the new owner of this /// contract. - function changeOwner(address _newOwner) + function changeOwner(address newOwner) 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(); _; } @@ -197,21 +204,21 @@ // 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) + modifier costs(uint amount) { + if (msg.value < amount) 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) { - owner = _newOwner; + owner = newOwner; // just some example condition if (uint160(owner) & 0 == 1) // This did not refund for Solidity @@ -291,8 +298,8 @@ 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 2e6cdaee3b..6fc280cde0 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' -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 @@ -74,7 +78,7 @@ def setup(sphinx): # version = re.search('PROJECT_VERSION "([^"]+)"', f.read()).group(1) version="0.8.4" # The full version, including alpha/beta/rc tags. -if os.path.isfile('../prerelease.txt') != True or os.path.getsize('../prerelease.txt') == 0: +if not os.path.isfile('../prerelease.txt') or os.path.getsize('../prerelease.txt') == 0: release = version else: # This is a prerelease version @@ -92,7 +96,7 @@ def setup(sphinx): # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build', 'contracts', 'types', 'examples', 'grammar', 'ir'] +exclude_patterns = ['_build', 'contracts', 'types', 'examples', 'grammar'] # The reST default role (used for this markup: `text`) to use for all # documents. @@ -132,7 +136,6 @@ def setup(sphinx): # documentation. html_theme_options = { 'logo_only': True, - 'style_nav_header_background': '#65afff', 'display_version': True, } @@ -148,12 +151,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, @@ -162,7 +165,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 @@ -210,7 +213,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 75a3e4ce27..6261b9f8ba 100644 --- a/docs/contracts/abstract-contracts.rst +++ b/docs/contracts/abstract-contracts.rst @@ -6,6 +6,7 @@ قراردادهای انتزاعی (Abstract Contracts) ****************** +<<<<<<< HEAD زمانی که حداقل یکی از توابع قرارداد‌ها اجرا نشود، باید قراردادها به صورت انتزاعی علامت گذاری شوند. ممکن است قراردادها بصورت انتزاعی علامت گذاری شوند حتی اگر همه توابع اجرا شوند. @@ -14,6 +15,17 @@ توجه داشته باشید که این قرارداد باید بصورت انتزاعی تعریف شود، زیرا تابع ``()utterance`` تعریف شده است، اما پیاده سازی ارائه نشده است (هیچ پیاده سازی ``{ }`` body داده نشده است): +======= +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 b4c56f1026..635c7eab5e 100644 --- a/docs/contracts/constant-state-variables.rst +++ b/docs/contracts/constant-state-variables.rst @@ -31,25 +31,29 @@ .. 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; - constructor(uint _decimals, address _reference) { - decimals = _decimals; + 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 = _reference.balance; + maxBalance = ref.balance; } - 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 +76,7 @@ تغییر ناپذیر ============= +<<<<<<< HEAD متغیر های تعریف شده به عنوان تغییرناپذیر ``immutable`` محدودیت کمتری نسبت به متغیر های ثابت ``constant`` دارند : به متغیر های تغییر ناپذیر می توان یک مقدار دلخواه در سازنده قرارداد یا در زمان تعریف آنها اختصاص داد. انها نمی توانند در زمان ساخت خوانده شوند و فقط یک بار مقدار دهی می شوند. @@ -90,4 +95,38 @@ This is a safeguard against different interpretations about the order of state variable initialization and constructor execution, especially - with regards to inheritance. \ No newline at end of file + with regards to inheritance. +======= +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 5d377ad510..fc28f94e5c 100644 --- a/docs/contracts/creating-contracts.rst +++ b/docs/contracts/creating-contracts.rst @@ -8,6 +8,12 @@ IDE هایی، مانند `Remix `_ ، فرآیند ایجاد را با استفاده از المان‌های UI انجام می‌دهند. +<<<<<<< HEAD +======= +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 یکی از راه‌های ایجاد قراردادها به صورت برنامه‌ای در اتریوم، استفاده از API جاوا اسکریپت `web3.js `_ است. یک تابع به نام `web3.eth.Contract `_ برای تسهیل ایجاد قرارداد را دارد. @@ -51,7 +57,7 @@ IDE هایی، مانند `Remix `_ ، فرآیند // This is the constructor which registers the // creator and the assigned name. - constructor(bytes32 _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`, @@ -68,7 +74,7 @@ IDE هایی، مانند `Remix `_ ، فرآیند // no real way to verify that. // This does not create a new contract. 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 ddce0a6b09..ebde855965 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: ******************************* @@ -71,7 +70,21 @@ This makes this a very cheap and convenient error-reporting feature at the same ``Panic(uint256)`` خواهد بود. .. note:: +<<<<<<< HEAD داده های خطا فقط باید برای نشان دادن خطا مورد استفاده قرار گیرند، نه برای کنترل جریان. دلیل آن این است که داده های بازگشتی از فراخوانی داخلی به صورت پیش فرض از طریق زنجیره فراخوانی های خارجی پخش می شوند. این بدان معناست که یک فراخوانی داخلی می تواند "جعل" کند، داده هایی را که به نظر می رسد از آن قرارداد فراخانی شده است. +======= + 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 3db9b7c577..e519533661 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,12 +9,23 @@ رویداد های سالیدیتی یک خلاصه ای از عملکرد گزارش گیری EVM ارائه می دهند. برنامه ها می توانند ار طریق رابط RPC به این رویداد ها ثبت نام کنند و به رویداد ها گوش دهند. +<<<<<<< HEAD رویدادها اعضای وراثتی قرارداد ها هستند. وقتی آنها را فراخوانی می کنید، آنها باعث می شوند که ورودی هایی که در تراکنش ها ذخیره شده اند گزارش شوند – یک ساختار داده ویژه در بلاکچین. این گزارش ها با آدرس قرارد داد ها مرتبط هستند، تا زمانی که یک بلوک قابل دسترس است ، در بلاکچین گنجانده شده اند(از حالا تا بی نهایت، ممکن است با آرامش نیز تغییر کند)،. گزارش و رویدادهای آن از داخل قرارداد ها (حتی از قراردادهایی که آنها را ایجاد کرده اند) قابل دسترس نیست . +======= +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 یک در خواست Merkle proof برای گزارش ها امکانپذیر است انجام شود، بنابراین اگر یک موجودیت خارجی قراردادی به همراه چنین اثباتی ارائه دهد، می تواند بررسی کند که گزارش @@ -69,6 +80,18 @@ In particular, it is possible to "fake" the signature of another event using an anonymous event. +.. 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 @@ -76,18 +99,18 @@ contract ClientReceipt { event Deposit( - address indexed _from, - bytes32 indexed _id, - uint _value + address indexed from, + bytes32 indexed id, + uint value ); - function deposit(bytes32 _id) public payable { + 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); + emit Deposit(msg.sender, id, msg.value); } } @@ -122,9 +145,9 @@ { "returnValues": { - "_from": "0x1111…FFFFCCCC", - "_id": "0x50…sd5adb20", - "_value": "0x420042" + "from": "0x1111…FFFFCCCC", + "id": "0x50…sd5adb20", + "value": "0x420042" }, "raw": { "data": "0x7f…91385", @@ -132,9 +155,18 @@ } } +<<<<<<< HEAD منابع اضافی برای درک رویداد ها ============================================== - `اسناد جاوا اسکریپت `_ - `نمونه های استفاده از رویدادها `_ - `چگونگی دسترسی به آنها در جاوا اسکریپت `_ +======= +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 3a0cf15fc3..e21eefabac 100644 --- a/docs/contracts/function-modifiers.rst +++ b/docs/contracts/function-modifiers.rst @@ -6,9 +6,15 @@ اصلاح کننده های تابع ******************** +<<<<<<< HEAD اصلاح کننده ها جهت تغییر رفتار توابع به روش تعریف وار استفاده می شوند. برای مثال، شما می توانید از یک اصلاح کننده جهت اعمال پیش شرط به صورت اتوماتیک برای اجرای آن تابع استفاده کنید. +======= +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 اصلاح کننده ها ویژگی های وراثتی قرارداد ها هستند و ممکن است توسط قرارداد هایی که نشات گرفته شده اند باز نویسی شوند. اما فقط زمانی که بصورت ``virtual`` نشانه گذاری شده @@ -18,6 +24,7 @@ // 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 @@ } contract Register is priced, destructible { - mapping (address => bool) registeredAddresses; + mapping(address => bool) registeredAddresses; uint price; constructor(uint initialPrice) { price = initialPrice; } @@ -71,8 +78,8 @@ registeredAddresses[msg.sender] = true; } - function changePrice(uint _price) public onlyOwner { - price = _price; + function changePrice(uint price_) public onlyOwner { + price = price_; } } @@ -112,9 +119,21 @@ داده و یا مقادیر بازگشتی را برگردانند. مقادیر آنها فقط به صراحت هنگام فراخوانی به آنها منتقل می شود. +<<<<<<< HEAD بازگشت واضح(Explicit) از یک اصلاح کننده یا بدنه تابع فقط از اصلاح کننده جاری و یا بنده تابع خارج می شود. متغیر های اختصاص داده شده باز می گردند و کنترل جریان ``_`` از اصلاح کننده قبلی ادامه می یابد. +======= +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:: در نسخه قدیمی سالیدیتی، دستورات ``return`` در توابع اصلاح کننده ها با رفتار متفاوت @@ -125,7 +144,12 @@ متغیر های باز گشتی بر روی :ref:`مقادیر پیش فرض` خود تنظیم می شوند درست مانند اینکه تابع دارای یک بدن خالی باشد. +<<<<<<< HEAD نماد ``_`` می تواند چندین بار در اصلاح کننده ظاهر شود. هر رخداد با بدنه تابع جایگزین می شود. +======= +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 عبارت های دلخواه برای ورودی (آرگومان) های اصلاح کننده مجاز هستند و در این مورد ، همه نماد های قابل مشاهده در تابع در اصلاح کننده نیز قابل مشاهده هستند. diff --git a/docs/contracts/functions.rst b/docs/contracts/functions.rst index a01ce5c5ae..8574d0721f 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,38 @@ // 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; - function f(uint[] memory _arr) public { + 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); + uint s = sum(arr); require(s >= 10); found = true; } } .. note:: +<<<<<<< HEAD توابعی که خارج از یک قرارداد تعریف شده اند همیشه در متن قرارداد اجرا می شوند. همچنان آنها به متغیر ``this`` دسترسی دارند، می توانند قراداد های دیگر را فراخوانی کنند، می توانند به قرارداد ها اتر ارسال و قرادادهایی که آنها را فراخوانی می کنند را نابود کنند، در میان چیز های دیگر. تفاوت اصلی بین توابع تعریف شده در داخل یک قرارداد با توابع آزاد این است که توابع آزاد دسترسی مستقیم به متغیر های ذخیره سازی و توابع دیگر ندارند و در میدان دید آنها نیست. +======= + 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,13 +74,14 @@ contract Simple { uint sum; - function taker(uint _a, uint _b) public { - sum = _a + _b; + function taker(uint a, uint b) public { + sum = a + b; } } پارامتر های تابع می توانند به عنوان متغیر های محلی استفاده شده و مقدار دهی شوند. +<<<<<<< HEAD .. note:: یک :ref:`تابع خارجی` نمی تواند یک آرایه چند بعدی را به عنوان یک ورودی قبول کند. این قابلیت @@ -81,6 +91,8 @@ یک :ref:`تابع داخلی` می تواند یک آرایه چند بعدی را بدون اضافه کردن این قابلیت به عنوان ورودی قبول کند. +======= +>>>>>>> english/develop .. index:: return array, return string, array, string, array of strings, dynamic array, variably sized array, return struct, struct متغیر های بازگشتی @@ -97,13 +109,13 @@ 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; } } @@ -121,12 +133,12 @@ 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); } } @@ -134,11 +146,24 @@ استفاده کرده اید، باید به همراه دستور return مقادیر بازگشتی را نیز فراهم کنید. .. note:: +<<<<<<< HEAD شما نمی توانید بعضی از نوع های متغیر را از توابع غیر-داخلی باز گردانید، بویژه آرایه های چند-بعدی پویا و ساختار های داده ای. اگر شما ABI کدر v2 را توسط ``;pragma abicoder v2`` فعال کرده باشید، فایل منبع کد شما نوع های بیشتری را قبول می کند، اما نوع های ``mapping`` هنوز دارای محدودیت هستند و فقط در داخل یک قرارداد استفاده می شوند و قابل انتقال نیستند. +======= + 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: @@ -212,7 +237,14 @@ توابع خالص -------------- +<<<<<<< HEAD توابعی خالص ``pure`` نامیده می شوند که قول دهند که از وضعیت نخوانند و تغییرش ندهند. +======= +Functions can be declared ``pure`` in which case they promise not to read from or modify the state. +In particular, it should be possible to evaluate a ``pure`` function at compile-time given +only its inputs and ``msg.data``, but without any knowledge of the current blockchain state. +This means that reading from ``immutable`` variables can be a non-pure operation. +>>>>>>> english/develop .. note:: اگر کامپایلر EVM بر روی Byzantium یا جدیدتر(پیش فرض) کد ``STATICCALL`` استفاده @@ -245,7 +277,11 @@ ایجاد شده بوده که محدودیت ``view`` یا ``pure`` نداشته اند واکشی شده است و این کد روشی برای گرفتن واکشی ``revert`` بدون ارسال آن است. +<<<<<<< HEAD این رفتار همچنین هم سو با کد ``STATICCALL`` است. +======= +This behavior is also in line with the ``STATICCALL`` opcode. +>>>>>>> english/develop .. warning:: این امکان وجود ندارد که از خواندن وضعیت توسط توابع در سطح EVM جلوگیری کرد @@ -269,7 +305,7 @@ توابع خاص ================= -.. index:: ! receive ether function, function;receive ! receive +.. index:: ! receive ether function, function;receive, ! receive .. _receive-ether-function: @@ -281,12 +317,23 @@ این تابع نمی تواند ورودی و مقدار بازگشتی داشته باشد، و باید میدان دید ``external`` خارجی و وضعیت ``payable`` تغییرناپذیر داشته باشد. می تواند مجازی باشد ، می تواند بازنویسی(override) و تغییر دهنده داشته باشد. +<<<<<<< HEAD تابع دریافت زمان فراخوانی می شود که به قرارداد، فراخوانی به همراه فراخوانی داده خالی ارسال شود. این همان تابعی است که در انتقال های اتر اجرا می شود( مثل ``()send.`` یا ``()transfer.`` ). اگر چنین تابعی وجود نداشته باشد، اما یک :ref:`تابع عقبگرد ` قابل پرداخت وجود داشته باشد، تابع عقبگرد در انتقال اتر فراخوانی می شود. اگر هر دو تابع وجود نداشته باشد، قرارداد قادر به دریافت تراکنسهای اتری به روش های عادی نخواهد بود و خطایی استثنا بروز خواهد داد. +======= +The receive function is executed on a +call to the contract with empty calldata. This is the function that is executed +on plain Ether transfers (e.g. via ``.send()`` or ``.transfer()``). If no such +function exists, but a payable :ref:`fallback function ` +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 +exception. +>>>>>>> english/develop در بدترین حالت ، تابع ``receive`` تنها می تواند توسط 2300 گاز در دسترس باشد( برای مثال زمانی که از ``send`` یا ``transfer`` استفاده شود)، فضای کمی برای انجام عملیات دیگر بجز ورود @@ -299,12 +346,22 @@ - ارسال اتر .. warning:: +<<<<<<< HEAD قراردادهایی که مستقیما اتر دریافت می کنند (بدون یک فراخوانی تابع، مثل ``send`` یا ``transfer``) اما تابع دریافت اتر ندارند یا یک تابع عقبگرد ندارند یک استثنا از خود بروز می دهند، و اتر ارسالی را باز می گردانند( این روش تا قبل از سالیدیتی نسخه 0.4.0 متفاوت بود). بنابراین اگر می خواهید قرارداد شما اتر دریافت کند ، شما مجبور هستید یک تابع دریافت اتر پیاده سازی کنید. (استفاده از تابع عقبگرد قابل پرداخت برای دریافت اتر پیشنهاد نمی شود، زیرا امکان دارد در تداخلات رابط خطا ندهد). +======= + 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:: @@ -339,18 +396,32 @@ تابع عقبگرد ----------------- +<<<<<<< HEAD یک قرارداد می تواند حداکثر یک تابع ``fallback`` داشته باشد، با ساتفاده از ``fallback () external [payable]`` یا ``fallback (bytes calldata _input) external [payable] returns (bytes memory _output)`` (هر دو بدون استفاده از کلمه کیلیدی ``function`` ) تعریف می شوند. این تابع باید دارای میدان دید خارجی ``external`` باشد. یک تابع عقبگرد می تواند مجازی در بدترباشد ، می تواند بازنویسی یا دارای تغییردهنده باشد. +======= +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 تابع عقبگرد هنگام فراخوانی قرارداد اجرا شده و اگر دیگر توابع با امضاء این تابع همخوانی نداشته باشد یا اگر داده ای درکل فراهم نشده و یا اگر :ref:`تابع گیرنده اتر ` تعریف نشده باشد. تابع عقبگرد همیشه داده دریافت می کند ، اما برای دریافت اتر باید بصورت ``payable`` نشان گذاری شده باشد. +<<<<<<< HEAD اگر نسخه به همراه پارامترها استفاده شده باشد، ``input_`` شامل کل داده ارسالی توسط قرارداد (برابر است یا ``msg.data`` ) است و ``output_`` می تواند داده را بازگرداند. داده برگشتی بصورت ABI- encoded نخواهد بود. در عوض بدون تغییرات برگشت خواهد شد( حتی بدون لایه بندی). +======= +If the version with parameters is used, ``input`` will contain the full data sent to the contract +(equal to ``msg.data``) and can return data in ``output``. The returned data will not be +ABI-encoded. Instead it will be returned without modifications (not even padding). +>>>>>>> english/develop در بدترین حالت، اگر یک تابع عقبگرد قابل پرداخت بجای تابع گیرنده مورد استفاده قرار گیرد، فقط با توسل به 2300 گاز در دسترس خواهد بود( بخش :ref:`تابع گیرنده اتر ` برای توضیحات و @@ -366,11 +437,21 @@ encoded نخواهد بود. در عوض بدون تغییرات برگشت خو جلوگیری می کند. .. note:: +<<<<<<< HEAD اگر شما می خواهید داده ورودی رمزگشایی(decode) کنید، شما می توانید با بررسی کردن چهار بایت اول از تابع انتخابگر و سپس با استفاده از ``abi.decode`` به همراه تکه ای از آرایه نوشتاری رمزگشایی داده کدشده-ABI استفاده کنید: ``(c, d) = ;abi.decode(_input[4:], (uint256, uint256))`` نکته اینکه این روش باید به عنوان آخرین راه حل مورد استفاده قرار گیرد و بجای آن باید از توابع مناسب استفاده کرد. +======= + 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 @@ -456,13 +537,13 @@ encoded نخواهد بود. در عوض بدون تغییرات برگشت خو 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; } } @@ -476,12 +557,12 @@ encoded نخواهد بود. در عوض بدون تغییرات برگشت خو // 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; } } @@ -509,12 +590,12 @@ encoded نخواهد بود. در عوض بدون تغییرات برگشت خو 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 d6d989944b..a06084df16 100644 --- a/docs/contracts/inheritance.rst +++ b/docs/contracts/inheritance.rst @@ -33,7 +33,7 @@ // 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); } @@ -47,7 +47,7 @@ // accessed externally via `this`, though. contract Destructible is Owned { // The keyword `virtual` means that the function can change - // its behaviour in derived classes ("overriding"). + // its behavior in derived classes ("overriding"). function destroy() virtual public { if (msg.sender == owner) selfdestruct(owner); } @@ -69,9 +69,9 @@ } - // Multiple inheritance is possible. Note that `owned` is + // 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++). + // instance of `Owned` (as for virtual inheritance in C++). contract Named is Owned, Destructible { constructor(bytes32 name) { Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970); @@ -108,7 +108,7 @@ // Here, we only specify `override` and not `virtual`. // This means that contracts deriving from `PriceFeed` - // cannot change the behaviour of `destroy` anymore. + // cannot change the behavior of `destroy` anymore. function destroy() public override(Destructible, Named) { Named.destroy(); } function get() public view returns(uint r) { return info; } @@ -122,6 +122,7 @@ // 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); } @@ -154,6 +155,7 @@ // 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); } @@ -274,8 +276,13 @@ owned) تعلق دارد. تابع واقعی که هنگام استفاده ا وراثتی که از قرارداد مورد نظر شروع و در یک قرارداد اشاره شده یک تابع به همراه امضا آن که بازنویسی نشده است پایان می یابد. +<<<<<<< HEAD اگر تابعی را به عنوان ``virtual`` که بازنویسی شده است نشان گذاری نکنید، قرارداد هایی که آن تابع را به ارث می برند نمی توانند رفتار آن را تغییر دهند. +======= +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:: @@ -397,8 +404,8 @@ owned) تعلق دارد. تابع واقعی که هنگام استفاده ا abstract contract A { uint public a; - constructor(uint _a) { - a = _a; + constructor(uint a_) { + a = a_; } } @@ -411,6 +418,7 @@ owned) تعلق دارد. تابع واقعی که هنگام استفاده ا مقادیر معتبر از خارج داد، بلکه فقط از طریق سازنده ی قرادادی که از آن اجرا شده است امکان پذیر می باشد. +<<<<<<< HEAD .. warning :: تا قبل از نسخه 0.4.22، سازنده ها به عنوان تابع هم نام با نام قرارداد تعریف می شدند. این نحوه نوشتاری منسوخ شد و دیگر از نسخه 0.5.0 مجاز نیست. @@ -418,9 +426,18 @@ owned) تعلق دارد. تابع واقعی که هنگام استفاده ا .. warning :: تا قبل از نسخه 0.7.0، شما باید محدوده ی دید سازنده ها را توسط ``internal`` یا ``public`` مشخص می کردید. +======= +.. warning:: + 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 آرگومانها برای سازنده های پایه =============================== @@ -436,7 +453,7 @@ owned) تعلق دارد. تابع واقعی که هنگام استفاده ا contract Base { uint x; - constructor(uint _x) { x = _x; } + constructor(uint x_) { x = x_; } } // Either directly specify in the inheritance list... @@ -444,11 +461,21 @@ owned) تعلق دارد. تابع واقعی که هنگام استفاده ا constructor() {} } - // or through a "modifier" of the derived constructor. + // or through a "modifier" of the derived constructor... 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 روش اول مستقیما از طریق لیست ورارثت است (``is Base(7)``). روش دیگر از روش اول به این صورت است که یک اصلاح کننده به عنوان بخشی از سازنده فراخوانی شده استفاده یم شود (``Base(_y * _y)``). انجام روش اول راحت تر است اگر ورودی سازنده یک ثابت باید و رفتار @@ -459,6 +486,26 @@ owned) تعلق دارد. تابع واقعی که هنگام استفاده ا اگر یک قرارداد ارث گرفته شده ورودی های همه سازنده های قرارداد پایه خود را مشخص نکند، abstract خواهد بود. +======= +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 @@ -545,9 +592,11 @@ One area where inheritance linearization is especially important and perhaps not Inheriting Different Kinds of Members of the Same Name ====================================================== -It is an error when any of the following pairs in a contract have the same name due to inheritance: - - a function and a modifier - - a function and an event - - an event and a modifier +The only situations where, due to inheritance, a contract may contain multiple definitions sharing +the same name are: -As an exception, a state variable getter can override an external function. +- Overloading of functions. +- Overriding of virtual functions. +- Overriding of external virtual functions by state variable getters. +- Overriding of virtual modifiers. +- Overloading of events. diff --git a/docs/contracts/interfaces.rst b/docs/contracts/interfaces.rst index a4581a15f9..a3085667b7 100644 --- a/docs/contracts/interfaces.rst +++ b/docs/contracts/interfaces.rst @@ -10,7 +10,7 @@ Interfaces are similar to abstract contracts, but they cannot have any functions There are further restrictions: - They cannot inherit from other contracts, but they can inherit from other interfaces. -- All declared functions must be external. +- 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. @@ -65,7 +65,7 @@ inheritance. Types defined inside interfaces and other contract-like structures can be accessed from other contracts: ``Token.TokenType`` or ``Token.Coin``. -.. warning: +.. warning:: Interfaces have supported ``enum`` types since :doc:`Solidity version 0.5.0 <050-breaking-changes>`, make sure the pragma version specifies this version as a minimum. diff --git a/docs/contracts/libraries.rst b/docs/contracts/libraries.rst index 4f0f03fec7..7256ebe031 100644 --- a/docs/contracts/libraries.rst +++ b/docs/contracts/libraries.rst @@ -34,7 +34,8 @@ contracts (using qualified access like ``L.f()``). Of course, calls to internal functions use the internal calling convention, which means that all internal types can be passed and types :ref:`stored in memory ` will be passed by reference and not copied. -To realize this in the EVM, code of internal library functions +To realize this in the EVM, the code of internal library functions +that are called from a contract and all functions called from therein will at compile time be included in the calling contract, and a regular ``JUMP`` call will be used instead of a ``DELEGATECALL``. @@ -145,16 +146,16 @@ custom types without the overhead of external function calls: 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; @@ -171,8 +172,8 @@ custom types without the overhead of external function calls: } } - 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) { @@ -214,7 +215,7 @@ In comparison to contracts, libraries are restricted in the following ways: (These might be lifted at a later point.) .. _library-selectors: -.. index:: selector +.. index:: ! selector; of a library function Function Signatures and Selectors in Libraries ============================================== diff --git a/docs/contracts/using-for.rst b/docs/contracts/using-for.rst index 582409904f..a05cb277c6 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,71 +6,146 @@ Using For ********* -The directive ``using A for B;`` can be used to attach library -functions (from the library ``A``) to any type (``B``) -in the context of a contract. -These functions will receive the object they are called on +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. -The effect of ``using A for *;`` is that the functions from -the library ``A`` are attached to *any* type. +It is valid either at file level or inside a contract, +at contract level. -In both situations, *all* functions in the library are attached, +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 -contract, including within all of its functions, and has no effect -outside of the contract in which it is used. The directive -may only be used inside a contract, not inside any of its functions. +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` in this way: +:ref:`libraries` section in this way, using file-level functions +instead of library functions. .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.6.0 <0.9.0; + pragma solidity ^0.8.13; - - // This is the same code as before, just without comments 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; + + function insert(Data storage self, uint value) + returns (bool) + { + if (self.flags[value]) + return false; // already there + self.flags[value] = true; + return true; + } - library Set { - function insert(Data storage self, uint value) - public - returns (bool) - { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) - public - returns (bool) - { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } + function remove(Data storage self, uint value) + returns (bool) + { + if (!self.flags[value]) + return false; // not there + self.flags[value] = false; + return true; + } - function contains(Data storage self, uint value) - public - view - returns (bool) - { - return self.flags[value]; - } + function contains(Data storage self, uint value) + view + returns (bool) + { + return self.flags[value]; } contract C { - using Set for Data; // this is the crucial change Data knownValues; function register(uint value) public { @@ -82,12 +157,13 @@ Let us rewrite the set example from the } } -It is also possible to extend elementary types in that way: +It is also possible to extend built-in types in that way. +In this example, we will use a library. .. 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 +176,61 @@ It is also possible to extend elementary types in that way: return type(uint).max; } } + using Search for uint[]; contract C { - using Search for uint[]; uint[] data; function append(uint value) public { data.push(value); } - function replace(uint _old, uint _new) public { + function replace(uint from, uint to) public { // This performs the library function call - uint index = data.indexOf(_old); + uint index = data.indexOf(from); if (index == type(uint).max) - data.push(_new); + data.push(to); else - data[index] = _new; + data[index] = to; } } 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 of the +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); + } + } diff --git a/docs/contracts/visibility-and-getters.rst b/docs/contracts/visibility-and-getters.rst index 5dd7513137..0b6bbd87ee 100644 --- a/docs/contracts/visibility-and-getters.rst +++ b/docs/contracts/visibility-and-getters.rst @@ -1,20 +1,41 @@ .. index:: ! visibility, external, public, private, internal +.. |visibility-caveat| replace:: Making something ``private`` or ``internal`` only prevents other contracts from reading or modifying the information, but it will still be visible to the whole world outside of the blockchain. + .. _visibility-and-getters: ********************** Visibility and Getters ********************** -Solidity knows two kinds of function calls: internal -ones that do not create an actual EVM call (also called -a "message call") and external -ones that do. Because of that, there are four types of visibility for -functions and state variables. +State Variable Visibility +========================= + +``public`` + Public state variables differ from internal ones only in that the compiler automatically generates + :ref:`getter functions` for them, which allows other contracts to read their values. + When used within the same contract, the external access (e.g. ``this.x``) invokes the getter + while internal access (e.g. ``x``) gets the variable value directly from storage. + Setter functions are not generated so other contracts cannot directly modify their values. -Functions have to be specified as being ``external``, -``public``, ``internal`` or ``private``. -For state variables, ``external`` is not possible. +``internal`` + Internal state variables can only be accessed from within the contract they are defined in + and in derived contracts. + They cannot be accessed externally. + This is the default visibility level for state variables. + +``private`` + Private state variables are like internal ones but they are not visible in derived contracts. + +.. warning:: + |visibility-caveat| + +Function Visibility +=================== + +Solidity knows two kinds of function calls: external ones that do create an actual EVM message call and internal ones that do not. +Furthermore, internal functions can be made inaccessible to derived contracts. +This gives rise to four types of visibility for functions. ``external`` External functions are part of the contract interface, @@ -24,27 +45,19 @@ For state variables, ``external`` is not possible. ``public`` Public functions are part of the contract interface - and can be either called internally or via - messages. For public state variables, an automatic getter - function (see below) is generated. + and can be either called internally or via message calls. ``internal`` - Those functions and state variables can only be - accessed internally (i.e. from within the current contract - or contracts deriving from it), without using ``this``. - This is the default visibility level for state variables. + Internal functions can only be accessed from within the current contract + or contracts deriving from it. + They cannot be accessed externally. + Since they are not exposed to the outside through the contract's ABI, they can take parameters of internal types like mappings or storage references. ``private`` - Private functions and state variables are only - visible for the contract they are defined in and not in - derived contracts. + Private functions are like internal ones but they are not visible in derived contracts. -.. note:: - Everything that is inside a contract is visible to - all observers external to the blockchain. Making something ``private`` - only prevents other contracts from reading or modifying - the information, but it will still be visible to the - whole world outside of the blockchain. +.. warning:: + |visibility-caveat| مشخص کننده میدان دید پس از نوع متغیر وضعیت و در توابع بین لیست پارامتر ها و لیست پارامتر های بازگشتی می آید. @@ -182,12 +195,12 @@ For state variables, ``external`` is not possible. 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; } این تابعی به شکل زیر ایجاد می کند. نگاشت در ساختار حذف شده است زیرا راه خوبی جهت diff --git a/docs/contributing.rst b/docs/contributing.rst index ec0d8b2cd5..d391909ac5 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -2,10 +2,15 @@ همکاری ####### +<<<<<<< HEAD همیشه از کمک دیگران استقبال می شود و گزینه های زیادی وجود دارد که چگونه می توانید به سالیدیتی کمک کنید. +======= +Help is always welcome and there are plenty of options to contribute to Solidity. +>>>>>>> english/develop به ویژه، از حمایت های شما در زمینه های زیر قدردانی می کنیم: +<<<<<<< HEAD * گزارش ایراد ها * رفع و پاسخگویی به `ایراد های سالیدیتی در گیت هاب `_، مخصوصا مواردی که با عنوان " @@ -14,17 +19,35 @@ * ترجمه اسناد به زبان های بیشتر. * پاسخگویی به سوالات دیگر کاربر ها در `stackExchange `_ و سالیدیتی `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 + `_. +* Getting involved in the language design process by proposing language changes or new features in the `Solidity forum `_ and providing feedback. +>>>>>>> english/develop در شروع، برای آشنایی با خود اجزا های سالیدیتی و روند ساخت (build) سالیدیتی، می توانید ساختن از منبع :ref:`building-from-source` را امتحان کنید. همچنین، داشتن مهارت کافی در نوشتن قرار داد های سالیدیتی ممکن است مفید باشد. +<<<<<<< HEAD لطفا توجه داشته باشید که این پروژه `یک کد مشارکتی `_ است. با شرکت در این پروژه – در ایرادها، درخواست های پول(pull)، یا کانال های gitter – شما قبول می کنید که قوانین آن را رعایت کنید. +======= +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 تماس های تیمی ============= +<<<<<<< HEAD اگر مشکلات یا در خواست های پول(pull) دارید برای مطرح کردن، یا علاقمند به شنیدن این هستید که تیم و مشارکت کنندگان مشغول به چه کار هایی هستند، می توانید به تماس های تیمی عمومی ما بپیوندید: @@ -33,6 +56,14 @@ - چهارشنبه ها ساعت 2 بعد از ظهر CET/CEST( به وقت مرکزی تابستانی اروپا) هر دو وقت تماس در `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 چطوری ایراد ها را گزارش دهیم ============================ @@ -41,6 +72,7 @@ `ردیاب ایرادات GitHub `_ استفاده کنید. هنگام گزارش ایرادات ، لطفا جزئیات زیر را ذکر کنید: +<<<<<<< HEAD * نسخه سالیدیتی. * کد منبع (در صورت امکان). * سیستم عامل. @@ -49,6 +81,19 @@ به حداقل رسانی کد منبع که باعث رخداد ایراد می شود همیشه بسیار مفید است و حتی بعضی اوقات یک سوء تفاهم را روشن می کند. +======= +* 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 روند کاری برای درخواست های pull =============================== @@ -65,9 +110,15 @@ علاوه بر این، اگر در حال نوشتن ویژگی جدید هستید، لطفا مطمئن شوید که موارد آزمایشی مناسب را بخش ``test/`` قرار داده اید/(به زیر توجه کنید) : +<<<<<<< HEAD با این حال، اگر تغییر بزرگتری ایجاد می کنید، لطفا اول با کانال `Solidity Development Gitter channel `_ توسعه سالیدیتی مشورت کنید ( متفاوت از یک مورد که در بالا ذکر شد، این مورد بجای کاربرد زبان ، به کامپایلر و توسعه زبان اشاره می کند) +======= +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 ویژگی های جدید و رفع اشکالات باید به فایل ``Changelog.md`` اضافه شود: لطفا در صورت نیاز سبک نوشته های قبلی را دنبال کنید @@ -76,7 +127,14 @@ درسته که ما آزمایش CI را انجام می دهیم، لطفا کد خود را آزمایش کرده و قبل از ارسال درخواست pull اطمینان حاصل کنید که بصورت محلی قابل ساخت (build) است. +<<<<<<< HEAD از کمک شما متشکریم! +======= +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 اجرای تست های کامپایلر ====================== @@ -84,6 +142,7 @@ پیش نیاز ها ------------- +<<<<<<< HEAD برخی از تست ها به کتابخانه evmone و برخی دیگر به libz3 نیاز دارند. (`evmone `_, `libz3 `_, و `libhera `_). @@ -94,31 +153,50 @@ اجرای تست ها ------------ +======= +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 سالیدیتی شامل انواع مختلفی از تست ها است، بیشتر آنها وصل به بسته `Boost C++ Test Framework `_ برنامه ``soltest`` می باشند. اجرای ``build/test/soltest`` یا پوشش دهنده اش ``scripts/soltest.sh`` برای بیشتر تغییرات کافی است. +<<<<<<< HEAD اسکریپت ``scripts/test.sh/.`` به صورت اتوماتیک بیشتر تست های سالیدتی را اجرا می کند ، هم بسته های `Boost C++ Test Framework `_ برنامه ``soltest`` (یا پوشش دهنده ی ``scripts/soltest.sh``) ، همچنین تست های تلفیقی و خط فرمان را اجرا می کند. +======= +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 سیستم تست به صورت اتوماتیک از پوشه جاری سعی می کند مکان کتابخانه `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 +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. ``evmone`` is needed mainly for running semantic and gas tests. If you do not have it installed, you can skip these tests by passing the ``--no-semantic-tests`` flag to ``scripts/soltest.sh``. -Running Ewasm tests is disabled by default and can be explicitly enabled -via ``./scripts/soltest.sh --ewasm`` and requires `hera `_ -to be found by ``soltest``. -The mechanism for locating the ``hera`` library is the same as for ``evmone``, except that the -variable for specifying an explicit location is called ``ETH_HERA``. - -The ``evmone`` and ``hera`` libraries should both end with the file name +The ``evmone`` library should both end with the file name extension ``.so`` on Linux, ``.dll`` on Windows systems and ``.dylib`` on macOS. For running SMT tests, the ``libz3`` library must be installed and locatable @@ -129,7 +207,7 @@ by ``cmake`` during compiler configure stage. اجرای ``scripts/soltest.sh --no-smt/.`` این تست ها ``libsolidity/smtCheckerTests`` و ``libsolidity/smtCheckerTestsJSON`` هستند. -.. note :: +.. note:: برای گرفتن لیست واحد های تست اجرا شونده توسط soltest ، دستور . ``build/test/soltest --list_content=HRF/.`` اجرا کنید. @@ -151,7 +229,7 @@ by ``cmake`` during compiler configure stage. - `run_test (-t) `_ برای اجرای تست های خاص و - `report-level (-r) `_ یک گزارش دقیقتر ارائه می دهد. -.. note :: +.. note:: آنهایی که در محیط ویندوزی می خواهند مجموعه های ساده ی بالا را بدون کتابخانه libz3 اجرا کنند. از گیت بش(bash) ``build/test/Release/soltest.exe -- --no-smt\.`` استفاده کنند. @@ -161,6 +239,12 @@ by ``cmake`` during compiler configure stage. “usual” عمل ساخت را انجام می دهید. برای مثال، شما می توانید با دستور زیر در پوشه ``build`` عمل کنید: +<<<<<<< HEAD +======= +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 .. @@ -214,7 +298,11 @@ CI تست های اضافه تری را اجرا می کند ( شامل ``solc-j // ---- // DeclarationError: (36-52): Identifier already declared. +<<<<<<< HEAD اجرای ``build/test/isoltest/.`` دوباره منجر به تست ناموفق میشود : +======= +Running ``./build/test/tools/isoltest`` again results in a test failure: +>>>>>>> english/develop .. code-block:: text @@ -235,12 +323,21 @@ CI تست های اضافه تری را اجرا می کند ( شامل ``solc-j چندین گزینه برای تست های ناموفق پیشنهاد می کند: +<<<<<<< HEAD - ``isoltest`` : ``edit`` تلاش می کند قرار داد را در یک ویراشگر باز کند تا بتوانید آن را ویرایش کنید. با ویرایشگر ارائه شده در خط فرمان ( به عنوان ``isotest --editor /path/to/editor``) در متغیر محیطی ``EDITOR`` یا فقط از مسیر ``/usr/bin/editor`` (به ترتیب) استفاده می کند. - ``update``: انتظارات مربوط به قرارداد تحت تست را بروزرسانی می کند. با حذف حاشیه نویسی هایی که با انتظارات مغایرت دارند و اضافه کردن حاشیه نویسی هایی که طبق انتظارات از قلم افتاده اند عمل بروز رسانی را انجام می دهد. سپس تست را مجددا اجرا می کند. - ``skip``: اجرای این تست را رد می کند. - ``quit``: از ``isotest`` خارج می شود. تمامی این گزینه ها بر قرار داد جاری اعمال می شوند به غیر از گزینه خروج ``quit`` که کل روند تست را متوقف می کند. +======= +- ``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 به صورت خودکار بروز رسانی تست بالا آن را تغییر می دهد به @@ -266,6 +363,62 @@ CI تست های اضافه تری را اجرا می کند ( شامل ``solc-j قرار ندهید، مگر اینکه در حال تست فراخوانی های وراثتی بین قرارداد ها باشید. هر فایل باید یک جنبه از ویژگی جدید شما را تست کند. +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. اجرای فازر(Fuzzer) توسط AFL =========================== @@ -290,7 +443,11 @@ code) را به عنوان ورودی می گیرید و هر زمان که با cmake .. -DCMAKE_C_COMPILER=path/to/afl-gcc -DCMAKE_CXX_COMPILER=path/to/afl-g++ make solfuzzer +<<<<<<< HEAD در این مرحله باید بتوانید پیامی مشابه پیام زیر را مشاهده کنید: +======= +At this stage, you should be able to see a message similar to the following: +>>>>>>> english/develop .. code-block:: text @@ -345,10 +502,18 @@ code) را به عنوان ورودی می گیرید و هر زمان که با # extract from documentation: path/to/solidity/scripts/isolate_tests.py path/to/solidity/docs +<<<<<<< HEAD در اسناد AFL آمده است که حجم (فایل های ورودی) نباید خیلی بزرگ باشد. خود فایل ها نباید بزرگتر از 1 کیلو بایت باشند و باید حداکثر یک فایل ورودی در هر عملکرد داشته باشد، بنابراین بهتر است با تعداد کوچک شروع کرد. همچنین ابزاری بنام ``afl-cm`` وجود دارد که می تواند فایل های ورودی که منجر به رفتار مشابه برنامه می شوند، اصلاح کند. +======= +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 حالا فزر را اجرا کنید( گزینه ``-m`` اندازه حافظه را تا 60MB مگابایت افزایش می دهد): @@ -396,6 +561,7 @@ code) را به عنوان ورودی می گیرید و هر زمان که با زبان انگلیسی ---------------- +<<<<<<< HEAD از زبان انگلیسی استفاده کنید با لهجه انگلیسی، مگر اینکه از نام پروژه یا برندی استفاده می کنید. سعی کنید از زبان عامیانه و اصطلاحات محلی کمتر استفاده کنید، حدالمکان زبان خود را برای خوانندگان واضح کنید. در زیر برخی از منابع برای کمک وجود دارند: @@ -411,6 +577,19 @@ code) را به عنوان ورودی می گیرید و هر زمان که با مشارکت کنندگان جامعه ترجمه هایی :ref:`translations` به زبان های دیگر موجود است. Please refer to the `translation guide `_ +======= +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 `_ +>>>>>>> english/develop for information on how to contribute to the community translations. حروف بزرگ برای عناوین @@ -474,6 +653,7 @@ code) را به عنوان ورودی می گیرید و هر زمان که با اجرای تست های مستندات --------------------------- +<<<<<<< HEAD با اجرای ``scripts/docs.sh/.`` مطمئن شوید که مشارکت های شما از تست های مستندات ما با موفقیت خارج شده است که وابستگی های مورد نیاز برای اسناد را نصب می کند و هرگونه مشکل مانند لینک های خراب و ایراد های نوشتاری را بررسی می کند. @@ -483,6 +663,18 @@ code) را به عنوان ورودی می گیرید و هر زمان که با برای اینکه فعالانه در گیر فرایند طراحی زبان شوید و ایده های خود را در مورد آینده سالیدیتی به اشتراک بگذارید، لطفا به `انجمن سالیدتی `_ بپیوندید. +======= +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 انجمن سالیدیتی به عنوان محلی برای پیشنهاد و بحث در مورد ویژگی های جدید زبان و اجرای آنها در مراحل اولیه ایده پردازی یا اصلاح ویژگی در دسترس است. @@ -502,7 +694,12 @@ code) را به عنوان ورودی می گیرید و هر زمان که با مورد بحث قرار می گیرند. با تغییر از شاخه پیش فرض (`توسعه`) به `شاخه جدید `_، می توانید تغییرات بعدی را برای نسخه جدید بعدی مشاهده کنید. +<<<<<<< HEAD برای موارد و سوالات موقتی می توانید از طریق کانال `Solidity-dev Gitter channel `_ با ما ارتباط برقرار کنید، یک اتاق گفتگوی اختصاصی برای بحث در مورد کامپایلر سالیدیتی و توسعه زبان ایجاد شده است. +======= +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 ما نظرات شما را در مورد اینگه چگونه می توانیم روند طراحی زبان را بهبود بخشیم حتی با همکاری بیشتر یا نیمه خوشحال می شویم، بشنویم. diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 9dd77b23db..9162b2707c 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -106,6 +106,7 @@ message call و نه مستقیماً از طریق jump ها، از هر دو .. warning:: +<<<<<<< HEAD مراقب باشید ``feed.info{value: 10, gas: 800}`` فقط ``value`` و مقدار ``gas`` ارسال شده با فراخوانی تابع را به صورت محلی تعیین کند و پرانتز در انتها فراخوانی واقعی را انجام دهد. بنابراین ``feed.info{value: 10, gas: 800}`` تابع را فراخوانی نمی‌کند و تنظیمات ``value`` و ``gas`` از بین @@ -117,6 +118,26 @@ message call و نه مستقیماً از طریق jump ها، از هر دو :ref:`فراخوانی‌های سطح پایین` که به جای قرارداد instances روی آدرس‌ها کار می‌کنند، انجام نمی‌شود. اگر قرارداد فراخوانی شده خودش یک اکستنشن ایجاد کند یا گاز تمام شود، توابع فراخوانی باعث ایجاد اکستنشن می‌شوند. +======= +Due to the fact that the EVM considers a call to a non-existing contract to +always succeed, Solidity uses the ``extcodesize`` opcode to check that +the contract that is about to be called actually exists (it contains code) +and causes an exception if it does not. This check is skipped if the return +data will be decoded after the call and thus the ABI decoder will catch the +case of a non-existing contract. + +Note that this check is not performed in case of :ref:`low-level calls ` which +operate on addresses rather than contract instances. + +.. note:: + Be careful when using high-level calls to + :ref:`precompiled contracts `, + since the compiler considers them non-existing according to the + above logic even though they execute code and can return data. + +Function calls also cause exceptions if the called contract itself +throws an exception or goes out of gas. +>>>>>>> english/develop .. warning:: @@ -133,12 +154,17 @@ message call و نه مستقیماً از طریق jump ها، از هر دو .. note:: +<<<<<<< HEAD قبل از سالیدیتی 0.6.2 ، روش توصیه شده برای تعیین مقدار و گاز استفاده از ``()f.value(x).gas(g)`` بود. این در سالیدیتی 0.6.2 منسوخ شد و دیگر از سالیدیتی 0.7.0 دیگر امکان پذیر نیست. فراخوان‌های نامگذاری شده و پارامترهای تابع ناشناس --------------------------------------------- +======= +Function Calls with Named Parameters +------------------------------------ +>>>>>>> english/develop آرگومان‌های فراخوانی تابع را می‌توان با نام، به هر ترتیب، در صورتی که در ``{ }`` محصور شده باشد، ارائه دهید، همانطور که در مثال زیر مشاهده می‌شود. لیست آرگومان باید توسط نام با پارامترهای اعلان تابع منطبق شود، @@ -160,15 +186,24 @@ message call و نه مستقیماً از طریق jump ها، از هر دو function set(uint key, uint value) public { data[key] = value; } - } +<<<<<<< HEAD نام پارامترهای تابع حذف شده -------------------------------- نام پارامترهای استفاده نشده (به ویژه پارامترهای برگشتی) را می توان حذف کرد. این پارامترها هنوز روی پشته وجود دارند، اما قابل دسترسی نیستند. +======= +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 @@ -272,7 +307,7 @@ instance از ``D`` با استفاده از گزینه ``value`` وجود د salt, keccak256(abi.encodePacked( type(D).creationCode, - arg + abi.encode(arg) )) ))))); @@ -282,6 +317,16 @@ instance از ``D`` با استفاده از گزینه ``value`` وجود د } .. warning:: +<<<<<<< HEAD +======= + There are some peculiarities in relation to salted creation. A contract can be + re-created at the same address after having been destroyed. Yet, it is possible + for that newly created contract to have a different deployed bytecode even + though the creation bytecode has been the same (which is a requirement because + otherwise the address would change). This is due to the fact that the constructor + can query external state that might have changed between the two creations + and incorporate that into the deployed bytecode before it is stored. +>>>>>>> english/develop یک سری ویژگی‌های مربوط به salted creationوجود دارد. پس از از بین رفتن، می‌توان یک قرارداد را در همان آدرس دوباره ایجاد کرد. با این وجود، آن قرارداد تازه ایجاد شده ممکن است دارای بایت‌کد دیپلوی @@ -355,6 +400,12 @@ instance از ``D`` با استفاده از گزینه ``value`` وجود د .. warning:: +<<<<<<< HEAD +======= + 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 هنگام اختصاص دادن چند متغیر به طور همزمان هنگامی که انواع مرجع درگیر هستند، مراقب باشید، زیرا ممکن است منجر به رفتار کپی غیر منتظره شود. @@ -364,6 +415,7 @@ instance از ``D`` با استفاده از گزینه ``value`` وجود د عوارض آرایه‌ها و ساختارها ------------------------------------ +<<<<<<< HEAD سمنتیک assignment ها برای تایپ‎‌های non-value مانند آرایه‌ها و ساختارها، از جمله ``bytes`` و ``string`` پیچیده تر است، برای اطلاعات بیشتر به قسمت :ref:`Data location و assignment behaviour ` مراجعه کنید. @@ -374,6 +426,10 @@ instance از ``D`` با استفاده از گزینه ``value`` وجود د مِمُوری ایجاد می‌کند. با این حال، ``h(x)`` با موفقیت ``x`` را تغییر می‌دهد زیرا فقط یک رفرنس منتقل می‌شود و نه یک کپی. +======= +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 .. code-block:: solidity @@ -506,6 +562,7 @@ overflow یا underflow وضعیتی است که در آن مقدار حاصل +<<<<<<< HEAD قبل از سالیدیتی 0.8.0 ، عملیات حسابی همیشه در صورت overflow یا underflow شدن منجر به استفاده گسترده از کتابخانه هایی می‌شود که چک‌های اضافی را ایجاد می‌کنند. @@ -518,6 +575,9 @@ overflow یا underflow وضعیتی است که در آن مقدار حاصل برای به دست آوردن رفتار قبلی، می‌توان از یک بلوک ``unchecked`` استفاده کرد: +======= +To obtain the previous behavior, an ``unchecked`` block can be used: +>>>>>>> english/develop .. code-block:: solidity @@ -665,6 +725,12 @@ s یک اکسپشن ``Error(string)`` (یا یک اکسپشن بدون داده) توسط کامپایلر در شرایط زیر ایجاد می‌شود: +<<<<<<< HEAD +======= +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 #. فراخوانی ``require(x)`` در جایی که ``x`` به صورت ``false`` ارزیابی شود. @@ -712,7 +778,7 @@ and ``assert`` for internal error checking. addr.transfer(msg.value / 2); // 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 money. + // still have half of the Ether. assert(address(this).balance == balanceBeforeTransfer - msg.value / 2); return address(this).balance; } @@ -727,6 +793,11 @@ and ``assert`` for internal error checking. در هر دو حالت، فراخوانی کننده می‌تواند با استفاده از ``try``/``catch`` واکنش نشان دهد، اما تغییرات در فراخوانی گیرنده همیشه برمی‌گردد. +<<<<<<< HEAD +======= +In both cases, the caller can react on such failures using ``try``/``catch``, but +the changes in the callee will always be reverted. +>>>>>>> english/develop .. note:: @@ -745,6 +816,11 @@ revert مستقیم را می‌توان با استفاده از دستور `` دستور ``revert`` یک خطای سفارشی را به عنوان آرگومان مستقیم و بدون پرانتز می‌گیرد: +<<<<<<< HEAD +======= +For backward-compatibility reasons, there is also the ``revert()`` function, which uses parentheses +and accepts a string: +>>>>>>> english/develop ;revert CustomError(arg1, arg2) @@ -886,7 +962,12 @@ NatSpec ارائه کرد که هیچ هزینه‌ای را متحمل نمی پس از بلوک های گرفتن ادامه می یابد. +<<<<<<< HEAD سالیدیتی بسته به نوع خطا از تایپ‌های مختلف بلوک‌های catch پشتیبانی می‌کند: +======= +It is planned to support other types of error data in the future. +The strings ``Error`` and ``Panic`` are currently parsed as is and are not treated as identifiers. +>>>>>>> english/develop @@ -928,6 +1009,7 @@ NatSpec ارائه کرد که هیچ هزینه‌ای را متحمل نمی .. note:: +<<<<<<< HEAD دلیل یک فراخوانی ناموفق می‌تواند manifold باشد. تصور نکنید که پیام خطا مستقیماً از قرارداد فراخوانی شده می‌آید: ممکن است خطا در اعماق فراخوانی زنجیره رخ داده باشد و قرارداد فراخوانی شده فقط آن را @@ -935,3 +1017,13 @@ NatSpec ارائه کرد که هیچ هزینه‌ای را متحمل نمی عمدی: فراخوانی کننده همیشه 63/64 گاز را در فراخوانی حفظ می‌کند و بنابراین حتی اگر قرارداد فراخوانی کننده از بین برود، فراخوانی کننده هنوز مقداری گاز باقی مانده دارد. +======= + The reason behind a failed call can be manifold. Do not assume that + the error message is coming directly from the called contract: + The error might have happened deeper down in the call chain and the + called contract just forwarded it. Also, it could be due to an + out-of-gas situation and not a deliberate error condition: + The caller always retains at least 1/64th of the gas in a call and thus + even if the called contract goes out of gas, the caller still + has some gas left. +>>>>>>> english/develop 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 2da28ef8e9..7fdf2cc30e 100644 --- a/docs/examples/blind-auction.rst +++ b/docs/examples/blind-auction.rst @@ -12,7 +12,16 @@ مزایده باز ساده =================== +<<<<<<< HEAD ایده‌ی کلی قرارداد مزایده ساده زیر این است که همه می‌توانند پیشنهادات خود را در طول یک دوره مناقصه ارسال کنند. پیشنهادات در حال حاضر شامل ارسال پول/ اتر به منظور متصل کردن مناقصه‌گرانِ مناقصه به پیشنهاد آنها است. اگر بالاترین پیشنهاد افزایش یابد، مناقصه‌گران قبلی پول خود را پس می‌گیرد. پس از پایان دوره مناقصه، قرارداد باید به صورت دستی فراخوانده شود تا ذینفع پول خود را دریافت کند- قراردادها نمی‌توانند خودشان فعال شوند. +======= +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 @@ -84,19 +93,19 @@ revert AuctionAlreadyEnded(); // If the bid is not higher, send the - // money back (the revert statement + // Ether back (the revert statement // will revert all changes in this // function execution including - // it having received the money). + // it having received the Ether). if (msg.value <= highestBid) revert BidNotHighEnough(highestBid); if (highestBid != 0) { - // Sending back the money by simply using + // 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 money themselves. + // withdraw their Ether themselves. pendingReturns[highestBidder] += highestBid; } highestBidder = msg.sender; @@ -113,6 +122,9 @@ // before `send` returns. pendingReturns[msg.sender] = 0; + // msg.sender is not of type `address payable` and must be + // explicitly converted using `payable(msg.sender)` in order + // use the member function `send()`. if (!payable(msg.sender).send(amount)) { // No need to call throw here, just reset the amount owing pendingReturns[msg.sender] = amount; @@ -158,11 +170,33 @@ مزایده باز قبلی در ادامه به مزایده کور توسعه یافته‌است. مزیت مزایده کور این است که هیچ گونه فشار زمانی نسبت به پایان دوره مناقصه وجود ندارد. ایجاد مزایده کور بر روی یک پلتفرم محاسباتی شفاف ممکن است متناقض به نظر برسد، اما رمزنگاری به کمک شما می‌آید. +<<<<<<< HEAD در طول دوره مناقصه، **یک پیشنهاد دهنده** در واقع پیشنهاد خود را ارسال نمی‌کند، بلکه فقط یک نسخه هش شده از آن را ارسال می‌کند. از آنجا که در حال حاضر یافتن دو مقدار (به اندازه کافی طولانی) که مقادیر هش آنها برابر باشد، عملاً غیرممکن تلقی می‌شود، مناقصه‌گر با این کار متعهد به مناقصه می‌شود. پس از پایان دوره مناقصه، مناقصه‌گران باید پیشنهادات خود را آشکار کنند: آنها مقادیر خود را بدون رمزگذاری ارسال می‌کنند و قرارداد بررسی می‌کند که مقدار هش همان مقدار ارائه شده در دوره مناقصه است. چالش دیگر این است که چگونه مزایده را به طور همزمان **اجباری و پنهان یا کور** جلوه دهید: تنها راه جلوگیری از ارسال نکردن مبلغ توسط داوطلب پس از برنده شدن در مزایده، ارسال آنها به همراه پیشنهاد است. از آنجا که انتقال مقدار در اتریوم پنهان یا کور نمی‌شود، هر کسی می‌تواند مقدار را ببیند. قرارداد زیر با قبول هر مقداری که بزرگتر از بالاترین پیشنهاد باشد، این مشکل را حل می‌کند. از آنجایی که این فقط در مرحله آشکار شدن قابل بررسی است، ممکن است برخی از پیشنهادات نامعتبر باشند، و این هدفمند است (حتی یک فلَگ صریح برای قرار دادن پیشنهادات **نامعتبر** با انتقال مقدار بالا ارائه می‌دهد): مناقصه‌گران با قرار دادن چند پیشنهاد زیاد یا کم اعتبار، می‌توانند رقابت را مختل کنند. +======= +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 .. code-block:: solidity diff --git a/docs/examples/micropayment.rst b/docs/examples/micropayment.rst index 712a6ce6a3..9042624ded 100644 --- a/docs/examples/micropayment.rst +++ b/docs/examples/micropayment.rst @@ -2,7 +2,15 @@ کانال پرداخت خرد ******************** +<<<<<<< HEAD در این بخش نحوه ساختن نمونه پیاده سازی کانال پرداخت را خواهیم آموخت. کانال پرداخت از امضاهای رمزنگاری شده برای انتقال مکرر اتر بین طرف‌های مشابه به صورت ایمن، آنی و بدون کارمزد استفاده می‌کند. برای مثال، باید نحوه امضا و تأیید امضاها و راه اندازی کانال پرداخت را درک کنیم. +======= +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 ایجاد و تأیید امضا ================================= @@ -11,23 +19,47 @@ آلیس فقط باید پیام های خارج از زنجیرهِ امضا شده با رمزنگاری (مثلاً از طریق ایمیل) را به باب بفرستد و این شبیه چک نوشتن است. +<<<<<<< HEAD آلیس و باب برای تأیید تراکنش‌ها از امضاها استفاده می‌کنند که با قراردادهای هوشمند در اتریوم امکان پذیر است. آلیس یک قرارداد هوشمند ساده خواهد ساخت که به او امکان می‌دهد اتر را منتقل کند، اما به جای اینکه خودش یک تابع را برای شروع پرداخت فراخوانی کند، به باب اجازه این کار را می‌دهد و بنابراین هزینه تراکنش را پرداخت می‌کند. +======= +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 قرارداد به شرح زیر کار می‌کند: +<<<<<<< HEAD 1. آلیس قرارداد ``ReceiverPays`` را دیپلوی می‌کند، به اندازه کافی اتر را برای پوشش پرداخت‌هایی که انجام خواهد شد، پیوست می‌کند. 2. آلیس با امضای پیام با کلید خصوصی خود اجازه پرداخت را می‌دهد. 3. آلیس پیام امضا شده با رمزنگاری را برای باب می‌فرستد. نیازی به مخفی نگه داشتن پیام نیست (بعداً توضیح داده خواهد شد) و سازوکار ارسال آن اهمیتی ندارد. 4. باب با ارائه پیام امضا شده به قرارداد هوشمند، پرداخت خود را مدعی می‌شود. قرارداد صحت پیام را تأیید می‌کند و سپس وجوه را آزاد می‌کند. +======= + 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 ایجاد امضا ---------------------- +<<<<<<< HEAD آلیس برای امضای تراکنش نیازی به تعامل با شبکه اتریوم ندارد، روند کار کاملا آفلاین است. در این آموزش، ما با استفاده از روش توصیف شده در `EIP-762 `_ پیام‌ها را در مرورگر با استفاده از `web3.js `_ و `MetaMask `_, امضا خواهیم کرد، زیرا تعدادی از مزایای امنیتی دیگر را فراهم می‌کند. +======= +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 @@ -60,10 +92,19 @@ بسته بندی آرگومان‌ها ----------------- +<<<<<<< HEAD حالا که ما مشخص کرده‌ایم که چه اطلاعاتی را باید در پیام امضا شده قرار دهیم، ما آماده هستیم که پیام را کنار هم قرار دهیم و آن را هش و امضا کنیم. برای سادگی، داده‌ها را بهم پیوند می‌دهیم. کتابخانه `ethereumjs-abi `_ تابعی به نام ``soliditySHA3`` را فراهم می‌کند که رفتار ``keccak256`` سالیدیتی را که برای آرگومان‌های رمزگذاری شده با استفاده از ``abi.encodePacked`` اعمال می‌شود، را تقلید می‌کند. در اینجا یک تابع جاوا اسکریپت وجود دارد که امضای مناسب را برای مثال ``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 @@ -106,6 +147,7 @@ // 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; @@ -205,8 +247,13 @@ هر پیام شامل اطلاعات زیر است: +<<<<<<< HEAD * آدرسِ قراردادِ هوشمند استفاده شده برای جلوگیری از حملات مجدد بین قراردادی. * مقدارِ کلِ اتری که تاکنون به گیرنده بدهکار است. +======= + * 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 در پایان یک سری انتقال‌ها، فقط یک بار کانال پرداخت بسته می‌شود. به همین دلیل، فقط یکی از پیام‌های ارسالی استفاده می‌شود. به همین دلیل است که هر پیام مجموع مقدار کل اتر بدهکار را به جای مقدار جداگانه کانال پرداخت مشخص می‌کند.گیرنده به طور طبیعی آخرین پیام را بخاطر اینکه بالاترین جمع کل را دارد، برای بازخرید انتخاب خواهد کرد. دیگر به نانس برای هر پیام نیاز نمی‌باشد زیرا قرارداد هوشمند فقط به یک پیام پایبند‌است. برای جلوگیری از استفاده پیامی که در نظر گرفته شده برای یک کانال پرداخت در کانال دیگر، از آدرس قرارداد هوشمند همچنان استفاده می‌شود. @@ -267,6 +314,7 @@ // 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 e76242cd04..c1fc84d330 100644 --- a/docs/examples/modular.rst +++ b/docs/examples/modular.rst @@ -4,8 +4,23 @@ قراردادهای ماژولی ***************** +<<<<<<< HEAD یک رویکرد ماژولی برای ساخت قراردادها، در کاهش پیچیدگی‌ها و بهبود خوانایی، که به شناسایی باگ‌ها و آسیب پذیری‌ها هنگام توسعه و بررسی کد کمک می‌کند. اگر رفتار یا هر ماژول را جداگانه تعیین و کنترل کنید، فعل و انفعالاتی را باید فقط در روابط بین مشخصات ماژول در نظر بگیرید و نه هر قسمت متحرک دیگر قرارداد. در مثال زیر، قرارداد از روش ``move`` :ref:`کتابخانه ` ``Balances`` برای بررسی اینکه بالانس‌های ارسال شده بین آدرس‌ها با آنچه شما انتظار دارید مطابقت دارد، استفاده می‌کند. به این ترتیب، کتابخانه ``Balances`` یک جز جداگانه است که موجودی حساب‌ها را به درستی ردیابی می‌کند را ارائه می‌دهد. به راحتی می‌توان تأیید کرد که کتابخانه ``Balances`` هرگز موجودی یا سرریز منفی تولید نمی‌کند و مجموع کل موجودی در طول مدت قرارداد ثابت نیست. +======= +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 @@ -24,7 +39,7 @@ 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 e84dcc3a50..4dc7b07818 100644 --- a/docs/examples/safe-remote.rst +++ b/docs/examples/safe-remote.rst @@ -4,9 +4,29 @@ خرید امن از راه دور ******************** +<<<<<<< HEAD خرید کالا از راه دور در حال حاضر نیاز به چندین طرف دارد که باید به یکدیگر اعتماد کنند. ساده ترین پیکربندی شامل یک فروشنده و یک خریدار است. خریدار مایل است کالایی را از فروشنده دریافت کند و فروشنده مایل است در ازای آن پول (یا معادل آن) دریافت کند. قسمت مشکل ساز محموله در اینجا است: هیچ راهی برای تعیین اطمینان از رسیدن کالا به خریدار وجود ندارد. روش‌های مختلفی برای حل این مشکل وجود دارد، اما همه آنها در مقابل یک یا بقیه راه‌ها کم می‌آورند. در مثال زیر، هر دو طرف باید مقدار دو برابر یک قلم کالا را به عنوان ضمانت در قرارداد قرار دهند. به محض اینکه این اتفاق افتاد، پول در قرارداد قفل شده خواهد ماند تا زمانی که خریدار تأیید کند که کالا را دریافت کرده‌است. پس از آن، مقدار (نیمی از سپرده خود) به خریدار بازگردانده می‌شود و فروشنده سه برابر مقدار (سپرده خود به علاوه مقدار) دریافت می‌کند. ایده پشت این امر این است که هر دو طرف انگیزه‌ای برای حل اوضاع دارند یا در غیر این صورت پول آنها برای همیشه قفل شده خواهد ماند. +======= +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. + +This contract of course does not solve the problem, but gives an overview of how +you can use state machine-like constructs inside a contract. +>>>>>>> english/develop البته این قرارداد مشکلی را حل نمی‌کند‌، اما یک نمای کلی از چگونگی استفاده از ساختار ماشین حالت مانند در داخل قرارداد ارائه می‌دهد. diff --git a/docs/examples/voting.rst b/docs/examples/voting.rst index 281b915144..cd7bfefc06 100644 --- a/docs/examples/voting.rst +++ b/docs/examples/voting.rst @@ -95,6 +95,7 @@ function delegate(address to) external { // assigns reference Voter storage sender = voters[msg.sender]; + require(sender.weight != 0, "You have no right to vote"); require(!sender.voted, "You already voted."); require(to != msg.sender, "Self-delegation is disallowed."); @@ -114,11 +115,16 @@ require(to != msg.sender, "Found loop in delegation."); } + 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].voted` + // modifies `voters[msg.sender]`. sender.voted = true; sender.delegate = to; - Voter storage delegate_ = voters[to]; + if (delegate_.voted) { // If the delegate already voted, // directly add to the number of votes @@ -173,4 +179,12 @@ بهبودهای احتمالی ===================== +<<<<<<< HEAD در حال حاضر، تراکنش‌ها زیادی برای واگذاری حق رأی به همه شرکت کنندگان مورد نیاز است. آیا می‌توانید به راه بهتری فکر کنید؟ +======= +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 2fc15ddda0..55fc0ef5c2 100644 --- a/docs/ext/remix_code_links.py +++ b/docs/ext/remix_code_links.py @@ -22,23 +22,16 @@ def remix_code_url(source_code, language, solidity_version): # NOTE: base64 encoded data may contain +, = and / characters. Remix seems to handle them just # fine without any escaping. 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 @@ -49,22 +42,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 5a73be85fd..43648ceb5d 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'; @@ -30,13 +29,11 @@ Else: 'else'; Emit: 'emit'; Enum: 'enum'; Error: 'error'; // not a real keyword -Revert: 'revert'; // not a real keyword Event: 'event'; External: 'external'; Fallback: 'fallback'; False: 'false'; Fixed: 'fixed' | ('fixed' [1-9][0-9]* 'x' [1-9][0-9]*); -From: 'from'; // not a real keyword /** * Bytes types of fixed length. */ @@ -46,7 +43,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 +62,17 @@ New: 'new'; /** * Unit denomination for numbers. */ -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 /** * Sized signed integer types. * int is an alias of int256. @@ -89,6 +90,7 @@ Try: 'try'; Type: 'type'; Ufixed: 'ufixed' | ('ufixed' [1-9][0-9]+ 'x' [1-9][0-9]+); Unchecked: 'unchecked'; +Unicode: 'unicode'; /** * Sized unsigned integer types. * uint is an alias of uint256. @@ -197,9 +199,7 @@ fragment EscapeSequence: /** * A single quoted string literal allowing arbitrary unicode characters. */ -UnicodeStringLiteral: - 'unicode"' DoubleQuotedUnicodeStringCharacter* '"' - | 'unicode\'' SingleQuotedUnicodeStringCharacter* '\''; +UnicodeStringLiteral: 'unicode' (('"' DoubleQuotedUnicodeStringCharacter* '"') | ('\'' SingleQuotedUnicodeStringCharacter* '\'')); //@doc:inline fragment DoubleQuotedUnicodeStringCharacter: ~["\r\n\\] | EscapeSequence; //@doc:inline @@ -221,6 +221,14 @@ fragment EvenHexDigits: HexCharacter HexCharacter ('_'? HexCharacter HexCharacte //@doc:inline fragment HexCharacter: [0-9A-Fa-f]; +/** + * 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. @@ -231,6 +239,12 @@ DecimalNumber: (DecimalDigits | (DecimalDigits? '.' DecimalDigits)) ([eE] '-'? D fragment DecimalDigits: [0-9] ('_'? [0-9])* ; +/** + * 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. @@ -251,6 +265,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) ; @@ -278,14 +298,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 f7630c59ee..c46cefd2fa 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -12,6 +12,7 @@ options { tokenVocab=SolidityLexer; } sourceUnit: ( pragmaDirective | importDirective + | usingDirective | contractDefinition | interfaceDefinition | libraryDefinition @@ -21,6 +22,7 @@ sourceUnit: ( | enumDefinition | userDefinedValueTypeDefinition | errorDefinition + | eventDefinition )* EOF; //@doc: inline @@ -151,7 +153,7 @@ stateMutability: Pure | View | Payable; */ overrideSpecifier: Override (LParen overrides+=identifierPath (Comma overrides+=identifierPath)* RParen)?; /** - * The definition of contract, library and interface functions. + * 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. */ @@ -160,7 +162,7 @@ locals[ boolean visibilitySet = false, boolean mutabilitySet = false, boolean virtualSet = false, - boolean overrideSpecifierSet = false + boolean overrideSpecifierSet = false, ] : Function (identifier | Fallback | Receive) @@ -174,6 +176,7 @@ locals[ )* (Returns LParen returnParameters=parameterList RParen)? (Semicolon | body=block); + /** * The definition of a modifier. * Note that within the body block of a modifier, the underscore cannot be used as identifier, @@ -311,10 +314,37 @@ errorDefinition: Semicolon; /** - * Using directive to bind library functions to types. - * Can occur within contracts and libraries. + * Operators that users are allowed to implement for some types with `using for`. */ -usingDirective: Using identifierPath For (Mul | typeName) Semicolon; +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)?; + /** * A type name can be an elementary type, a function type, a mapping type, a user-defined type * (e.g. a contract or struct) or an array type. @@ -346,7 +376,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 @@ -367,12 +397,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 ; @@ -388,9 +419,12 @@ inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack; /** * Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers. */ -identifier: Identifier | From | Error | Revert; +identifier: Identifier | From | Error | Revert | Global; literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral; + +literalWithSubDenomination: numberLiteral SubDenomination; + booleanLiteral: True | False; /** * A full string literal consists of either one or several consecutive quoted strings. @@ -408,7 +442,8 @@ unicodeStringLiteral: UnicodeStringLiteral+; /** * Number literals can be decimal or hexadecimal numbers with an optional unit. */ -numberLiteral: (DecimalNumber | HexNumber) NumberUnit?; +numberLiteral: DecimalNumber | HexNumber; + /** * A curly-braced block of statements. Opens its own scope. */ @@ -476,7 +511,13 @@ revertStatement: Revert expression callArgumentList Semicolon; * The contents of an inline assembly block use a separate scanner/lexer, i.e. the set of keywords and * allowed identifiers is different inside an inline assembly block. */ -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)*; @@ -497,7 +538,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; /** * Only elementary types or user defined types are viable as mapping keys. */ @@ -564,7 +605,7 @@ yulFunctionDefinition: * While only identifiers without dots can be declared within inline assembly, * paths containing dots can refer to declarations outside the inline assembly block. */ -yulPath: YulIdentifier (YulPeriod YulIdentifier)*; +yulPath: YulIdentifier (YulPeriod (YulIdentifier | YulEVMBuiltin))*; /** * A call to a function with return values can only occur as right-hand side of an assignment or * a variable declaration. diff --git a/docs/index.rst b/docs/index.rst index 7ac655f56a..f1cc55e317 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -2,6 +2,7 @@ ======== سالیدیتی یک زبان شیء گرا و سطح بالا برای پیاده سازی قراردادهای هوشمند می‌باشد. قرارداد‌های هوشمند، برنامه‌هایی هستند که رفتار حساب‌ها در داخل حالت اتریوم را کنترل می‌کنند. +<<<<<<< HEAD سالیدیتی یک `زبان آکلادی `_ می‌باشد که از زبان‌هایی مانند سی پلاس پلاس ، پایتون و جاوا اسکریپت تأثیر گرفته و برای هدف قراردادن EVM یا ماشینِ مجازیِ اتریوم طراحی شده‌است. @@ -16,16 +17,53 @@ .. warning:: سالیدیتی به تازگی نسخه 0.8.X را منتشر کرده که تغییرات جدید را معرفی می‌کند. حتماً :doc:`لیست کامل <080-breaking-changes>` را مطالعه کنید. +======= +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 ایده‌های بهبود سالیدیتی یا این مستند همیشه مورد استقبال قرار میگیرد، برای جزئیات بیشتر :doc:`راهنمای همکاری ` را مطالعه کنید. +<<<<<<< HEAD شروع +======= +.. Hint:: + + 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. + + +Getting Started +>>>>>>> english/develop --------------- **1. درک مبانی قراردادهای هوشمند** +<<<<<<< HEAD اگر با مفهوم قراردادهای هوشمند آشنا هستید، به شما توصیه می‌کنیم که با جستجوی بخش "معرفی قراردادهای هوشمند" شروع به کار کنید، که شامل موارد زیر است: +======= +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:`یک مثال ساده از قرارداد هوشمند ` که با سالیدیتی نوشته شده‌است. * :ref:`مبانی بلاکچین `. @@ -43,25 +81,52 @@ .. hint:: +<<<<<<< HEAD +======= + 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. +>>>>>>> english/develop می‌توانید نمونه‌های کد را مستقیماً در مرورگر خود با `ویرایشگر متن ریمیکس `_ امتحان کنید. ریمیکس یک ویرایشگر متن مبتنی بر مرورگر وب است که به شما امکان می‌دهد، بدون نیاز به نصب سالیدیتی به صورت محلی، قراردادهای هوشمند سالیدیتی را بنویسید، دیپلوی و مدیریت کنید. .. warning:: +<<<<<<< HEAD نرم افزار به عنوان نوشته‌ی انسان، می‌تواند باگ داشته باشد. هنگام نوشتن قراردادهای هوشمند خود، باید بهترین شیوه‌های توسعه نرم افزار را دنبال کنید. شیوه‌های توسعه نرم افزار شامل بازبینی ، آزمایش ، حسابرسی و اثبات صحتِ کد می‌باشد. کاربران قرارداد هوشمند گاهی اوقات به خودِ کد نسبت به نویسندگان آن‌ها اطمینان بیشتری دارند. بلاکچین‌ها و قراردادهای هوشمند مسائل منحصر به فرد خود را دارند، که باید مراقب آنها باشید. بنابراین قبل از کار بر روی تولید کد، حتماً قسمت :ref:`ملاحظات امنیتی ` را مطالعه کنید. +======= + 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. یادگیری بیشتر** +<<<<<<< HEAD اگر می‌خواهید در مورد ساخت برنامه‌های غیرمتمرکز در اتریوم اطلاعات بیشتری کسب کنید، `منابع توسعه دهنده اتریوم `_ می‌توانند به شما در تهیه مستندِ عمومیِ بیشتر در مورد اتریوم و انتخاب گسترده‌ای از آموزش‌ها، ابزارها و چارچوب‌های توسعه کمک کنند. اگر سؤالی دارید، می‌توانید جواب‌ها را جستجو کنید یا از طریق `Ethereum StackExchange `_, یا `کانال 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: ترجمه‌ها ------------ +<<<<<<< HEAD داوطلبان جامعه سالیدیتی به ترجمه این مستندات به چندین زبان کمک می‌کنند. این‌ مستندات سطوح مختلفی از کامل و بروز بودن را دارند. نسخه انگلیسی به عنوان مرجع می‌باشد. .. note:: @@ -79,6 +144,30 @@ * `چینی `_ (در حال انجام) * `اسپانیایی `_ * `ترکی `_ (جزئی) +======= +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 فهرست ======== @@ -90,8 +179,8 @@ :caption: مبانی introduction-to-smart-contracts.rst - installing-solidity.rst solidity-by-example.rst + installing-solidity.rst .. toctree:: :maxdepth: 2 @@ -113,6 +202,7 @@ using-the-compiler.rst analysing-compilation-output.rst + ir-breaking-changes.rst .. toctree:: :maxdepth: 2 @@ -129,21 +219,31 @@ .. toctree:: :maxdepth: 2 - :caption: Additional Material + :caption: Advisory content + 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 e0d27a193c..ff0952f544 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -9,16 +9,47 @@ نسخه بندی ========== +<<<<<<< HEAD نسخه‌های سالیدیتی از `نسخه بندی سمننتیکی `_ پیروی می‌کنند و علاوه بر این نسخه‌ها، **نسخه‌های توسعه شبانه** نیز در دسترس هستند. کارکردن نسخه‌های نسخه شبانه تضمین نمی‌شود و علی‌رغم همه تلاش‌ها ممکن است تغییرات غیرمستند و یا تغییرات جدید را شامل شوند. توصیه می‌کنیم از آخرین نسخه استفاده کنید. بسته‌های نصبی زیر از آخرین نسخه استفاده خواهند کرد. +======= +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 ریمیکس ===== *ریمیکس را برای قراردادهای کوچک و برای یادگیری سریع سالیدیتی توصیه می‌کنیم. * +<<<<<<< HEAD می‌توانید به صورت آنلاین به `ریمیکس `_ دسترسی داشته باشید و نیازی به نصب هیچ چیزی ندارید. اگر می‌خواهید بدون اتصال به اینترنت از آن استفاده کنید، به https://github.com/ethereum/remix-live/tree/gh-pages مراجعه کنید و فایل ``zip.`` را همانطور که در آن صفحه توضیح داده شده بارگیری کنید. ریمیکس همچنین یک گزینه مناسب برای تست نسخه شبانه بدون نصب چندین نسخه سالیدیتی است. این صفحه گزینه‌های بیشتر برای نصب نرم افزار کامپایلر سالیدیتی روی رایانه شما با خط فرمان را توضیح می‌دهد. اگر در حال کار بر روی قرارداد بزرگتر هستید یا به گزینه‌های کامپایل بیشتری نیاز دارید، یک کامپایلر خط فرمان انتخاب کنید. +======= +`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: @@ -27,7 +58,14 @@ npm / Node.js برای نصب راحت و قابل حمل ``solcjs`` یک کامپایلر سالیدیتی، از ``npm`` استفاده کنید. برنامه `solcjs` دارای ویژگی‌های کمتری نسبت به راه‌های دسترسی به کامپایلر است که در این صفحه توضیح داده شده است. مستندات :ref:`commandline-compiler` فرض می‌کند که از کامپایلر کامل ``solc`` استفاده می‌کنید. استفاده از ``solcjs`` در `مخزن `_ خود ثبت شده است. +<<<<<<< HEAD توجه داشته باشید: پروژه solc-js از C++ `solc` با استفاده از Emscripten مشتق گرفته شده‌است، به این معنی که هر دو از کد منبع کامپایلر یکسانی استفاده می‌کنند. `solc-js` را می‌توان مستقیماً در پروژه‌های جاوا اسکریپت (مانند ریمیکس) استفاده کرد. لطفاً به مخزن solc-js برای مشاهده دستورات مراجعه کنید. +======= +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 @@ -35,35 +73,60 @@ npm / Node.js .. note:: +<<<<<<< HEAD خط فرمان اجرایی ``solcjs`` نام دارد. گزینه‌های خط فرمان ``solcjs`` با ``solc`` سازگار نیستند و ابزارها (مانند ``geth``) انتظار دارند رفتار ``solc`` با ``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 داکر ====== +<<<<<<< HEAD تصاویر داکر از نسخه‌های سالیدیتی با استفاده از تصویر ``solc`` از سازمان ``ethereum`` در دسترس است. از برچسب ``stable`` برای آخرین نسخه منتشر شده و nightly برای تغییرات احتمالی ناپایدار در شاخه‌ی نسخه استفاده می‌کند. تصویر داکر کامپایلر اجرایی را اجرا می‌کند، بنابراین می‌توانید تمام آرگومان‌های کامپایلر را به آن منتقل کنید. به عنوان مثال، دستور زیر نسخه پایدار تصویر ``solc`` را دریافت می‌کند (اگر قبلاً آن را ندارید)، و آن را در یک محفظه جدید اجرا می‌کند و آرگومان ``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 همچنین می‌توانید نسخه‌هایِ توسعهِ منتشر شده را با برچسب مشخص کنید، به عنوان مثال، برای نسخه 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 برای استفاده از تصویر داکر برای کامپایل فایل‌های سالیدیتی در دستگاه میزبان، یک پوشه محلی برای ورودی و خروجی نصب کرده و قرارداد کامپایل را مشخص کنید. برای مثال: +======= +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 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 +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 `). @@ -93,7 +156,24 @@ self-contained (i.e. it does not refer to any external files that would have to sudo apt-get update sudo apt-get install solc +<<<<<<< HEAD ما همچنین یک `بسته اسنپ `_ را منتشر می‌کنیم که در `توزیع‌های پشتیبانی شده لینوکس `_ قابل نصب است. برای نصب آخرین نسخه پایدار 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 @@ -109,6 +189,7 @@ self-contained (i.e. it does not refer to any external files that would have to اسنپ ``solc`` از سختگیری شدید استفاده می‌کند. این حالت امن‌ترین حالت برای بسته‌های فوری است اما با محدودیت‌هایی همراه است، مثلاً شما فقط به فایل‌های موجود در دایرکتوری‌های ``home/`` و ``media/`` دسترسی خواهید داشت. برای کسب اطلاعات بیشتر، به `Demystifying Snap Confinement `_. مراجعه کنید. +<<<<<<< HEAD آرک لینوکس همچنین دارای بسته‌هایی است، البته محدود به آخرین نسخه توسعه می‌باشد: .. code-block:: bash @@ -120,6 +201,8 @@ self-contained (i.e. it does not refer to any external files that would have to .. code-block:: bash emerge dev-lang/solidity +======= +>>>>>>> english/develop بسته‌های مک‌او اس ============== @@ -162,15 +245,37 @@ self-contained (i.e. it does not refer to any external files that would have to مخزن نه تنها راهی سریع و آسان برای کاربران نهایی است تا باینری‌ها را برای استفاده در خارج از جعبه آماده کنند، بلکه به معنای مناسب بودن با ابزارهای ثالث است: +<<<<<<< HEAD - محتوا در https://binaries.soliditylang.org قرارداده شده‌است که در آن می‌توان به راحتی از طریق HTTPS بدون احراز هویت، محدودیت سرعت یا نیاز به استفاده از git بارگیری کرد. - محتوا با هدرهای صحیح `نوع محتوا` و با پیکربندی CORS ارائه می‌شود تا بتواند مستقیماً توسط ابزارهایی که در مرورگر اجرا می‌شوند بارگیری شود. - فایل‌های باینری نیازی به نصب یا باز کردن بسته بندی ندارند (به استثنای نسخه‌های قدیمی ویندوز که همراه با DLLهای ضروری هستند). - ما برای سطح بالایی از سازگاری با گذشته تلاش می‌کنیم. فایل‌ها، پس از اضافه شدن، بدون ارائه پیوند تغییر مسیر در مکان قدیمی حذف یا منتقل نمی‌شوند. همچنین هرگز در محل خود تغییر داده نمی‌شوند و همیشه باید با چک‌سام اصلی مطابقت داشته باشند. تنها استثناء‌ می‌تواند فایل‌های شکسته یا غیرقابل استفاده باشد که اگر به همین صورت باقی بمانند، می‌توانند بیشتر از فایده باعث آسیب شوند. - • فایل‌ها از طریق HTTP و HTTPS ارائه می‌شوند. تا زمانیکه لیست فایل‌ها را به صورت ایمن (از طریق git ،HTTPS ، IPFS یا به صورت محلی ذخیره کردید) به دست آوردید. و پس از بارگیری، فایل‌های هش باینری را تأیید کنید. لازم نیست از HTTPS برای خود فایل‌های باینری استفاده کنید. +======= +- 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 همین فایل‌های باینری در بیشتر موارد در `Solidity release page on Github`_ در گیت‌هاب موجود است. تفاوت در این است که ما به طور کلی نسخه‌های قدیمی را در صفحه انتشار گیتهاب به روز نمی‌کنیم. این بدان معناست که در صورت تغییر شرایط نامگذاری، نام آن‌ها را تغییر نمی‌دهیم و برای پلتفرم‌هایی که در زمان انتشار پشتیبانی نمی‌شوند، نسخه‌‌هایی اضافه نمی‌کنیم. این امر فقط در ``solc-bin`` اتفاق می‌افتد. +<<<<<<< HEAD مخزن ``solc-bin`` شامل چندین دایرکتوری سطح بالا است که هر یک نمایانگر یک پلتفرم واحد می‌باشد. هر یک شامل یک فایل ``list.json`` است که فایل‌های باینری موجود را فهرست می‌کند. برای مثال در ``emscripten-wasm32/list.json`` اطلاعات زیر را در مورد نسخه 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 @@ -189,6 +294,7 @@ self-contained (i.e. it does not refer to any external files that would have to این بدان معناست که: +<<<<<<< HEAD - شما می‌توانید باینری را در همان فهرست با نام `solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js `_ پیدا کنید. توجه داشته باشید که فایل ممکن است یک پیوند باشد و اگر از گیت برای بارگیری آن استفاده نمی‌کنید یا سیستم فایل شما از پیوند‌ها پشتیبانی نمی‌کند، باید خودتان آن را حل کنید. - باینری نیز در https://binaries.soliditylang.org/emscripten-wasm32/solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js قرار داده شده‌است. در این حالت گیت ضروری نمی‌باشد. و پیوندها، یا با ارائه یک کپی از فایل یا با بازگرداندن یک مسیر HTTP به طور شفاف حل می‌شوند. - فایل همچنین در IPFS در `QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS`_ موجود است. @@ -197,6 +303,23 @@ self-contained (i.e. it does not refer to any external files that would have to from ethereumjs-util`_ در جاوا اسکریپت ارائه شده‌است. - همچنین می‌توانید یکپارچگی باینری را با مقایسه هش sha256 آن با ``0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2`` تأیید کنید. +======= +- You can find the binary in the same directory under the name + `solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js `_. + 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 + ``0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2``. +>>>>>>> english/develop .. warning:: @@ -227,8 +350,12 @@ self-contained (i.e. it does not refer to any external files that would have to نسخه از منبع ==================== +<<<<<<< HEAD پیش نیازهای – همه‌ی سیستم عامل‌ها +======= +Prerequisites - All Operating Systems +>>>>>>> english/develop ------------------------------------- موارد زیر وابستگی‌ها برای همه نسخه‌های سالیدیتی می‌باشند: @@ -236,14 +363,15 @@ self-contained (i.e. it does not refer to any external files that would have to +-----------------------------------+-------------------------------------------------------+ | Software | Notes | +===================================+=======================================================+ -| `CMake`_ (version 3.13+) | Cross-platform build file generator. | +| `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+, Optional) | For use with SMT checker. | +| `z3`_ (version 4.8.16+, Optional) | For use with SMT checker. | +-----------------------------------+-------------------------------------------------------+ | `cvc4`_ (Optional) | For use with SMT checker. | +-----------------------------------+-------------------------------------------------------+ @@ -255,12 +383,18 @@ self-contained (i.e. it does not refer to any external files that would have to .. _z3: https://github.com/Z3Prover/z3 .. note:: +<<<<<<< HEAD نسخه‌های سالیدیتی قبل از 0.5.10 نمی‌توانند به درستی با نسخه‌های +Boost 1.70 لینک شوند. یک راه حل ممکن این است که قبل از اجرای دستور cmake برای پیکربندی سالیدیتی، نام ``Boost install path>/lib/cmake/Boost-1.70.0>`` را به طور موقت تغییر نام دهید. با شروع از 0.5.10 لینک کردن برخلاف +Boost 1.70 باید بدون دخالت دستی کار کند. +======= + 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 .. note:: @@ -273,7 +407,22 @@ self-contained (i.e. it does not refer to any external files that would have to If you do this, however, please remember to pass the ``--no-smt`` option to ``scripts/tests.sh`` to skip the SMT tests. +<<<<<<< HEAD حداقل نسخه‌های کامپایلر +======= +.. 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 ^^^^^^^^^^^^^^^^^^^^^^^^^ کامپایلرهای ++ C زیر و حداقل نسخه‌های آنها می‌توانند پایگاه کد سالیدیتی را ایجاد کنند: @@ -287,9 +436,20 @@ self-contained (i.e. it does not refer to any external files that would have to پیش نیازها - مک‌او اس --------------------- +<<<<<<< HEAD برای نسخه‌های مک‌او اس، مطمئن شوید که آخرین نسخه `Xcode `_ را نصب کرده‌اید. این شامل کامپایلر `Clang C++ `_ ، `Xcode IDE `_ و سایر ابزارهای توسعه اپل می‌باشد که برای ایجاد برنامه‌های ++ C در OS X مورد نیاز است. اگر برای اولین بار Xcode را نصب می‌کنید یا نسخه جدیدی را نصب کرده‌اید، باید قبل از توسعه، با لایسنس موافقت کنید تا بتوانید با خط فرمان، توسعه‌ها را انجام دهید: +======= +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 @@ -327,8 +487,9 @@ self-contained (i.e. it does not refer to any external files that would have to * پشتیبانی از C ++/CLI .. _Visual Studio 2019: https://www.visualstudio.com/vs/ -.. _Visual Studio 2019 Build Tools: 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 +<<<<<<< HEAD اسکریپت کمکی وابستگی‌ها -------------------------- @@ -339,11 +500,18 @@ self-contained (i.e. it does not refer to any external files that would have to ./scripts/install_deps.sh یا در ویندوز: +======= +We have a helper script which you can use to install all required external dependencies: +>>>>>>> english/develop .. code-block:: bat scripts\install_deps.ps1 +<<<<<<< HEAD +======= +This will install ``boost`` and ``cmake`` to the ``deps`` subdirectory. +>>>>>>> english/develop توجه داشته باشید که دستور دوم ``boost`` و ``cmake`` را در زیر شاخه ``deps`` نصب می‌کند، در حالی که دستور قبلی سعی می‌کند وابستگی‌ها را به صورت جهانی نصب کند. @@ -358,14 +526,26 @@ self-contained (i.e. it does not refer to any external files that would have to git clone --recursive https://github.com/ethereum/solidity.git cd solidity +<<<<<<< HEAD اگر می‌خواهید به نسخه سالیدیتی کمک کنید، باید سالیدیتی را فورک کنید و فورک شخصی خود را به عنوان ریموت دوم اضافه کنید: +======= +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 این روش منجر به نسخه پیش انتشار می‌شود که به عنوان مثال یک فَلگ در هر کد بایتی که توسط چنین کامپایلری تولید می‌شود، تنظیم می‌شود. اگر می‌خواهید کامپایلر سالیدیتی منتشر شده را دوباره توسعه دهید، لطفاً از tarball منبع در صفحه انتشار گیتهاب استفاده کنید: +======= + 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 (نه "کد منبع" ارائه شده توسط گیتهاب). @@ -430,7 +610,12 @@ self-contained (i.e. it does not refer to any external files that would have to حل کننده‌های SMT ----------- +<<<<<<< HEAD سالیدیتی را می‌توان در کنار حل کننده‌های SMT ایجاد کرد و در صورت یافتن آنها در سیستم به طور پیش فرض این کار را انجام می‌دهد. هر حل کننده را می‌توان با گزینه `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 *توجه: در برخی موارد ، این نیز می تواند یک راه حل احتمالی برای خرابی نسخه باشد.* @@ -460,6 +645,11 @@ self-contained (i.e. it does not refer to any external files that would have to - کامیت در قالب ``commit.GITHASH`` - پلتفرم، که دارای تعداد دلخواه موارد است، حاوی جزئیات مربوط به پلتفرم و کامپایلر +<<<<<<< HEAD +======= +These parts are combined as required by SemVer, where the Solidity pre-release tag equals to the SemVer pre-release +and the Solidity commit and platform combined make up the SemVer build metadata. +>>>>>>> english/develop اگر تغییرات محلی وجود داشته باشد، کامیت‌ها با ``mod.`` پسوند داده می‌شود. @@ -475,7 +665,14 @@ self-contained (i.e. it does not refer to any external files that would have to اطلاعات مهم در مورد نسخه بندی ====================================== +<<<<<<< HEAD پس از انتشار، سطح نسخه پَچ بامپ ‌شده است، زیرا ما فرض می‌کنیم که فقط تغییرات سطح پَچ دنبال می‌شود. وقتی تغییرات ادغام می‌شوند، نسخه باید با توجه به semver و شدت تغییرات بامپ شود. سرانجام، همیشه نسخه‌ای از نسخه فعلی شبانه منتشر می‌شود، اما بدون تعیین ``prerelease`` . +======= +After a release is made, the patch version level is bumped, because we assume that only +patch level changes follow. When changes are merged, the version should be bumped according +to SemVer and the severity of the change. Finally, a release is always made with the version +of the current nightly build, but without the ``prerelease`` specifier. +>>>>>>> english/develop مثال: @@ -490,4 +687,14 @@ self-contained (i.e. it does not refer to any external files that would have to این رفتار با :ref:`نسخه پراگما ` به خوبی کار می‌کند. +<<<<<<< HEAD + +======= +1. The 0.4.0 release is made. +2. The nightly build has a version of 0.4.1 from now on. +3. Non-breaking changes are introduced --> no change in version. +4. A breaking change is introduced --> version is bumped to 0.5.0. +5. The 0.5.0 release is made. +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 b1b89a6a3c..7afcfc2ac5 100644 --- a/docs/internals/layout_in_storage.rst +++ b/docs/internals/layout_in_storage.rst @@ -56,7 +56,8 @@ as individual values. 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. + 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. Mappings and Dynamic Arrays @@ -90,7 +91,7 @@ The value corresponding to a mapping key ``k`` is located at ``keccak256(h(k) . where ``.`` is concatenation and ``h`` is a function that is applied to the key depending on its type: - 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`` computes the ``keccak256`` hash of the unpadded data. +- for strings and byte arrays, ``h(k)`` is just the unpadded data. If the mapping value is a non-value type, the computed slot marks the start of the data. If the value is of struct type, @@ -139,8 +140,7 @@ by checking if the lowest bit is set: short (not set) and long (set). .. note:: Handling invalidly encoded slots is currently not supported but may be added in the future. - If you are compiling via the experimental IR-based compiler pipeline, reading an invalidly encoded - slot results in a ``Panic(0x22)`` error. + If you are compiling via IR, reading an invalidly encoded slot results in a ``Panic(0x22)`` error. JSON Output =========== @@ -153,7 +153,7 @@ the :ref:`standard JSON interface `. The output is a JSON object element has the following form: -.. code:: +.. code-block:: json { @@ -181,7 +181,7 @@ The given ``type``, in this case ``t_uint256`` represents an element in ``types``, which has the form: -.. code:: +.. code-block:: json { "encoding": "inplace", @@ -208,7 +208,7 @@ of types), arrays have its ``base`` type, and structs list their ``members`` in the same format as the top-level ``storage`` (see :ref:`above `). -.. note :: +.. note:: 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. @@ -232,13 +232,13 @@ value and reference types, types that are encoded packed, and nested types. 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 0dca1b183c..9622578355 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -5,8 +5,16 @@ بهینه ساز (The Optimizer) ************* +<<<<<<< HEAD کامپایلر سالیدیتی از دو ماژول بهینه ساز مختلف استفاده می‌کند: بهینه ساز « old» که در سطح آپکد عمل می‌کند و بهینه ساز « new» که بر روی کد 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 بهینه ساز مبتنی بر آپکد، مجموعه ای از `قوانین ساده سازی `_ را برای آپکدها اعمال می‌کند. همچنین مجموعه کدهای مساوی را ترکیب کرده و کدهای استفاده نشده را حذف می‌کند. @@ -18,6 +26,7 @@ به طور مشابه، اگر تابعی بدون اثرات جانبی باشد و نتیجه آن در صفر ضرب شود، می‌توانید فراخوانی تابع را به طور کامل حذف کنید. +<<<<<<< HEAD در حال حاضر، پارامتر ``optimize--`` بهینه‌ساز مبتنی بر آپکد را برای بایت‌کد تولید شده و بهینه‌ساز Yul را برای کد Yul تولید شده به صورت داخلی فعال می‌کند، به عنوان مثال برای ABI coder v2. می‌توان از ``solc --ir-optimized --optimize`` برای تولید یک Yul IR آزمایشی بهینه برای سورس سالیدیتی استفاده @@ -25,6 +34,36 @@ کرد. در زیر می‌توانید جزئیات بیشتری در مورد ماژول‌های بهینه ساز و مراحل بهینه سازی آنها بیابید. +======= +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 مزایای بهینه سازی کد سالیدیتی @@ -256,6 +295,7 @@ Simple Inlining تمام اجزای ماژول بهینه ساز مبتنی بر Yul در زیر توضیح داده شده است. مراحل تبدیل زیر اجزای اصلی هستند: +<<<<<<< HEAD - تبدیل SSA - حذف کننده Subexpression مشترک - ساده کننده بیان @@ -263,58 +303,97 @@ Simple Inlining - Inliner کامل مراحل بهینه ساز +======= +.. _optimizer-steps: + +Optimizer Steps +>>>>>>> english/develop --------------- این لیستی از تمام مراحلی است که بهینه ساز مبتنی بر Yul بر اساس حروف الفبا مرتب شده است. در زیر می توانید اطلاعات بیشتری در مورد تک تک مراحل و ترتیب آنها بیابید. -- :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:`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: انتخاب بهینه سازی ها ----------------------- +<<<<<<< HEAD به طور پیش فرض بهینه ساز دنباله از پیش تعریف شده مراحل بهینه سازی خود را برای مجموعه تولید شده اعمال می کند. شما می توانید این دنباله را override کنید و با استفاده از گزینه ``--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 دنباله داخل ``[...]`` چندین بار در یک حلقه اعمال می شود تا زمانی که کد Yul بدون تغییر باقی بماند یا تا زمانی که به حداکثر تعداد دور (در حال حاضر 12) برسد. اختصارات موجود در اسناد یا همان بخش `داکیومنت بهینه ساز Yul `_ لیست شده است. +======= +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 پیش پردازش(Preprocessing) ------------- @@ -420,11 +499,9 @@ ForLoopInitRewriter .. code-block:: text - { - Init... - for {} C { Post... } { - Body... - } + Init... + for {} C { Post... } { + Body... } این کار بقیه فرآیند بهینه‌سازی را آسان می‌کند، زیرا می‌توانیم قوانین محدوده‌بندی پیچیده بلوک اولیه‌ @@ -519,7 +596,7 @@ ExpressionSplitter The expression splitter turns expressions like ``add(mload(0x123), mul(mload(0x456), 0x20))`` into a sequence of declarations of unique variables that are assigned sub-expressions -of that expression so that each function call has only variables or literals +of that expression so that each function call has only variables as arguments. موارد فوق تبدیل به @@ -528,15 +605,24 @@ as arguments. .. code-block:: yul { - let _1 := mload(0x123) - let _2 := mul(_1, 0x20) - let _3 := mload(0x456) - let z := add(_3, _2) + let _1 := 0x20 + let _2 := 0x456 + let _3 := mload(_2) + let _4 := mul(_3, _1) + let _5 := 0x123 + let _6 := mload(_5) + let z := add(_6, _4) } توجه داشته باشید که این تبدیل ترتیب آپکدها یا فراخوانی تابع را تغییر نمی دهد. +<<<<<<< HEAD +======= +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 برای شرط تکرار حلقه اعمال نمی شود، زیرا جریان کنترل حلقه اجازه این "طرح بندی" عبارات داخلی را در همه موارد نمی دهد. ما می‌توانیم با اعمال :ref:`for-loop-condition-into-body` برای انتقال شرط تکرار @@ -679,7 +765,7 @@ mapping هستند یا حالت یکسانی دارند، بدون تغییر - "unused", "undecided" -> "undecided" - "unused", "used" -> "used" -- "undecided, "used" -> "used" +- "undecided", "used" -> "used" برای حلقه‌های for، شرط، بدنه و پس‌پارت(post-part) دو بار بازدید می‌شوند و جریان کنترل اتصال در شرایط را در نظر می‌گیرند. به عبارت دیگر، ما سه مسیر جریان کنترلی ایجاد می کنیم: صفر اجرای حلقه، @@ -793,11 +879,20 @@ SSA باشد، مقادیر متغیرها برای مدت زمان بیشتری .. _expression-simplifier: +<<<<<<< HEAD ساده کننده بیان (Expression Simplifier) ^^^^^^^^^^^^^^^^^^^^^ Simplifier Expression از Dataflow Analyzer استفاده می کند و از لیستی از تبدیل های معادل در عباراتی مانند ``X + 0 -> X`` برای ساده کردن کد استفاده می کند. +======= +ExpressionSimplifier +^^^^^^^^^^^^^^^^^^^^ + +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 سعی می کند الگوهایی مانند ``X + 0`` را در هر زیر عبارت مطابقت دهد. در طول رویه تطبیق، متغیرها را به @@ -835,6 +930,7 @@ Works best if the code is in SSA form. Prerequisite: Disambiguator, ForLoopInitRewriter. +<<<<<<< HEAD .. _reasoning-based-simplifier: ReasoningBasedSimplifier @@ -857,6 +953,9 @@ Disambiguator، SSATtransform. بیانیه-مقیاس ساده سازی +======= +Statement-Scale Simplifications +>>>>>>> english/develop ------------------------------- .. _circular-reference-pruner: @@ -953,8 +1052,13 @@ DeadCodeEliminator این مرحله بهینه سازی کدهای غیرقابل دسترسی را حذف می کند. +<<<<<<< HEAD کد غیرقابل دسترسی به هر کدی در یک بلوک گفته می‌شود که قبل از آن ترک، بازگشت، نامعتبر، شکست، ادامه، خود تخریب یا بازگردانی وجود دارد. +======= +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 @@ -970,6 +1074,22 @@ DeadCodeEliminator +.. _equal-store-eliminator: + +EqualStoreEliminator +^^^^^^^^^^^^^^^^^^^^ + +This steps removes ``mstore(k, v)`` and ``sstore(k, v)`` calls if +there was a previous call to ``mstore(k, v)`` / ``sstore(k, v)``, +no other store in between and the values of ``k`` and ``v`` did not change. + +This simple step is effective if run after the SSA transform and the +Common Subexpression Eliminator, because SSA will make sure that the variables +will not change and the Common Subexpression Eliminator re-uses exactly the same +variable if the value is known to be the same. + +Prerequisites: Disambiguator, ForLoopInitRewriter + .. _unused-pruner: UnusedPruner @@ -1004,19 +1124,28 @@ UnusedPruner BlockFlattener ^^^^^^^^^^^^^^ +<<<<<<< HEAD این مرحله بلوک های تودرتو را با درج عبارت در بلوک داخلی در محل مناسب بلوک بیرونی حذف می کند. به FunctionGrouper بستگی دارد و بیرونی ترین بلوک را برای حفظ فرم تولید شده توسط FunctionGrouper صاف نمی کند. +======= +This stage eliminates nested blocks by inserting the statement in the +inner block at the appropriate place in the outer block. It depends on the +FunctionGrouper and does not flatten the outermost block to keep the form +produced by the FunctionGrouper. +>>>>>>> english/develop .. code-block:: yul { - let x := 2 { - let y := 3 - mstore(x, y) + let x := 2 + { + let y := 3 + mstore(x, y) + } } } تبدیل می شود به @@ -1025,9 +1154,11 @@ FunctionGrouper صاف نمی کند. .. code-block:: yul { - let x := 2 - let y := 3 - mstore(x, y) + { + let x := 2 + let y := 3 + mstore(x, y) + } } تا زمانی که کد مبهم باشد، این مشکلی ایجاد نمی کند زیرا دامنه متغیرها فقط می تواند رشد کند. @@ -1108,6 +1239,52 @@ UnusedFunctionParameterPruner تا تابع را بازنویسی کنیم. +.. 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 @@ -1154,14 +1331,32 @@ ExpressionInliner FullInliner ^^^^^^^^^^^ +<<<<<<< HEAD Full Inliner جایگزین تماس های خاصی از عملکردهای خاص توسط بدنه عملکرد می شود که در اکثر موارد خیلی مفید نیست، زیرا فقط اندازه کد را افزایش می دهد اما فایده ای ندارد. علاوه بر این، کد معمولاً بسیار گران است و ما اغلب ترجیح می‌دهیم کد کوتاه‌تری داشته باشیم تا کد کارآمدتر. اگرچه در موارد مشابه، درون‌سازی یک تابع می‌تواند اثرات مثبتی بر مراحل بهینه‌ساز بعدی داشته باشد. این در صورتی است که مثلا یکی از آرگومان های تابع ثابت باشد. +======= +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. + +During inlining, a heuristic is used to tell if the function call +should be inlined or not. +The current heuristic does not inline into "large" functions unless +the called function is tiny. Functions that are only used once +are inlined, as well as medium-sized functions, while function +calls with constant arguments allow slightly larger functions. +>>>>>>> english/develop +<<<<<<< HEAD در طول Inline، از یک اکتشافی برای تشخیص اینکه آیا فراخوانی تابع باید خطی باشد یا نه استفاده می‌شود. اکتشافی فعلی در توابع "بزرگ" قرار نمی گیرد مگر اینکه تابع فراخوانی شده کوچک باشد. توابعی @@ -1180,6 +1375,14 @@ Full Inliner جایگزین تماس های خاصی از عملکردهای خ پاک کردن(Cleanup) +======= +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 ------- پاکسازی در پایان اجرای بهینه ساز انجام می شود. سعی می کند عبارات تقسیم شده را دوباره به عبارات عمیق تو در تو ترکیب کند و همچنین "کامپایل پذیری" را برای ماشین ها با حذف متغیرها تا حد امکان @@ -1220,11 +1423,18 @@ SSAReverser این یک گام کوچک است که در صورت ترکیب شدن با Common Subexpression Eliminator و Unused Pruner به معکوس کردن اثرات تبدیل SSA کمک می کند. +<<<<<<< HEAD فرم SSA که تولید می کنیم برای تولید کد در EVM و WebAssembly به طور یکسان مضر است زیرا متغیرهای محلی زیادی تولید می کند. بهتر است فقط از متغیرهای موجود با انتساب به جای اعلان متغیرهای تازه استفاده مجدد شود. تبدیل SSA بازنویسی می کند. +======= +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 .. code-block:: yul @@ -1340,7 +1550,10 @@ ForLoopConditionOutOfBody LiteralRematerialiser باید قبل از این مرحله اجرا شود. +Codegen-Based Optimizer Module +============================== +<<<<<<< HEAD وب اسمبلی خاص -------------------- @@ -1352,3 +1565,61 @@ LiteralRematerialiser باید قبل از این مرحله اجرا شود. بستگی به Function Grouper دارد. +======= +Currently, the codegen-based optimizer module provides two optimizations. + +The first one, available in the legacy code generator, moves literals to the right side of +commutative binary operators, which helps exploit their associativity. + +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 f88c7be0de..cc1e6945a2 100644 --- a/docs/internals/source_mappings.rst +++ b/docs/internals/source_mappings.rst @@ -29,7 +29,14 @@ Mappingهای سورس +<<<<<<< HEAD .. note :: +======= +.. 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 در مورد دستورالعمل‌هایی که با هیچ سورس فایل خاصی مرتبط نیستند، سورس mapping یک مشخص کننده عدد اینتیجر ``1-`` را اختصاص می‌دهد. این ممکن است برای بخش‌های بایت‌کد ناشی از دستورات diff --git a/docs/internals/variable_cleanup.rst b/docs/internals/variable_cleanup.rst index 7e4c61d725..797862ade3 100644 --- a/docs/internals/variable_cleanup.rst +++ b/docs/internals/variable_cleanup.rst @@ -4,12 +4,25 @@ پاکسازی متغیرها ********************* +<<<<<<< HEAD وقتی value کوتاهتر از 256 بیت است، در برخی موارد بیت‌های باقی مانده باید پاک شوند. کامپایلر سالیدیتی برای پاکسازی این بیت‌های باقی‌مانده قبل از هر عملیاتی طراحی شده است که ممکن است توسط پتانسیل garbage در بیت‌های باقی‌مانده تأثیر منفی بگذارد. به عنوان مثال، قبل از نوشتن یک value در مِمُوری، بیت‌های باقیمانده باید پاک شوند، زیرا محتویات مِمُوری را می‌توان برای محاسبه هش استفاده کرد یا به عنوان داده یک کال مسیج (message call) ارسال کرد. به طور مشابه، قبل از ذخیره یک value در storage، بیت‌های باقی مانده باید پاک شوند زیرا در غیر این صورت می‌توان garbled value را مشاهده کرد. +======= +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 توجه داشته باشید که دسترسی از طریق اسمبلی درون خطی چنین عملیاتی در نظر گرفته نمی‌شود: اگر از اسمبلی درون خطی برای دسترسی به متغیرهای سالیدیتی کوتاهتر از ۲۵۶ بیت استفاده می‌کنید، کامپایلر @@ -23,24 +36,86 @@ garbage در بیت‌های باقی‌مانده تأثیر منفی بگذا تایپ‌های مختلف قوانین متفاوتی برای پاکسازی مقادیر نامعتبر دارند: +<<<<<<< HEAD +======= +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. +>>>>>>> english/develop -+---------------+---------------+-------------------+ -|Type |Valid Values |Invalid Values Mean| -+===============+===============+===================+ -|enum of n |0 until n - 1 |exception | -|members | | | -+---------------+---------------+-------------------+ -|bool |0 or 1 |1 | -+---------------+---------------+-------------------+ -|signed integers|sign-extended |currently silently | -| |word |wraps; in the | -| | |future exceptions | -| | |will be thrown | -| | | | -| | | | -+---------------+---------------+-------------------+ -|unsigned |higher bits |currently silently | -|integers |zeroed |wraps; in the | -| | |future exceptions | -| | |will be thrown | -+---------------+---------------+-------------------+ ++---------------+---------------+-------------------------+ +|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 diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index b691db10de..5085abee7f 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -8,7 +8,13 @@ یک قرارداد هوشمند ساده *********************** +<<<<<<< HEAD بیایید با یک مثال ابتدایی شروع کنیم که مقدار یک متغیر را تعیین می‌کند و آن را در معرض دسترسی سایر قراردادها قرار می‌دهد. اینکه الان شما متوجه چیزی نمی‌شوید طبیعی می‌باشد، بعداً به جزئیات بیشتری خواهیم پرداخت. +======= +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 مثال ذخیره سازی =============== @@ -61,7 +67,7 @@ // The keyword "public" makes variables // accessible from other contracts address public minter; - mapping (address => uint) public balances; + mapping(address => uint) public balances; // Events allow clients to react to specific // contract changes you declare @@ -116,7 +122,13 @@ .. index:: mapping +<<<<<<< HEAD خط بعدی، ``;mapping (address => uint) public balances`` یک متغیر ِحالتِ عمومی ایجاد می‌کند، اما یک نوع داده پیچیده‌تر است. نوع :ref:`mapping ` آدرس‌ها را به اعداد صحیح بدون علامت (:ref:`unsigned integers `) نگاشت می‌کند. +======= +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 Mapping ‌ها را می‌توان به عنوان `جداول هش `_ مشاهده کرد که عملاً مقداردهی اولیه شده‌اند، به طوری که همه کلیدهای ممکن از همان ابتدا وجود داشته و به مقداری که همهِ نمایشِ بایت آن‌ها صفر است نگاشت شده باشند. با این حال، نه می‌توان لیستی از تمام کلیدهای Mapping و نه لیستی از تمام مقادیر را بدست آورد. آنچه را که به Mapping اضافه کرده‌اید، ثبت کنید یا از آن در زمینه‌ای که نیازی به آن مقدار نیست استفاده کنید. یا حتی بهتر است که یک لیست نگهدارید یا از نوع داده مناسب استفاده کنید. @@ -124,8 +136,8 @@ Mapping ‌ها را می‌توان به عنوان `جداول هش ` را مشخص می‌کند که در آخرین خط با تابع ``send`` منتشر می‌شود. کلاینت اتریوم مانند برنامه‌های کاربردی وب می‌توانند به این رویداد ها که در بلاکچین منتشر شده‌اند، بدون هزینه زیاد گوش دهند. شنونده به محض انتشار، آرگومان‌های ``from`` ، ``to`` و ``amount`` را دریافت می‌کند، که امکان ردیابی تراکنش‌ها را فراهم می‌کند. +<<<<<<< HEAD برای گوش دادن به این event، می‌توانید از کد جاوا اسکریپت زیر استفاده کنید که از `web3.js `_ برای ایجاد شیء قرارداد ``Coin`` استفاده می‌کند و هر رابط کاربری تابع ``balances`` که به صورت خودکار ایجاد شده را از بالا فراخوانی می‌کند:: +======= +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) { @@ -163,9 +183,19 @@ overflows, i.e., when ``balances[receiver] + amount`` in arbitrary precision ari than the maximum value of ``uint`` (``2**256 - 1``). This is also true for the statement ``balances[receiver] += amount;`` in the function ``send``. +<<<<<<< HEAD :ref:`خطاها ` به شما امکان می‌دهند اطلاعات بیشتری در مورد علت شرایط یا شکست عملیات به فراخوانی کننده ارائه دهید. خطاها همراه با :ref:`دستورات revert ` استفاده می‌شوند. دستورات revert بدون تغییر و بدون قید و شرط، تمام تغییرات مشابه با تابع ``require`` را نابود و برمی‌گردانند ، اما همچنین به شما امکان ارائه نام خطا و داده‌های اضافی را که به فراخوانی کننده (و در نهایت به برنامه سمت کاربر یا جستوجوگر بلاک ) نشان دهید، را می‌دهند. به طوری که یک شکست را می‌توان به راحتی عیب یابی کرد یا به آن واکنش نشان داد. +======= +: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 The ``send`` function can be used by anyone (who already has some of these coins) to send coins to anyone else. If the sender does not have @@ -191,7 +221,14 @@ while providing the sender with error details using the ``InsufficientBalance`` به عنوان مثال، جدولی را تصور کنید که بالانس تمام حساب‌ها را در یک ارز الکترونیکی فهرست می‌کند. اگر انتقال از یک حساب به حساب دیگر درخواست شود، ماهیت تراکنشی پایگاه داده تضمین می‌کند که اگر مبلغ از یک حساب کم شود، همیشه به حساب دیگر اضافه می‌شود. اگر به هر دلیلی، افزودن مبلغ به حساب مقصد امکان پذیر نباشد، حساب مبدأ نیز ویرایش نمی‌شود. +<<<<<<< HEAD علاوه بر این، یک تراکنش همیشه به صورت رمزنگاری توسط فرستنده (سازنده ) امضا می‌شود. این امر باعث می‌شود محافظت از دسترسی به تغییرات خاص پایگاه داده آسان باشد. در مثال ارز الکترونیکی ، یک بررسی ساده تضمین می‌کند که فقط شخصی که کلیدهای حساب را دارد می‌تواند از آن پول انتقال بدهد. +======= +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 @@ -202,7 +239,13 @@ while providing the sender with error details using the ``InsufficientBalance`` پاسخ خلاصه این است که شما نیاز ندارید مراقبت باشید. یک ترتیب از تراکنش‌های پذیرفته شده به صورت جهانی برای شما انتخاب می‌شود، که اختلافات را حل می‌کند. تراکنش‌ها به صورت چیزی که "بلاک" نام دارد، بسته و سپس اجرا می‌شوند و در بین گره‌های مشارکت کننده توزیع می‌شوند. اگر دو تراکنش با یکدیگر مغایرت داشته باشند، تراکنشی که در نهایت دوم شود رد می‌شود و بخشی از بلاک نمی‌شود. +<<<<<<< HEAD این بلاک‌ها از نظر زمانی یک توالی خطی را تشکیل می‌دهند و بخاطر همین است که کلمه "بلاکچین" از آن گرفته می‌شود. بلاک‌ها در فواصل نسبتاً منظمی به زنجیره اضافه می‌شوند - برای اتریوم تقریباً هر 17 ثانیه می‌باشد. +======= +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 به عنوان بخشی از "مکانیزم انتخاب ترتیبی " (که "استخراج " نامیده می‌شود) ممکن است فقط در "نوک " زنجیره، برگرداندن بلاک‌ها هرزگاهی اتفاق بیفتد. هرچه تعداد بلاک‌های اضافه شده در بالای یک بلاکِ خاص بیشتر باشد، احتمال برگردانندن آن بلاک کمتر است. بنابراین ممکن است تراکنش شما برگردانده شود و حتی از بلاکچین حذف شود، اما هرچه بیشتر منتظر بمانید، احتمال آن کمتر است. @@ -211,6 +254,11 @@ while providing the sender with error details using the ``InsufficientBalance`` اگر می‌خواهید فراخوانی قراردادتان را در آینده زمان بندی کنید، می توانید از `alarm clock `_ یا سرویس اوراکل مشابه استفاده کنید. +<<<<<<< HEAD +======= + If you want to schedule future calls of your contract, you can use + a smart contract automation tool or an oracle service. +>>>>>>> english/develop .. _the-ethereum-virtual-machine: @@ -261,18 +309,46 @@ while providing the sender with error details using the ``InsufficientBalance`` گَس === +<<<<<<< HEAD به محض ایجاد، هر تراکنش با مقدار مشخصی **گَس** شارژ می شود، هدف آن محدود کردن میزان کار مورد نیاز برای انجام تراکنش و پرداخت همزمان هزینه این اجرا است. هنگامی که EVM تراکنش را انجام می‌دهد، گَس طبق قوانین خاص به تدریج خالی می‌شود. **gas price** مقداری است که توسط سازنده تراکنش تنظیم می‌شود و باید ``gas_price * gas`` را قبل از حساب ارسالی پرداخت کند. اگر پس از اجرا مقداری گَس باقی مانده باشد، به همان روش به سازنده بازپرداخت می‌شود. اگر گَس در هر نقطه مصرف شود (یعنی منفی باشد)، یک استثناء اتمام گَس ایجاد می‌شود، که تمام تغییرات و اصلاحات ایجاد شده در حالت را در این چارچوب فراخوانی فعلی، باز می‌گرداند . +======= +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 فضای ذخیره سازی ، حافظه مِمُوری و پشته ============================= +<<<<<<< HEAD ماشین مجازی اتریوم دارای سه فضا برای ذخیره سازی داده می‌باشد: فضای ذخیره سازی یا storage، حافظه موقت یا مِمُوری و پشته، که در پاراگراف‌های زیر توضیح داده شده‌اند. +======= +The Ethereum Virtual Machine has three areas where it can store data: +storage, memory and the stack. +>>>>>>> english/develop هر حساب دارای یک فضای داده به نام **storage** می‌باشد، که بین تابع فراخوانی و تراکنش‌ها ثابت است. @@ -307,12 +383,22 @@ EVM یک ماشین ثبت نیست بلکه یک ماشین پشته است، فراخوانی‌ها به عمق 1024 **محدود می‌‌شوند**، این بدان معنی است که برای انجام عملیات پیچیده‌تر، حلقه‌ها بر فراخوانی‌های مکرر باید ترجیح داده شوند. بعلاوه، فقط 63/64امین از گَس می‌تواند در یک پیام فراخوانی فوروارد شود، که در عمل باعث ایجاد عمق کمتر از 1000 می‌شود. -.. index:: delegatecall, callcode, library +.. index:: delegatecall, library +<<<<<<< HEAD Delegatecall / Callcode و کتابخانه ها ===================================== نوع خاصی از پیام های فراخوانی به نام ** **delegatecall وجود دارد، که همانند یک پیام فراخوانی می‌باشند، جدا از این واقعیت که کد در آدرس مقصد در قرارداد فراخوانی کننده اجرا می‌شود و ``msg.sender`` و ``msg.value`` مقادیر خود را تغییر نمی‌دهند. +======= +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 این بدان معناست که یک قرارداد می‌تواند به صورت پویا در زمان اجرا، کد را از آدرس دیگری بارگیری کند. Storage، آدرس فعلی و بالانس هنوز به قرارداد فراخوانی کننده اشاره دارد و فقط کد از آدرس فراخوانی شده گرفته شده‌است. @@ -331,7 +417,7 @@ delegatecall امکان ویژگی "کتابخانه" در سالیدیتی را قراردادها حتی می‌توانند قراردادهای دیگری را با استفاده از یک آپکد خاص ایجاد کنند (یعنی آدرس صفر را به عنوان یک تراکنش به سادگی صدا نمی‌زنند). تنها تفاوت بین **فراخوانی‌های ایجاد** و پیام‌های فراخوانی عادی این است که داده‌های پیلود اجرا می‌شوند و نتیجه به عنوان کد و فراخوانی کننده ، ذخیره می‌شود. ایجاد کننده، آدرس قرارداد جدید را روی پشته دریافت می‌کند. -.. index:: selfdestruct, self-destruct, deactivate +.. index:: ! selfdestruct, deactivate غیرفعال کردن و خود تخریبی ============================ @@ -339,9 +425,47 @@ delegatecall امکان ویژگی "کتابخانه" در سالیدیتی را تنها راه حذف کد از بلاکچین زمانی است که قراردادی در آن آدرس عملیات ``selfdestruct`` را انجام دهد. باقی مانده اتر ذخیره شده در آن آدرس به مقصد تعیین شده ارسال می‌شود و سپس storage و کد از حالت خارج می‌شود. حذف قرارداد از نظر تئوری یک ایده خوب به نظر می‌رسد، اما به طور بالقوه خطرناک است، زیرا اگر کسی اتر را به قراردادهای حذف شده بفرستد، اتر برای همیشه از بین می‌رود. .. warning:: +<<<<<<< HEAD حتی اگر قراردادی با ``selfdestruct`` حذف شود، هنوز به عنوان بخشی از تاریخچهِ بلاکچین باقی می‌ماند و احتمالاً توسط اکثر گره‌های اتریوم نگهداری شود. بنابراین استفاده از ``selfdestruct`` با حذف داده‌ها از روی هارد دیسک یکسان نیست. +======= + 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:: حتی اگر کد قرارداد فاقد فراخوانی ``selfdestruct`` باشد، باز هم می‌تواند آن عملیات را با استفاده از ``delegatecall`` یا ``callcode`` انجام دهد. +<<<<<<< HEAD اگر می‌خواهید قراردادهای خود را غیرفعال کنید، در عوض باید آنها را با تغییر حالت داخلی که باعث برگشت همه توابع می‌شود، **غیرفعال** کنید. این امر استفاده از قرارداد را غیرممکن می‌کند، زیرا بلافاصله اتر را برمی‌گرداند. +======= +If you want to deactivate your contracts, you should instead **disable** them +by changing some internal state which causes all functions to revert. This +makes it impossible to use the contract, as it returns Ether immediately. + + +.. index:: ! precompiled contracts, ! precompiles, ! contract;precompiled + +.. _precompiledContracts: + +Precompiled Contracts +===================== + +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. + +Different EVM-compatible chains might use a different set of +precompiled contracts. It might also be possible that new +precompiled contracts are added to the Ethereum main chain in the future, +but you can reasonably expect them to always be in the range between +``1`` and ``0xffff`` (inclusive). +>>>>>>> english/develop diff --git a/docs/ir/ir-breaking-changes.rst b/docs/ir-breaking-changes.rst similarity index 73% rename from docs/ir/ir-breaking-changes.rst rename to docs/ir-breaking-changes.rst index 8afbc58c3e..4917cfc715 100644 --- a/docs/ir/ir-breaking-changes.rst +++ b/docs/ir-breaking-changes.rst @@ -1,12 +1,28 @@ .. index: ir breaking changes +.. _ir-breaking-changes: + ********************************* Solidity IR-based Codegen Changes ********************************* -This section highlights the main differences between the old and the IR-based codegen, -along with the reasoning behind the changes and how to update affected code. +Solidity can generate EVM bytecode in two different ways: +Either directly from Solidity to EVM opcodes ("old codegen") or through +an intermediate representation ("IR") in Yul ("new codegen" or "IR-based codegen"). + +The IR-based code generator was introduced with an aim to not only allow +code generation to be more transparent and auditable but also +to enable more powerful optimization passes that span across functions. + +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. Semantic Only Changes ===================== @@ -14,8 +30,57 @@ Semantic Only Changes This section lists the changes that are semantic-only, thus potentially hiding new and different behavior in existing code. -- When storage structs are deleted, every storage slot that contains a member of the struct is set to zero entirely. Formally, 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). +.. _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). .. code-block:: solidity @@ -53,14 +118,14 @@ hiding new and different behavior in existing code. // 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() { _; _; } } - If you execute ``f(0)`` in the old code generator, it will return ``2``, while - it will return ``1`` when using the new code generator. + 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. .. code-block:: solidity @@ -91,73 +156,6 @@ hiding new and different behavior in existing code. - New code generator: ``0`` as all parameters, including return parameters, will be re-initialized before each ``_;`` evaluation. -- The order of contract 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 execute: - - 1. If present at declaration, initial values are assigned to state variables. - 2. Constructor, if present. - -This causes differences in some contracts, for example: - - .. 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. - -- Copying ``bytes`` arrays from memory to storage is implemented in a different way. The old code generator always copies full words, while the new one cuts the byte array after its end. The old behaviour can lead to dirty data being copied after the end of the array (but still in the same storage slot). - This causes differences in some contracts, for example: - - .. code-block:: solidity - - // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.8.1; - - contract C { - bytes x; - function f() public returns (uint _r) { - bytes memory m = "tmp"; - assembly { - mstore(m, 8) - mstore(add(m, 32), "deadbeef15dead") - } - x = m; - assembly { - _r := sload(x.slot) - } - } - } - - Previously ``f()`` would return ``0x6465616462656566313564656164000000000000000000000000000000000010`` (it has correct length, and correct first 8 elements, but then it contains dirty data which was set via assembly). - Now it is returning ``0x6465616462656566000000000000000000000000000000000000000000000010`` (it has correct length, and correct elements, but does not contain superfluous data). - .. index:: ! evaluation order; expression - For the old code generator, the evaluation order of expressions is unspecified. @@ -171,19 +169,20 @@ This causes differences in some contracts, for example: // 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; } } The function ``preincr_u8(1)`` returns the following values: - - 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 + - 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 .. index:: ! evaluation order; function arguments - On the other hand, function argument expressions are evaluated in the same order by both code generators with the exception of the global functions ``addmod`` and ``mulmod``. + On the other hand, function argument expressions are evaluated in the same order + by both code generators with the exception of the global functions ``addmod`` and ``mulmod``. For example: .. code-block:: solidity @@ -191,11 +190,11 @@ This causes differences in some contracts, for example: // 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); } } @@ -227,11 +226,15 @@ This causes differences in some contracts, for example: - Old code generator: ``aMod = 0`` and ``mMod = 2`` - New code generator: ``aMod = 4`` and ``mMod = 0`` -- The new code generator imposes a hard limit of ``type(uint64).max`` (``0xffffffffffffffff``) for the free memory pointer. Allocations that would increase its value beyond this limit revert. The old code generator does not have this limit. +- The new code generator imposes a hard limit of ``type(uint64).max`` + (``0xffffffffffffffff``) for the free memory pointer. Allocations that would + increase its value beyond this limit revert. The old code generator does not + have this limit. For example: .. code-block:: solidity + :force: // SPDX-License-Identifier: GPL-3.0 pragma solidity >0.8.0; @@ -246,7 +249,7 @@ This causes differences in some contracts, for example: } } - The function `f()` behaves as follows: + The function ``f()`` behaves as follows: - Old code generator: runs out of gas while zeroing the array contents after the large memory allocation - New code generator: reverts due to free memory pointer overflow (does not run out of gas) @@ -264,11 +267,11 @@ The old code generator uses code offsets or tags for values of internal function these offsets are different at construction time and after deployment and the values can cross this border via storage. Because of that, both offsets are encoded at construction time into the same value (into different bytes). -In the new code generator, function pointers use the AST IDs of the functions as values. Since calls via jumps are not possible, +In the new code generator, function pointers use internal IDs that are allocated in sequence. Since calls via jumps are not possible, calls through function pointers always have to use an internal dispatch function that uses the ``switch`` statement to select the right function. -The ID ``0`` is reserved for uninitialized function pointers which then cause a panic in the disptach function when called. +The ID ``0`` is reserved for uninitialized function pointers which then cause a panic in the dispatch function when called. In the old code generator, internal function pointers are initialized with a special function that always causes a panic. This causes a storage write at construction time for internal function pointers in storage. @@ -280,6 +283,7 @@ Cleanup The old code generator only performs cleanup before an operation whose result could be affected by the values of the dirty bits. The new code generator performs cleanup after any operation that can result in dirty bits. +The hope is that the optimizer will be powerful enough to eliminate redundant cleanup operations. For example: @@ -289,13 +293,13 @@ For example: // 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; } } @@ -304,6 +308,6 @@ The function ``f(1)`` returns the following values: - Old code generator: (``fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe``, ``00000000000000000000000000000000000000000000000000000000000000fe``) - New code generator: (``00000000000000000000000000000000000000000000000000000000000000fe``, ``00000000000000000000000000000000000000000000000000000000000000fe``) -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``. +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``. diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst index 89c120ba5f..b05cccb602 100644 --- a/docs/layout-of-source-files.rst +++ b/docs/layout-of-source-files.rst @@ -2,29 +2,58 @@ چیدمان یک فایل منبع سالیدیتی ******************************** +<<<<<<< HEAD فایل‌های منبع می‌توانند حاوی تعداد دلخواهی از :ref:`تعاریف قرارداد` ، دستور‌های ایمپورت ، دستور‌های :ref:`pragma directives` ، :ref:`struct` ، :ref:`enum` ، :ref:`توابع` ، :ref:`خطا`، تعاریف :ref:`متغیر ثابت` باشند. +======= +Source files can contain an arbitrary number of +:ref:`contract definitions`, import_ , +:ref:`pragma` and :ref:`using for` directives and +:ref:`struct`, :ref:`enum`, :ref:`function`, :ref:`error` +and :ref:`constant variable` definitions. +>>>>>>> english/develop .. index:: ! license, spdx مشخص کننده‌ی لایسنس SPDX ======================= +<<<<<<< HEAD در صورت در دسترس بودن کد منبع ، اعتماد به قرارداد هوشمند می‌تواند بهتر ایجاد شود. از آنجا که در دسترس قرار دادن کد منبع همیشه مشکلات حقوقی مربوط به حق چاپ را تحت تأثیر قرار می دهد، کامپایلر سالیدیتی استفاده از `مشخص کنندهِ لایسنس SPDX `_ قابلِ خوانده شدن توسطِ ماشین را ترغیب می‌کند. هر فایل منبع باید با یک کامنت که نشان دهد لایسنس آن است شروع شود: +======= +Trust in smart contracts can be better established if their source code +is available. Since making source code available always touches on legal problems +with regards to copyright, the Solidity compiler encourages the use +of machine-readable `SPDX license identifiers `_. +Every source file should start with a comment indicating its license: +>>>>>>> english/develop ``// SPDX-License-Identifier: MIT`` +<<<<<<< HEAD +======= +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 کامپایلر تأیید نمی‌کند که مجوز بخشی از `لیستی `_ است که توسط SPDX مجاز است، اما رشته ارائه شده در :ref:`فرداداده بایت‌کد` را شامل می‌شود. اگر نمی‌خواهید مجوزی را تعیین نکنید یا اگر کد منبع، منبع باز نیست؛ لطفاً از مقدار ویژه ``UNLICENSED``استفاده کنید. +<<<<<<< HEAD البته ارائه این کامنت شما را از سایر تعهدات مربوط به صدور لایسنس مانند نیاز به ذکر مجوز خاص در هِدر هر فایل منبع یا دارنده اصلی حق چاپ خلاص نمی کند. کامنت توسط کامپایلر در هر کجای فایل در سطح فایل شناسایی می‌شود، اما توصیه می‌شود آن را در بالای فایل قرار دهید. اطلاعات بیشتر در مورد نحوه استفاده از مشخص کننده لایسنس SPDX را می‌توانید در `وب سایت SPDX `_ بیابید. +======= +More information about how to use SPDX license identifiers +can be found at the `SPDX website `_. +>>>>>>> english/develop .. index:: ! pragma @@ -38,7 +67,7 @@ کلمه کلیدی ``pragma`` یا پراگما برای فعال کردن برخی از ویژگی‌های کامپایلر یا بررسی‌ها استفاده می‌شود. یک دستورالعمل پراگما همیشه محلی برای یک فایل منبع است، بنابراین اگر می‌خواهید آن را در کل پروژه خود فعال کنید، باید پراگما را به تمام فایل‌های خود اضافه کنید. اگر فایل‌ دیگری را :ref:`ایمپورت` کنید، پراگمای آن فایل به طور خودکار در فایل وارد شده اعمال نمی‌شود. -.. index:: ! pragma, version +.. index:: ! pragma;version .. _version_pragma: @@ -58,12 +87,24 @@ .. note:: با استفاده از نسخه pragma نسخه کامپایلر *تغییر نمی‌کند*. همچنین ویژگی‌های کامپایلر را *فعال یا غیرفعال نمی‌کند*. این فقط به کامپایلر دستور می‌دهد که بررسی کند آیا نسخه آن با نسخه مورد نیاز پراگما مطابقت دارد یا خیر. اگر مطابقت نداشته باشد، کامپایلر خطایی را صادر می‌کند. +.. index:: ! ABI coder, ! pragma; abicoder, pragma; ABIEncoderV2 +.. _abi_coder: + ABI Coder Pragma ---------------- با استفاده از ``pragma abicoder v1`` یا ``pragma abicoder v2`` می‌توانید از بین دو پیاده سازی رمزگذار و رمزگشای ABI یکی را انتخاب کنید. +<<<<<<< HEAD رمزگذار جدید ABI (v2) قادر به رمزگذاری و رمزگشایی آرایه‌ها و structهای دلخواه تو در تو است. ممکن است کد بهینه کمتری تولید کند و به اندازه رمزگذار قدیمی تست نشده باشد، اما از نظر سالیدیتی نسخه 0.6.0 غیر آزمایشی محسوب می‌شود. شما هنوز هم باید با استفاده از ``;pragma abicoder v2`` آن را صریحاً فعال کنید. در سالیدیتی نسخه 0.8.0 به طور پیش فرض فعال می‌شود، گزینه‌ای برای انتخاب کدگذار قدیمی با استفاده از ``;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 مجموعه نوع‌های پشتیبانی شده توسط رمزگذار جدید یک مجموعه فوق العاده دقیق از نوع‌های پشتیبانی شده توسط رمزگذار قدیمی است. قراردادهایی که از آن استفاده می‌کنند می‌توانند با قراردادهایی که بدون محدودیت نیستند ارتباط برقرار کنند. بازگشت فقط تا زمانی امکان پذیر است که قرارداد غیر ``abicoder v2`` سعی در فراخوانی‌هایی نداشته باشد که نیاز به انواع رمزگشایی داشته باشند که فقط توسط رمزگذار جدید پشتیبانی می‌شوند. کامپایلر می‌تواند این مورد را تشخیص دهد و خطایی ایجاد کند. فعال کردن ``abicoder v2`` قرارداد برای اینکه خطا برطرف شود، کافی است. @@ -74,8 +115,7 @@ ABI Coder Pragma تا سالیدیتی نسخه 0.7.4، می‌توان با استفاده از ``pragma experimental ABIEncoderV2`` ، رمزگذار ABI v2 را انتخاب کرد، اما صریحاً رمزگذار v1 را نمی‌توان انتخاب کرد زیرا پیش فرض بود. -.. index:: ! pragma, experimental - +.. index:: ! pragma; experimental .. _experimental_pragma: پراگما آزمایشی @@ -84,6 +124,7 @@ ABI Coder Pragma پراگما دوم ، پراگما آزمایشی است. می‌توانند برای فعال کردن ویژگی‌های کامپایلر یا زبان استفاده شوند که هنوز به طور پیش فرض فعال نشده‌اند. پراگماهای آزمایشی زیر در حال حاضر پشتیبانی می‌شوند: +.. index:: ! pragma; ABIEncoderV2 ABIEncoderV2 ~~~~~~~~~~~~ @@ -93,6 +134,7 @@ ABIEncoderV2 +.. index:: ! pragma; SMTChecker .. _smt_checker: کنترل کننده SMTC @@ -115,10 +157,17 @@ ABIEncoderV2 سینتکس و سمنتیک -------------------- +<<<<<<< HEAD سالیدیتی برای کمک به ماژولی بودن کد شما که مشابه آنچه در جاوا اسکریپت در دسترس است (از ES6 به بعد)، از دستورات ایمپورت پشتیبانی می‌کند. با این حال، سالیدیتی مفهوم `اکسپورت به صورت پیشفرش `_ را پشتیبانی نمی‌کند. در سطح جهانی، می‌توانید از دستورات ایمپور به شکل زیر استفاده کنید: +======= +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 .. code-block:: solidity 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 ea06950212..77edafcc3e 100644 --- a/docs/metadata.rst +++ b/docs/metadata.rst @@ -6,6 +6,7 @@ .. index:: metadata, contract verification +<<<<<<< HEAD کامپایلر سالیدیتی به طور خودکار یک فایل JSON، فراداده قرارداد، که حاوی اطلاعاتی درباره قرارداد کامپایل شده است، تولید می کند. می توانید از این فایل برای query یا جستجو از نسخه کامپایلر، منابع استفاده شده، اسناد ABI و NatSpec برای تعامل ایمن تر با قرارداد و تأیید کد منبع آن استفاده کنید. @@ -28,98 +29,196 @@ برسانند و کلیدهای همه اشیاء را مرتب کنند تا به یک قالب بندی منحصر به فرد برسند. نظرات در اینجا فقط برای اهداف توضیحی مجاز نیست و استفاده می شود. +======= +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 { - // Required: The version of the metadata format - "version": "1", - // Required: Source code language, basically selects a "sub-version" - // of the specification - "language": "Solidity", // Required: Details about the compiler, contents are specific // to the language. "compiler": { - // Required for Solidity: Version of the compiler - "version": "0.4.6+commit.2dabbdf0.Emscripten.clang", // Optional: Hash of the compiler binary which produced this output - "keccak256": "0x123..." + "keccak256": "0x123...", + // Required for Solidity: Version of the compiler + "version": "0.8.2+commit.661d1103" }, - // Required: Compilation source files/source units, keys are file names - "sources": - { - "myFile.sol": { - // Required: keccak256 hash of the source file - "keccak256": "0x123...", - // Required (unless "content" is used, see below): Sorted URL(s) - // to the source file, protocol is more or less arbitrary, but a - // Swarm URL is recommended - "urls": [ "bzzr://56ab..." ], - // Optional: SPDX license identifier as given in the source file - "license": "MIT" + // 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 }, - "destructible": { - // Required: keccak256 hash of the source file - "keccak256": "0x234...", - // 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: 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 - "settings": - { - // Required for Solidity: Sorted list of remappings - "remappings": [ ":g=/dir" ], + // 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 backwards-compatibility. + // and are only given for backward-compatibility. "optimizer": { - "enabled": true, - "runs": 500, "details": { - // peephole defaults to "true" - "peephole": true, - // inliner defaults to "true" - "inliner": true, + "constantOptimizer": false, + "cse": false, + "deduplicate": false, + // inliner defaults to "false" + "inliner": false, // jumpdestRemover defaults to "true" "jumpdestRemover": true, "orderLiterals": false, - "deduplicate": false, - "cse": false, - "constantOptimizer": false, + // peephole defaults to "true" + "peephole": true, "yul": true, // Optional: Only present if "yul" is "true" "yulDetails": { - "stackAllocation": false, - "optimizerSteps": "dhfoDgvulfnTUtnIf..." + "optimizerSteps": "dhfoDgvulfnTUtnIf...", + "stackAllocation": false } - } - }, - "metadata": { - // Reflects the setting used in the input json, defaults to false - "useLiteralContent": true, - // Reflects the setting used in the input json, defaults to "ipfs" - "bytecodeHash": "ipfs" + }, + "enabled": true, + "runs": 500 }, - // Required for Solidity: File and name of the contract or library this - // metadata is created for. - "compilationTarget": { - "myFile.sol": "MyContract" + // 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..." }, - // Required for Solidity: Addresses for libraries used - "libraries": { - "MyLib": "0x123123..." + "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: Generated information about the contract. - "output": - { - // Required: ABI definition of the contract - "abi": [/* ... */], - // Required: NatSpec user documentation of the contract - "userdoc": [/* ... */], - // Required: NatSpec developer documentation of the contract - "devdoc": [/* ... */] - } + // Required: The version of the metadata format + "version": 1 } .. warning:: @@ -149,20 +248,53 @@ از هش IPFS برای بازیابی فایل استفاده کرد. +<<<<<<< HEAD +======= +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 - 0xa2 - 0x64 'i' 'p' 'f' 's' 0x58 0x22 <34 bytes IPFS hash> - 0x64 's' 'o' 'l' 'c' 0x43 <3 byte version encoding> - 0x00 0x33 + { + "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": "" + } +<<<<<<< HEAD در حالی که بیلدهای انتشار solc از کدگذاری 3 بایتی نسخه همانطور که در بالا نشان داده شده است (هر کدام یک بایت برای شماره نسخه اصلی، فرعی و وصله) استفاده می کنند، نسخه های پیش از انتشار از یک رشته نسخه کامل شامل هش commit و تاریخ ساخت استفاده می کنند. +======= +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 مپینگ CBOR می‌تواند حاوی کلیدهای دیگری نیز باشد، بنابراین بهتر است به جای اینکه با ``0xa264`` شروع کنید، داده‌ها را به طور کامل رمزگشایی کنید. به عنوان مثال، اگر از هر ویژگی آزمایشی که بر تولید @@ -173,16 +305,36 @@ توجه: کامپایلر در حال حاضر از هش IPFS فراداده استفاده می کند، اما ممکن است در آینده از هش bzzr1 یا هش دیگری نیز استفاده کند، بنابراین برای شروع با ``0xa2 0x64 'i' 'p' 'f' 's'`` به این دنباله اعتماد نکنید . ما همچنین ممکن است داده های اضافی را به این ساختار CBOR اضافه کنیم، بنابراین بهترین گزینه استفادهاز تجزیه کننده 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 استفاده برای تولید رابط خودکار و NatSpec ==================================================== +<<<<<<< HEAD فراداده به روش زیر استفاده می شود: مؤلفه ای که می خواهد با یک قرارداد تعامل داشته باشد (مثلاً Mist یا هر کیف پول) کد قرارداد را بازیابی می کند، از آن هش IPFS/Swarm یک فایل که سپس بازیابی می شود. آن فایل با JSON در ساختاری مانند بالا رمزگشایی می شود. +======= +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 +<<<<<<< HEAD سپس این مؤلفه می تواند از ABI برای ایجاد خودکار یک رابط کاربری ابتدایی برای قرارداد استفاده کند. +======= +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 علاوه بر این، کیف پول می‌تواند از اسناد کاربر theNatSpec برای نمایش یک پیام تأیید برای کاربر در زمان تعامل با قرارداد، همراه با درخواست مجوز برای امضای تراکنش استفاده کند. برای اطلاعات بیشتر، فرمت @@ -201,4 +353,22 @@ (`npm package `_) می توانید کد نمونه ای را مشاهده کنید که نحوه استفاده از این ویژگی را نشان می دهد. +<<<<<<< HEAD + +======= +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 297bbc8c62..0265fef3e6 100644 --- a/docs/natspec-format.rst +++ b/docs/natspec-format.rst @@ -36,7 +36,7 @@ tools. Documentation Example ===================== -Documentation is inserted above each ``contract``, ``interface``, +Documentation is inserted above each ``contract``, ``interface``, ``library``, ``function``, and ``event`` using the Doxygen notation format. A ``public`` state variable is equivalent to a ``function`` for the purposes of NatSpec. @@ -46,7 +46,7 @@ for the purposes of NatSpec. - For Vyper, use ``"""`` indented to the inner contents with bare comments. See the `Vyper - documentation `__. + documentation `__. The following example shows a contract and a function using all available tags. @@ -58,7 +58,7 @@ The following example shows a contract and a function using all available tags. This may change in the future. -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.2 < 0.9.0; @@ -154,10 +154,6 @@ to the end-user as: if a function is being called and the input ``a`` is assigned a value of 10. -Specifying these dynamic expressions is outside the scope of the Solidity -documentation and you may read more at -`the radspec project `__. - .. _header-inheritance: Inheritance Notes @@ -183,7 +179,7 @@ other to be used by the developer. If the above contract is saved as ``ex1.sol`` then you can generate the documentation using: -.. code:: +.. code-block:: shell solc --userdoc --devdoc ex1.sol @@ -202,7 +198,7 @@ User Documentation The above documentation will produce the following user documentation JSON file as output: -.. code:: +.. code-block:: json { "version" : 1, @@ -230,7 +226,7 @@ Developer Documentation Apart from the user documentation file, a developer documentation JSON file should also be produced and should look like this: -.. code:: +.. code-block:: json { "version" : 1, diff --git a/docs/path-resolution.rst b/docs/path-resolution.rst index 40a727068b..ff4930bc9d 100644 --- a/docs/path-resolution.rst +++ b/docs/path-resolution.rst @@ -21,7 +21,7 @@ source unit is assigned a unique *source unit name* which is an opaque and unstr When you use the :ref:`import statement `, you specify an *import path* that references a source unit name. -.. index:: ! import callback, ! Host Filesystem Loader +.. index:: ! import callback, ! Host Filesystem Loader, ! --no-import-callback .. _import-callback: Import Callback @@ -36,11 +36,12 @@ An import callback is free to interpret source unit names in an arbitrary way, n If there is no callback available when one is needed or if it fails to locate the source code, compilation fails. -The command-line compiler provides the *Host Filesystem Loader* - a rudimentary callback +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 then the local filesystem +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 @@ -139,7 +140,7 @@ The initial content of the VFS depends on how you invoke the compiler: #. **Standard input** - On the command line it is also possible to provide the source by sending it to compiler's + On the command-line it is also possible to provide the source by sending it to compiler's standard input: .. code-block:: bash @@ -197,7 +198,7 @@ source unit name. 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 ``/../`` seguments or sequences of multiple slashes remain a part of it. + 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. @@ -248,19 +249,15 @@ and is bounded by two path separators. A separator is a forward slash or the beginning/end of the string. For example in ``./abc/..//`` there are three path segments: ``.``, ``abc`` and ``..``. -The compiler computes a source unit name from the import path in the following way: +The compiler resolves the import into a source unit name based on the import path, in the following way: -1. First a prefix is computed +#. 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: - - Prefix is initialized with the source unit name of the importing source unit. - - The last path segment with preceding slashes is removed from the prefix. - - Then, the leading part of the normalized import path, consisting only of ``/`` and ``.`` - characters is considered. - For every ``..`` segment found in this part the last path segment with preceding slashes is - removed from the prefix. - -2. Then the prefix is prepended to the normalized import path. - If the prefix is non-empty, a single slash is inserted between it and the import path. + - 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. The removal of the last path segment with preceding slashes is understood to work as follows: @@ -268,14 +265,10 @@ work as follows: 1. Everything past the last slash is removed (i.e. ``a/b//c.sol`` becomes ``a/b//``). 2. All trailing slashes are removed (i.e. ``a/b//`` becomes ``a/b``). -The normalization rules are the same as for UNIX paths, namely: - -- All the internal ``.`` segments are removed. -- Every internal ``..`` segment backtracks one level up in the hierarchy. -- Multiple slashes are squashed into a single one. - -Note that normalization is performed only on the import path. -The source unit name of the importing module that is used for the prefix remains unnormalized. +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. @@ -353,13 +346,13 @@ of the compiler. CLI Path Normalization and Stripping ------------------------------------ -On the command line the compiler behaves just as you would expect from any other program: +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, +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 +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. The normalization rules are as follows: @@ -416,7 +409,7 @@ The resulting file path becomes the source unit name. 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. + the base path and to only use relative paths on the command-line. .. index:: ! allowed paths, ! --allow-paths, remapping; target .. _allowed-paths: @@ -429,7 +422,7 @@ locations that are considered safe by default: - Outside of Standard JSON mode: - - The directories containing input files listed on the command line. + - 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. @@ -523,7 +516,7 @@ you can use the following in your source file: 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/iterable_mapping.sol``. +Loader, which will then look in ``/project/dapp-bin/library/math.sol``. .. warning:: @@ -559,7 +552,7 @@ you checked out to ``/project/dapp-bin_old``, then you can run: This means that all imports in ``module2`` point to the old version but imports in ``module1`` point to the new version. -Here are the detailed rules governing the behaviour of remappings: +Here are the detailed rules governing the behavior of remappings: #. **Remappings only affect the translation between import paths and source unit names.** diff --git a/docs/requirements.txt b/docs/requirements.txt index 23c8f90432..b1b21a8691 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,7 +4,7 @@ sphinx_rtd_theme>=0.5.2 pygments-lexer-solidity>=0.7.0 -sphinx-a4doc>=1.2.1 +sphinx-a4doc>=1.6.0 # 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 5b8d0013ab..85b3cf9a39 100644 --- a/docs/resources.rst +++ b/docs/resources.rst @@ -14,7 +14,7 @@ General Resources * `Solidity Compiler Developers Chat `_ * `Awesome Solidity `_ * `Solidity by Example `_ - +* `Solidity Documentation Community Translations `_ Integrated (Ethereum) Development Environments ============================================== @@ -23,10 +23,10 @@ Integrated (Ethereum) Development Environments Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine. * `Dapp `_ - Tool for building, testing and deploying smart contracts from the command line. + Tool for building, testing and deploying smart contracts from the command-line. - * `Embark `_ - Developer platform for building and deploying decentralized applications. + * `Foundry `_ + Fast, portable and modular toolkit for Ethereum application development written in Rust. * `Hardhat `_ Ethereum development environment with local Ethereum network, debugging features and plugin ecosystem. @@ -34,26 +34,12 @@ Integrated (Ethereum) Development Environments * `Remix `_ Browser-based IDE with integrated compiler and Solidity runtime environment without server-side components. - * `Scaffold-ETH `_ - Ethereum development stack focused on fast product iterations. - - * `Truffle `_ + * `Truffle `_ Ethereum development framework. Editor Integrations =================== -* Atom - - * `Etheratom `_ - Plugin for the Atom editor that features syntax highlighting, compilation and a runtime environment (Backend node & VM compatible). - - * `Atom Solidity Linter `_ - Plugin for the Atom editor that provides Solidity linting. - - * `Atom Solium Linter `_ - Configurable Solidity linter for Atom using Solium (now Ethlint) as a base. - * Emacs * `Emacs Solidity `_ @@ -61,27 +47,42 @@ Editor Integrations * IntelliJ - * `IntelliJ IDEA plugin `_ - Solidity plugin for IntelliJ IDEA (and all other JetBrains IDEs) + * `IntelliJ IDEA plugin `_ + Solidity plugin for IntelliJ IDEA (and all other JetBrains IDEs). -* Sublime +* Sublime Text * `Package for SublimeText - Solidity language syntax `_ Solidity syntax highlighting for SublimeText editor. * Vim - * `Vim Solidity `_ - Plugin for the Vim editor providing syntax highlighting. + * `Vim Solidity by Thesis `_ + Syntax highlighting for Solidity in Vim. + + * `Vim Solidity by TovarishFin `_ + Vim syntax file for Solidity. * `Vim Syntastic `_ Plugin for the Vim editor providing compile checking. -* Visual Studio Code +* Visual Studio Code (VS Code) + + * `Ethereum Remix Visual Studio Code extension `_ + Ethereum Remix extension pack for VS Code - * `Visual Studio Code extension `_ + * `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 ============== @@ -109,8 +110,8 @@ Solidity Tools * `leafleth `_ A documentation generator for Solidity smart-contracts. -* `PIET `_ - A tool to develop, audit and use Solidity smart contracts through a simple graphical interface. +* `Scaffold-ETH `_ + Forkable Ethereum development stack focused on fast product iterations. * `sol2uml `_ Unified Modeling Language (UML) class diagram generator for Solidity contracts. @@ -130,6 +131,9 @@ Solidity Tools * `Solhint `_ Solidity linter that provides security, style guide and best practice rules for smart contract validation. +* `Sourcify `_ + Decentralized automated contract verification service and public repository of contract metadata. + * `Sūrya `_ Utility tool for smart contract systems, offering a number of visual outputs and information about the contracts' structure. Also supports querying the function call graph. diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst index 09770c5707..92d601043d 100644 --- a/docs/security-considerations.rst +++ b/docs/security-considerations.rst @@ -7,28 +7,28 @@ Security Considerations While it is usually quite easy to build software that works as expected, it is much harder to check that nobody can use it in a way that was **not** anticipated. -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)! +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)! NOTE: In addition to the list below, you can find more security recommendations and best practices `in Guy Lando's knowledge list `_ and @@ -41,20 +41,18 @@ Pitfalls Private Information and Randomness ================================== -Everything you use in a smart contract is publicly visible, even -local variables and state variables marked ``private``. +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 -miners to be able to cheat. +Using random numbers in smart contracts is quite tricky if you do not want block builders to be able to cheat. -Re-Entrancy -=========== +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): +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): .. code-block:: solidity @@ -72,12 +70,12 @@ complete contract): } } -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 +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: .. code-block:: solidity @@ -97,8 +95,7 @@ as it uses ``call`` which forwards all remaining gas by default: } } -To avoid re-entrancy, you can use the Checks-Effects-Interactions pattern as -outlined further below: +To avoid reentrancy, you can use the Checks-Effects-Interactions pattern as demonstrated below: .. code-block:: solidity @@ -116,51 +113,58 @@ outlined further below: } } -Note that re-entrancy 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. +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. Gas Limit and Loops =================== -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. +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. Sending and Receiving Ether =========================== -- Neither contracts nor "external accounts" are currently able to prevent that someone sends 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)``. +- 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 ` +- 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 + 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. +- 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. +- 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. - If you want to send Ether using ``address.transfer``, there are certain details to be aware of: @@ -184,24 +188,28 @@ Sending and Receiving Ether Call Stack Depth ================ -External function calls can fail any time because they exceed the maximum -call stack size limit of 1024. In such situations, Solidity throws an exception. +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. +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. +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. Authorized Proxies ================== -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: +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: .. code-block:: solidity @@ -210,9 +218,9 @@ using a second 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); } // Other functions and other functionality } @@ -220,16 +228,17 @@ using a second proxy: // This is the full contract, it has no other functionality and // requires no privileges to work. 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 ========= -Never use tx.origin for authorization. Let's say you have a wallet contract like this: +Never use ``tx.origin`` for authorization. +Let's say you have a wallet contract like this: .. code-block:: solidity @@ -272,7 +281,11 @@ Now someone tricks you into sending Ether to the address of this attack wallet: } } -If your wallet had checked ``msg.sender`` for authorization, it would get the address of the attack wallet, instead of the owner address. But by checking ``tx.origin``, it gets the original address that kicked off the transaction, which is still the owner address. The attack wallet instantly drains all your funds. +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. .. _underflow-overflow: @@ -312,16 +325,14 @@ Try to use ``require`` to limit the size of inputs to a reasonable range and use Clearing Mappings ================= -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``. +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``. .. code-block:: solidity @@ -329,19 +340,19 @@ field of a ``struct`` that is the base type of a dynamic storage array. The 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 { @@ -349,15 +360,12 @@ field of a ``struct`` that is the base type of a dynamic storage array. The } } -Consider the example above and the following sequence of calls: ``allocate(10)``, -``writeMap(4, 128, 256)``. +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 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``. +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``. If your ``mapping`` information must be deleted, consider using a library similar to `iterable mapping `_, @@ -368,10 +376,11 @@ Minor Details - 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. + 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. *************** Recommendations @@ -381,48 +390,45 @@ Take Warnings Seriously ======================= 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. +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. +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. +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. Restrict the Amount of 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. +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. Keep it Small and Modular ========================= -Keep your contracts small and easily understandable. Single out unrelated -functionality in other contracts or into libraries. General recommendations -about 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. +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. Use the Checks-Effects-Interactions Pattern =========================================== -Most functions will first perform some checks (who called the function, -are the arguments in range, did they send enough Ether, does the person -have tokens, etc.). These checks should be done first. +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. +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 re-entrancy problem explained above. +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. Note that, also, calls to known contracts might in turn cause calls to unknown contracts, so it is probably better to just always apply this pattern. @@ -430,24 +436,23 @@ unknown contracts, so it is probably better to just always apply this pattern. Include a Fail-Safe Mode ======================== -While making your system fully decentralised will remove any intermediary, -it might be a good idea, especially for new code, to include some kind -of fail-safe mechanism: +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?", +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. +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 money" contract. +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. Ask for Peer Review =================== 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. +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. diff --git a/docs/smtchecker.rst b/docs/smtchecker.rst index a9732d05ee..f8085b63de 100644 --- a/docs/smtchecker.rst +++ b/docs/smtchecker.rst @@ -73,7 +73,7 @@ Tutorial Overflow ======== -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0; @@ -82,12 +82,12 @@ Overflow 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) { @@ -97,7 +97,7 @@ Overflow 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"`` +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: @@ -116,13 +116,13 @@ Here, it reports the following: Overflow.add(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935) -- internal call --> o.sol:9:20: | - 9 | return _x + _y; + 9 | return x_ + y_; | ^^^^^^^ If we add ``require`` statements that filter out overflow cases, the SMTChecker proves that no overflow is reachable (by not reporting warnings): -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0; @@ -131,12 +131,12 @@ the SMTChecker proves that no overflow is reachable (by not reporting warnings): 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) { @@ -155,25 +155,25 @@ An assertion represents an invariant in your code: a property that must be true 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)``. +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! -.. 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 +182,20 @@ The following code searches for the maximum element of an unrestricted array of numbers, and asserts the property that the found element must be greater or equal every element in the array. -.. 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 +216,21 @@ All the properties are correctly proven safe. Feel free to change the properties and/or add restrictions on the array to see different results. For example, changing the code to -.. 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 +243,7 @@ gives us: Warning: CHC: Assertion violation happens here. Counterexample: - _a = [0, 0, 0, 0, 0] + a = [0, 0, 0, 0, 0] = 0 Transaction trace: @@ -251,7 +251,7 @@ gives us: Test.max([0, 0, 0, 0, 0]) --> max.sol:14:4: | - 14 | assert(m > _a[i]); + 14 | assert(m > a[i]); State Properties @@ -268,7 +268,7 @@ Let us place a robot at position (0, 0). The robot can only move diagonally, one and cannot move outside the grid. The robot's state machine can be represented by the smart contract below. -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0; @@ -319,7 +319,7 @@ We can also trick the SMTChecker into giving us a path to a certain position we think might be reachable. We can add the property that (2, 4) is *not* reachable, by adding the following function. -.. code-block:: Solidity +.. code-block:: solidity function reach_2_4() public view { assert(!(x == 2 && y == 4)); @@ -368,7 +368,7 @@ In some cases, it is possible to automatically infer properties over state variables that are still true even if the externally called code can do anything, including reenter the caller contract. -.. code-block:: Solidity +.. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0; @@ -383,9 +383,9 @@ anything, including reenter the caller contract. 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 { @@ -395,8 +395,8 @@ anything, including reenter the caller contract. lock = false; } - function set(uint _x) mutex public { - x = _x; + function set(uint x_) mutex public { + x = x_; } function run() mutex public { @@ -483,6 +483,14 @@ All targets are checked by default, except underflow and overflow for Solidity > There is no precise heuristic on how and when to split verification targets, but it can be useful especially when dealing with large contracts. +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 ================ @@ -491,6 +499,23 @@ how many unproved targets there are. If the user wishes to see all the specific unproved targets, the CLI option ``--model-checker-show-unproved`` and the JSON option ``settings.modelChecker.showUnproved = true`` can be used. +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 ================== @@ -518,6 +543,206 @@ which has the following form: "source2.sol": ["contract2", "contract3"] } +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: + +- Contract Invariants: these are properties over the contract's state variables + that are true before and after every possible transaction that the contract may ever run. For example, ``x >= y``, where ``x`` and ``y`` are a contract's state variables. +- Reentrancy Properties: they represent the behavior of the contract + in the presence of external calls to unknown code. These properties can express a relation + between the value of the state variables before and after the external call, where the external call is free to do anything, including making reentrant calls to the analyzed contract. Primed variables represent the state variables' values after said external call. Example: ``lock -> x = x'``. + +The user can choose the type of invariants to be reported using the CLI option ``--model-checker-invariants "contract,reentrancy"`` or as an array in the field ``settings.modelChecker.invariants`` in the :ref:`JSON input`. +By default the SMTChecker does not report invariants. + Division and Modulo With Slack Variables ======================================== @@ -526,7 +751,7 @@ 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 +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. @@ -597,20 +822,26 @@ which is primarily an SMT solver and makes `Spacer `_ which does both. The user can choose which solvers should be used, if available, via the CLI -option ``--model-checker-solvers {all,cvc4,smtlib2,z3}`` or the JSON option +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 is currently the only way to use Eldarica, for example, since it does not have a C++ API. 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. + - 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. Since both BMC and CHC use ``z3``, and ``z3`` is available in a greater variety of environments, including in the browser, most users will almost never need to be @@ -662,7 +893,7 @@ Types that are not yet supported are abstracted by a single 256-bit unsigned integer, where their unsupported operations are ignored. For more details on how the SMT encoding works internally, see the paper -`SMT-based Verification of Solidity Smart Contracts `_. +`SMT-based Verification of Solidity Smart Contracts `_. Function Calls ============== @@ -737,15 +968,15 @@ not mean loss of proving power. { 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 69872033bb..afc7aa18d8 100644 --- a/docs/structure-of-a-contract.rst +++ b/docs/structure-of-a-contract.rst @@ -109,11 +109,11 @@ .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.4.21 <0.9.0; + pragma solidity ^0.8.22; - contract SimpleAuction { - event HighestBidIncreased(address bidder, uint amount); // Event + event HighestBidIncreased(address bidder, uint amount); // Event + contract SimpleAuction { function bid() public payable { // ... emit HighestBidIncreased(msg.sender, msg.value); // Triggering event diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 18abaa7cce..427fc9dcf3 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -8,23 +8,44 @@ مقدمه ***** +<<<<<<< HEAD این راهنما در نظر دارد در مورد نحوه ی کد نویسی سالیدیتی صحبت کند. این راهنما همواره در حال تکامل است و با گذشت زمان امکان دارد قواعد جدید جایگزین قواعد قبلی شود. +======= +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 بسیاری از پروژه ها سبک نوشتاری خود را پیاده سازی می کنند. درصورتی که تداخلی رخ دهد، سبک نوشتاری خاص در پروژه الویت پیدا می کند. +<<<<<<< HEAD ساختار بسیاری از سبک نوشتاری های پیشنهاد شده (recommended) از `سبک نوشتاری pep8 `_ بر گرفته شده است. هدف این راهنما ارائه روش صحیح و یا بهترین روش برای کد نویسی سالیدیتی نیست. هدف این راهنما یکپارچگی است. `pep8 `_ صراحتا این مفهوم را نشان بیان می کند. +======= +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:: یک سبک نوشتار در مورد یکپارچگی است. سبک نوشتاری به همراه یکپارچگی مهم است. یکپارچگی در یک پروژه بسیار مهم است.یکپارچگی در یک ماژول یا تابع از همه مهمتر است. +<<<<<<< HEAD اما مهمتر از همه: **دانستن زمان غیر یکپارچه بودن است** -- بعضی اوغات یکپارچگی در نظر گرفته نمی شود. در صورت شک، به امثال دیگر نگاه کنید و تصمیم بگیرید کدام بهتر است و از پرسیدن سوال دریغ نکنید! +======= + 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 *********** @@ -47,7 +68,11 @@ Tabs یا Spaces خط های خالی =========== +<<<<<<< HEAD تعاریف های سطح اول خود را به دو خط خالی در سورس کد(source code) سالیدتی احاطه کنید. +======= +Surround top level declarations in Solidity source with two blank lines. +>>>>>>> english/develop بله: @@ -142,7 +167,11 @@ Tabs یا Spaces ماکسیموم طول خط =================== +<<<<<<< HEAD `طبق پیشنهاد PEP8 `_ ماکسیموم طول هرخط 79 (یا 99) کاراکتر باشد به خواننده کمک می کند تا به راحتی کد رابخواند. +======= +Maximum suggested line length is 120 characters. +>>>>>>> english/develop خط های پیچیده باید قوانین ذیل را رعایت کنند: @@ -199,7 +228,7 @@ Tabs یا Spaces .. code-block:: solidity - thisIsALongNestedMapping[being][set][to_some_value] = someFunction( + thisIsALongNestedMapping[being][set][toSomeValue] = someFunction( argument1, argument2, argument3, @@ -210,7 +239,7 @@ Tabs یا Spaces .. code-block:: solidity - thisIsALongNestedMapping[being][set][to_some_value] = someFunction(argument1, + thisIsALongNestedMapping[being][set][toSomeValue] = someFunction(argument1, argument2, argument3, argument4); @@ -229,7 +258,7 @@ Tabs یا Spaces bytes32[] options ); - LongAndLotsOfArgs( + emit LongAndLotsOfArgs( sender, recipient, publicKey, @@ -247,7 +276,7 @@ Tabs یا Spaces uint256 amount, bytes32[] options); - LongAndLotsOfArgs(sender, + emit LongAndLotsOfArgs(sender, recipient, publicKey, amount, @@ -276,6 +305,7 @@ Imports // ... } + contract B is Owned { // ... } @@ -433,17 +463,21 @@ Imports x = 1; y = 2; - long_variable = 3; + longVariable = 3; خیر: .. code-block:: solidity - x = 1; - y = 2; - long_variable = 3; + x = 1; + y = 2; + longVariable = 3; +<<<<<<< HEAD فضای خالی را در توابع دریافت و عقبگرد قرار ندهید: +======= +Do not include a whitespace in the receive and fallback functions: +>>>>>>> english/develop بله: @@ -666,9 +700,16 @@ block and the opening brace. selfdestruct(owner); } +<<<<<<< HEAD برای تعاریف طولانی تابع، توصیه می شود که هر ورودی (argument) را در همان سطح تو رفتگی بدنه تابع قرار دهید. پرانتز بسته و آکولاد باز باید در خط خود قرار بگیرند و همان سطح تورفتگی تابع را داشته باشند. +======= +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 بله: @@ -734,7 +775,7 @@ block and the opening brace. function thisFunctionNameIsReallyLong( address x, address y, - address z, + address z ) public onlyOwner @@ -833,15 +874,20 @@ block and the opening brace. constructor(uint) { } } + + contract C { constructor(uint, uint) { } } + + contract D { constructor(uint) { } } + contract A is B, C, D { uint x; @@ -913,8 +959,14 @@ block and the opening brace. function shortFunction() public { doSomething(); } +<<<<<<< HEAD این آموزه ها برای بهبود خوانایی تعریف توابع بودند. نویسندگان باید از بهترین قضاوت خود استفاده کنند راهنمای وی نمی تواند تمامی جایگزینی های احتمالی تعریف توابع را پوشش دهد. +======= +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 نگاشت ها ======== @@ -1000,9 +1052,16 @@ block and the opening brace. x += 3+4; x |= y&&z; +<<<<<<< HEAD * عملگر هایی که دارای الویت بالایی نسبت به دیگر عملگر ها دارند می توانند فضای خالی نداشته باشند. برای افزایش خوانایی در عبارات پیچیده مجاز است. فضای خالی در هر دو طرف عملگر باید به یک مقدار (یکسان) باشد: +======= +* 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 بله: @@ -1024,6 +1083,7 @@ block and the opening brace. ترتیب چیدمان ************ +<<<<<<< HEAD چیدمان عناصر قرارداد به ترتیب ذیل است: 1. بیانیه Pragma @@ -1031,21 +1091,72 @@ block and the opening brace. 3. رابط ها (Interfaces) 4. کتابخانه ها (Libraries) 5. قرارداد ها +======= +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 در داخل هر قرارداد، کتابخانه یا رابط به ترتیب ذیل است: +<<<<<<< HEAD 1. تعاریف نوع (Type declarations) 2. متغیر های وضعیت (State variables) 3. رخداد ها (Events) 4. توابع +======= +1. Type declarations +2. State variables +3. Events +4. Errors +5. Modifiers +6. Functions +>>>>>>> english/develop .. note:: امکان دارد تعریف نوع ها نزدیک رخداد ها یا متغیر های وضعیت کد را واضح تر کند. +<<<<<<< HEAD ************* اصول نامگذاری ************* +======= +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 اصول نامگذاری زمانی قدرتمند هستند که به صورت سرتاسری وفق داده و استفاده شوند. استفاده از اصول مختلف اطلاعات *اضافی* منتقل می کند یا به بیان دیگر بلافاصله در دسترس @@ -1065,6 +1176,7 @@ block and the opening brace. برای جلوگیری از سردرگمی، از نام های زیر برای اشاره به سبک های مختلف نامگذاری استفاده خواهد شد. +<<<<<<< HEAD * ``b`` ( تک کلمه کوچک-چین(lowercase)) * ``B`` ( تک کلمه بزرگ-چین(uppercase)) * ``lowercase`` (کوچک-چین) @@ -1074,6 +1186,15 @@ block and the opening brace. * ``CapitalizedWords`` (or CapWords) ( یا کلمات با حروف بزرگ اول) (CapWord) * ``mixedCase`` (مثل نوع قبل است با این تفاوت که حرف اول کلمه اول کوچک و باقی حرف اول کلمات دیگر بزرگ) * ``Capitalized_Words_With_Underscores`` ( مثل نوع ما قبل با این تفاوت که از خط زیر نیر استفاده می شود) +======= +* ``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!) +>>>>>>> english/develop .. note:: هنگام استفاده از CapitalizedWords تمام حروف کلمه اولیه را با حروف بزرگ وارد کنید. بنابراین HTTPServerError بهتر از HttpServerError است. هنگام استفاده از mixedCase تمام حروف کلمه اولیه کوچک و بقیه کلمات را با حرف بزرگ اول بنویسید. بنابراین xmlHTTPRequest بهتر از XMLHTTPRequest است. @@ -1110,15 +1231,15 @@ block and the opening brace. 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; } @@ -1149,15 +1270,15 @@ block and the opening brace. 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; } @@ -1233,10 +1354,30 @@ Enums در سبک تعاریف ساده باید از روش نام گذاری C اجتناب از تداخل نام گذاری =========================== -* ``single_trailing_underscore_`` +* ``singleTrailingUnderscore_`` +<<<<<<< HEAD این اصول زمانی پیشنهاد می شود که نام مورد نظر با نام داخلی یا نام دیگر رزرو شده ای تداخل داشته باشد. +======= +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 f6c5b401d9..a6b2574633 100644 --- a/docs/types/conversion.rst +++ b/docs/types/conversion.rst @@ -49,7 +49,17 @@ because ``uint256`` cannot hold values such as ``-1``. ویژگی‌های امنیتی کامپایلر را دور بزنید، بنابراین مطمئن شوید که نتیجه همان چیزی است که شما می‌خواهید و انتظار دارید! +<<<<<<< HEAD مثال زیر را در نظر بگیرید که ``int`` منفی را به ``uint`` تبدیل می‌کند: +======= +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! + +Take the following example that converts a negative ``int`` to a ``uint``: +>>>>>>> english/develop .. code-block:: solidity @@ -135,6 +145,7 @@ because ``uint256`` cannot hold values such as ``-1``. } } +.. index:: ! literal;conversion, literal;rational, literal;hexadecimal number .. _types-conversion-literals: تبدیل بین لیترال‌ها و نوع‌های اصلی @@ -154,11 +165,17 @@ because ``uint256`` cannot hold values such as ``-1``. .. note:: +<<<<<<< HEAD قبل از نسخه 0.8.0، هر عدد تحت اعشاری یا هگزا دسیمال می‌تواند به ضمنی به یک نوع صحیح تبدیل شود. از 0.8.0، چنین تبدیل‌های صریح به اندازه تبدیل‌های ضمنی سختگیرانه هستند، یعنی تنها در صورتی مجاز هستند که کلمه تحت اللفظی در محدوده حاصله مطابقت داشته باشد. آرایه‌های بایت با اندازه ثابت +======= +.. index:: literal;string, literal;hexadecimal + +Fixed-Size Byte Arrays +>>>>>>> english/develop ---------------------- اعداد اعشاری لیترال را نمی‌توان به صورت ضمنی به آرایه‌های بایت با اندازه ثابت تبدیل کرد. می‌تواند لیترال‌های @@ -190,16 +207,32 @@ because ``uint256`` cannot hold values such as ``-1``. bytes2 e = "x"; // not allowed bytes2 f = "xyz"; // not allowed +<<<<<<< HEAD آدرس‌ها +======= +.. index:: literal;address + +Addresses +>>>>>>> english/develop --------- همانطور که در :ref:`آدرس لیترال‌ها` توضیح داده شد، لیترال‌های هگز با اندازه صحیح که از آزمون چک‌سام عبور می‌کنند از نوع ``address`` هستند. هیچ لیترال دیگری را نمی‌توان به طور ضمنی به نوع ``address`` تبدیل کرد. +<<<<<<< HEAD تبدیل صریح از ``bytes20`` یا هر نوع عدد صحیح به ``address`` منجر به ``address payable`` می‌شود. ``address a`` را می‌توان به ``address payable`` از طریق ``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 af8fd0b9cf..27eda5ef65 100644 --- a/docs/types/mapping-types.rst +++ b/docs/types/mapping-types.rst @@ -4,16 +4,36 @@ انواع نگاشت‌ها (Mapping Types) ============= +<<<<<<< HEAD نوع‌های نگاشت از سینتکس ``mapping(_KeyType => _ValueType)`` استفاده می‌کنند و متغیرهای نوع نگاشت با استفاده از سینتکس ``mapping(_KeyType => _ValueType) _VariableName`` مشخص می‌شوند. ``KeyType_`` می‌تواند هر نوع مقدار داخلی، ``bytes`` ، ``string`` یا هر نوع قرارداد یا enum باشد. سایر نوع‌های پیچیده یا تعریف شده توسط کاربر، مانند نگاشت یا (mapping)‌، struct‌ها یا انواع آرایه مجاز نیستند. ``ValueType_`` می‌تواند هر نوعی باشد، از جمله نگاشت‌ها، آرایه‌ها و struct‌ها. +======= +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 می‌‍‌‌‌‌توانید نگاشت‍‌ها را به صورت `جداول هش `_ در نظر بگیرید که عملاً مقداردهی اولیه می‌شوند به گونه ای که هر کلید ممکن وجود دارد و به مقداری نگاشت می‌شود که پیش نمایش بایت همه‌ی آن صفر می‌باشند، یک نوع :ref:`مقدار پیش فرض` . شباهت در اینجا پایان می‌یابد، داده‌های کلیدی در نگاشت ذخیره نمی‌شوند، فقط از هش ``keccak256`` برای جستجوی مقدار استفاده می‌شود. +<<<<<<< HEAD +======= +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 به همین دلیل، نگاشت‌ها طول یا مفهومی از کلید یا مقدار تنظیم شده ندارند و بنابراین بدون اطلاعات اضافی در مورد کلیدهای اختصاص داده شده پاک نمی‌شوند (به قسمت :ref:`clearing-mappings` مراجعه کنید). @@ -59,11 +79,37 @@ } } +<<<<<<< HEAD مثال زیر یک نسخه ساده از توکن `ERC20 token `_ است. ``_allowances`` نمونه‌ای از نوع نگاشت در داخل نوع نگاشت دیگر است. مثال زیر از ``_allowances`` برای ثبت مبلغی که شخص دیگری مجاز به برداشت از حساب شما است استفاده می‌کند. +======= +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 @@ -72,8 +118,8 @@ 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); @@ -83,23 +129,24 @@ } function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { + require(_allowances[sender][msg.sender] >= amount, "ERC20: Allowance not high enough."); + _allowances[sender][msg.sender] -= amount; _transfer(sender, recipient, amount); - approve(sender, msg.sender, amount); return true; } - function approve(address owner, address spender, uint256 amount) public returns (bool) { - require(owner != address(0), "ERC20: approve from the zero address"); + function approve(address spender, uint256 amount) public returns (bool) { require(spender != address(0), "ERC20: approve to the zero address"); - _allowances[owner][spender] = amount; - emit Approval(owner, spender, amount); + _allowances[msg.sender][spender] = amount; + emit Approval(msg.sender, spender, amount); return true; } function _transfer(address sender, address recipient, uint256 amount) internal { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); + require(_balances[sender] >= amount, "ERC20: Not enough funds."); _balances[sender] -= amount; _balances[recipient] += amount; @@ -114,17 +161,25 @@ نگاشت های تکرارپذیر ----------------- +<<<<<<< HEAD نمی‌توانید بر روی نگاشت‌ها تکرار کنید، یعنی نمی‌توانید کلیدهای آنها را بشمارید.گرچند امکان اجرای یک ساختار داده در بالای آنها و تکرار آن وجود دارد. به عنوان مثال، کد زیر یک کتابخانه ``IterableMapping`` را پیاده سازی می‌کند که قرارداد ``User`` سپس داده‌ها را نیز اضافه می‌کند و تابع ``sum`` تکرار می‌شود تا تمام مقادیر را جمع کند. +======= +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 :force: // 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; } @@ -135,6 +190,8 @@ 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; @@ -164,25 +221,29 @@ 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); + } } // How to use it @@ -204,11 +265,11 @@ // Computes the sum of all stored data. 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 d7039afac0..3427895aa6 100644 --- a/docs/types/operators.rst +++ b/docs/types/operators.rst @@ -1,14 +1,68 @@ -.. index:: assignment, ! delete, lvalue +.. index:: ! operator +<<<<<<< HEAD اپراتورهای شامل LValues =========================== اگر ``a`` یک LValue باشد (به عنوان مثال یک متغیر یا چیزی که می‌توان به آن اختصاص داد)، عملگرهای زیر به صورت مختصر در دسترس هستند: +======= +Operators +========= + +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: + +1. If the type of the right operand can be implicitly converted to the type of the left + operand, use the type of the left operand, +2. if the type of the left operand can be implicitly converted to the type of the right + operand, use the type of the right operand, +3. otherwise, the operation is not allowed. + +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. + +The operator's result type is the same as the type the operation is performed in, +except for comparison operators where the result is always ``bool``. + +The operators ``**`` (exponentiation), ``<<`` and ``>>`` use the type of the +left operand for the operation and the result. + +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 + +Compound and Increment/Decrement Operators +------------------------------------------ +>>>>>>> english/develop ``a += e`` معادل ``a = a + e`` است. عملگرها ``=-`` ، ``=*`` ، ``=/`` ، ``%=`` ، ``=|`` ، ``=&`` و ``=^`` بر این اساس تعریف می‌شوند. ``++a`` و ``--a`` معادل ``a += 1`` / ``a -= 1`` هستند اما این عبارت هنوز مقدار قبلی ``a`` را دارد. در مقابل ، ``a--`` و ``a++`` تأثیر یکسانی در ``a`` دارند اما مقدار را پس از تغییر برمی‌گردانند. +.. index:: !delete + .. _delete: حذف @@ -58,3 +112,11 @@ 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 e40936a151..443e750b6d 100644 --- a/docs/types/reference-types.rst +++ b/docs/types/reference-types.rst @@ -52,8 +52,13 @@ .. _data-location-assignment: +<<<<<<< HEAD مکان داده و رفتار انتساب (Data location and assignment behaviour) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +======= +Data location and assignment behavior +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>>>>>>> english/develop مکان داده نه تنها برای ماندگاری داده‌ها بلکه برای معنای انتساب‌ها نیز مهم هستند: @@ -85,8 +90,10 @@ // 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 @@ -115,6 +122,7 @@ +<<<<<<< HEAD شاخص‌ها مبتنی بر صفر هستند و دسترسی در خلاف جهت اعلامیه است. @@ -138,6 +146,15 @@ و ``push(value).`` می‌توان برای افزودن یک عنصر جدید در انتهای آرایه استفاده کرد، جایی که ``()push.`` یک عنصر مقداردهی شده صفر را اضافه می‌کند و مرجعی را به آن برمی‌گرداند. +======= +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 a dynamically-sized array, where ``.push()`` appends a zero-initialized element and returns +a reference to it. +>>>>>>> english/develop + +.. 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 @@ -156,6 +173,7 @@ Variables of type ``bytes`` and ``string`` are special arrays. The ``bytes`` typ but it is packed tightly in calldata and memory. ``string`` is equal to ``bytes`` but does not allow length or index access. +<<<<<<< HEAD سالیدیتی توابع دستکاری string ندارد، اما کتابخانه‌هایstring طرف سوم وجود دارد. همچنین می‌توانید دو string را توسط keccak256-hash آنها با استفاده از ``keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2))`` مقایسه کنید و دو رشته را با استفاده از ``bytes.concat(bytes(s1), bytes(s2))`` بهم پیوست دهید. @@ -168,6 +186,19 @@ length or index access. می‌توانید طول را به تعداد مشخصی از بایت محدود کنید، همیشه از یکی از انواع مقدار ``bytes1`` تا ``bytes32`` استفاده کنید زیرا بسیار ارزان‌تر هستند. +======= +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 ``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 +padding is absent due to tight packing, see :ref:`bytes and string `. As a general rule, +use ``bytes`` for arbitrary-length raw byte data and ``string`` for arbitrary-length +string (UTF-8) data. If you can limit the length to a certain number of bytes, +always use one of the value types ``bytes1`` to ``bytes32`` because they are much cheaper. +>>>>>>> english/develop .. note:: If you want to access the byte-representation of a string ``s``, use @@ -175,6 +206,7 @@ length or index access. that you are accessing the low-level bytes of the UTF-8 representation, and not the individual characters. +<<<<<<< HEAD اگر می‌خواهید به نمایش بایت یک رشته‌ی ``s`` دسترسی پیدا کنید، از ``bytes(s).length`` / ``bytes(s)[7] = 'x';`` استفاده کنید. بخاطر داشته باشید که شما به بایت‌های سطح پایین، پیش نمایش UTF-8 و نه به کارکترهای جداگانه دسترسی پیدا می‌کنید. @@ -183,32 +215,57 @@ length or index access. .. index:: ! bytes-concat +======= +.. index:: ! bytes-concat, ! string-concat +>>>>>>> english/develop .. _bytes-concat: +.. _string-concat: +<<<<<<< HEAD تابع bytes.concat ^^^^^^^^^^^^^^^^^^^^^^^^^ با استفاده از ``bytes.concat`` می‌توانید تعدادی متغیر از ``bytes`` یا ``bytes1 ... bytes32`` را بهم پیوند دهید. این تابع یک تک آرایه ``bytes memory`` را برمی‌گرداند که شامل محتویات آرگومان‌ها بدون padding است. اگر می‌خواهید از پارامترهای رشته‌ای یا انواع دیگر استفاده کنید، ابتدا باید آنها را به ``bytes`` یا ``bytes1``/.../``bytes32`` تبدیل کنید. +======= +The functions ``bytes.concat`` and ``string.concat`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +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. + +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 that are not implicitly convertible to ``bytes``, you need to convert them to ``bytes`` or ``bytes1``/.../``bytes32`` first. + +>>>>>>> english/develop .. 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); } } +<<<<<<< HEAD اگر بدون آرگومان ``bytes.concat`` فراخوانی کنید، آرایه‌ای خالی از ``bytes`` را برمی‌گرداند. +======= +If you call ``string.concat`` or ``bytes.concat`` without arguments they return an empty array. +>>>>>>> english/develop .. index:: ! array;allocating, new @@ -240,7 +297,7 @@ length or index access. } } -.. index:: ! array;literals, ! inline;arrays +.. index:: ! literal;array, ! inline;arrays آرایه‌ لیترال‌ها ^^^^^^^^^^^^^^ @@ -375,14 +432,18 @@ length or index access. 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. +<<<<<<< HEAD **pop**: آرایه‌های storage و ``bytes`` پویا (نه ``string``) دارای یک عضو تابع به نام ``pop`` هستند که می‌توانید برای حذف یک عنصر از انتهای آرایه استفاده کنید. همچنین به طور ضمنی :ref:`delete` را روی عنصر حذف شده فراخوانی می‌کند. +======= +**pop()**: +>>>>>>> english/develop 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:: @@ -405,11 +466,18 @@ length or index access. .. note:: +<<<<<<< HEAD در نسخه‌های EVM قبل از Byzantium، دسترسی به آرایه‌های پویا از برگشتیِ توابعِ فراخوانی‌ امکان پذیر نبود. اگر توابعی را فراخوانی می‌کنید که آرایه‌های پویا را برمی‌گردانند، حتماً از EVMی استفاده کنید که روی حالت Byzantium تنظیم شده‌است. +======= + In EVM versions before Byzantium, it was not possible to access + 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. +>>>>>>> english/develop .. code-block:: solidity @@ -417,20 +485,22 @@ length or index access. 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 { @@ -452,45 +522,45 @@ length or index access. 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) { @@ -509,6 +579,120 @@ length or index access. } } +.. 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: @@ -560,21 +744,21 @@ slice is ``x[start]`` and the last element is ``x[end - 1]``. /// @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."); } } @@ -612,11 +796,11 @@ Struct‌ها 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 d36cc12287..c948e3d69c 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -4,7 +4,12 @@ انواع مقدار =========== +<<<<<<< HEAD انواع زیر را نیز انواع مقدار می‌نامند زیرا متغیرهای این نوع‌ها همیشه از نظر مقدار منتقل می‌شوند، یعنی وقتی که به عنوان آرگومان تابع یا در "انتساب‌ها " استفاده میشوند، همیشه کپی می‌شوند. +======= +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. +>>>>>>> english/develop .. index:: ! bool, ! true, ! false @@ -50,7 +55,7 @@ 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 `. @@ -155,10 +160,16 @@ to the type of the left operand is always performed at the end, but not mentione به توان رساندن (Exponentiation) ^^^^^^^^^^^^^^ +<<<<<<< HEAD به توان رساندن فقط برای انواع بدون علامت در توان در دسترس است. نوع توان در نتیجه همیشه با نوع پایه برابر است. لطفاً توجه داشته باشید که به اندازه کافی بزرگ باشد تا بتواند نتیجه را حفظ کند و برای اعلان شکست احتمالی یا رفتار پیچیده آماده شود. +======= +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 behavior. +>>>>>>> english/develop .. note:: @@ -206,12 +217,22 @@ to the type of the left operand is always performed at the end, but not mentione آدرس ------- +<<<<<<< HEAD نوع آدرس به دو صورت وجود دارد که تا حد زیادی یکسان هستند: +======= +The address type comes in two largely identical flavors: +>>>>>>> english/develop - ``address``: دارای مقدار 20 بایت (اندازه آدرس اتریوم) است. - ``address payable``: همان ``address`` است، اما با اعضای اضافی ``transfer`` و ``send`` . +<<<<<<< HEAD ایده پشت این تمایز این است که ``address payable`` آدرسی است که می‌توانید اتر را به آن بفرستید، در حالی که نمی‌توان با یک ``address`` ساده اتر ارسال کرد. +======= +The idea behind this distinction is that ``address payable`` is an address you can send Ether to, +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. +>>>>>>> english/develop تبدیل‌های نوع:: @@ -229,6 +250,7 @@ to the type of the left operand is always performed at the end, but not mentione .. note:: +<<<<<<< HEAD اگر به متغیر نوع ``address`` نیاز دارید و قصد دارید اتر را برای آن ارسال کنید، نوع آن را به عنوان آدرس ``address payable`` مشخص کنید تا این نیاز قابل مشاهده باشد. همچنین، سعی کنید این تمایز یا تغییر را در اسرع وقت انجام دهید. @@ -237,9 +259,23 @@ to the type of the left operand is always performed at the end, but not mentione عملگرها: * ``<=``, ``<``, ``==``, ``!=``, ``>=`` و ``>`` +======= + 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: +>>>>>>> english/develop .. warning:: +<<<<<<< HEAD +======= + 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, 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``. +>>>>>>> english/develop اگر نوعی را که از اندازه بایت بزرگتری استفاده می‌کند به ``address`` تبدیل کنید، به عنوان مثال ``bytes32`` ، سپس به ``address`` کوتاه می‌شود. برای کاهش ابهام تبدیل ورژن 0.4.24 و بالاتر @@ -253,11 +289,15 @@ to the type of the left operand is always performed at the end, but not mentione .. note:: +<<<<<<< HEAD تمایز بین ``address`` و ``address payable`` با ورژن 0.5.0 معرفی شده‌است. همچنین از آن ورژن، قراردادها از نوع آدرس مشتق گرفته نمی‌شوند، اما اگر تابع payable fallback یا receive داشته باشند، هنوز میتوان به صورت صریح به ``address`` و ``address payable`` تبدیل شوند. +======= + Mixed-case hexadecimal numbers conforming to `EIP-55 `_ are automatically treated as literals of the ``address`` type. See :ref:`Address Literals`. +>>>>>>> english/develop .. _members-of-addresses: @@ -275,7 +315,7 @@ to the type of the left operand is always performed at the end, but not mentione .. code-block:: solidity :force: - address payable x = address(0x123); + address payable x = payable(0x123); address myAddress = address(this); if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10); @@ -293,9 +333,20 @@ to the type of the left operand is always performed at the end, but not mentione * ``send`` +<<<<<<< HEAD Send نقطه مقابل سطح پایین ``transfer`` است. در صورت عدم اجرا، قرارداد فعلی با استثنا متوقف نخواهد شد، اما ``send`` مقدار ``false`` را برمیگرداند. .. warning:: +======= + +``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 Ether. +>>>>>>> english/develop ستفاده از ``send`` خطرات زیادی دارد: اگر فراخوانی پشته عمق 1024 باشد (که همیشه می‌تواند توسط فراخوانی کننده مجبور شود) انتقال شکست میخورد و اگر گاز گیرنده شما تمام شود نیز از کار می‌افتد. بنابراین @@ -371,6 +422,12 @@ Send نقطه مقابل سطح پایین ``transfer`` است. در صورت بهتر است بدون توجه به اینکه آیا حالت از آن خوانده می شود یا روی آن نوشته شده است، از تکیه بر مقادیر گاز سخت رمزگذاری شده در کد قرارداد هوشمند خود جلوگیری کنید، زیرا این امر می تواند مشکلات زیادی را به همراه داشته باشد. همچنین، دسترسی به گاز ممکن است در آینده تغییر کند. +* ``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)``. + .. note:: کلیه قراردادها را می‌توان به نوع ``address`` تبدیل کرد، بنابراین می‌توان بالانس قرارداد فعلی را با استفاده از ``address(this).balance`` جستوجو کرد. @@ -451,6 +508,7 @@ Send نقطه مقابل سطح پایین ``transfer`` است. در صورت .. note:: +<<<<<<< HEAD قبل از ورژن 0.8.0 ، ``byte`` یک نام مستعار برای ``bytes1`` بود. @@ -468,6 +526,9 @@ Send نقطه مقابل سطح پایین ``transfer`` است. در صورت رشته‌ای با کد UTF-8 به صورت پویا، به قسمت :ref:`آرایه‌ها` کنید. از نوع مقدار نیست! .. index:: address, literal;address +======= +.. index:: address, ! literal;address +>>>>>>> english/develop .. _address_literals: @@ -486,13 +547,14 @@ Send نقطه مقابل سطح پایین ``transfer`` است. در صورت قالب checksum آدرس مختلط در `EIP-55 `_ تعریف شده است. -.. index:: literal, literal;rational +.. index:: integer, rational number, ! literal;rational .. _rational_literals: لیترال‌های عدد گویا و صحیح ----------------------------- +<<<<<<< HEAD لیترال‌های عدد صحیح از توالی اعداد در محدوده 0-9 تشکیل می شوند. آنها به عنوان دیسیمال تفسیر می شوند. به عنوان مثال ``69`` به معنای شصت و نه است. لیترال‌های Octal در سالیدیتی وجود ندارند و صفرهای قبل از عدد نامعتبر هستند. @@ -500,8 +562,28 @@ Send نقطه مقابل سطح پایین ``transfer`` است. در صورت لیترال‌های کسری دیسیمال توسط یک ``.`` با حداقل یک عدد در یک طرف تشکیل می‌شوند. مثال‌ها شامل ``.1`` ، ``1.`` و ``1.3`` است. +======= +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 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. +The literal ``MeE`` is equivalent to ``M * 10**E``. +Examples include ``2e10``, ``-2e10``, ``2e-10``, ``2.5e1``. +>>>>>>> english/develop +<<<<<<< HEAD +======= +Number literal expressions retain arbitrary precision until they are converted to a non-literal type (i.e. by +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. +>>>>>>> english/develop نشانه علمی نیز پشتیبانی می‌شود، جایی که پایه می‌تواند کسر داشته باشد و توان ‌تواند. برای مثال از جمله ``2e10`` ، ``-2e10`` ، ``2e-10`` ، ``2.5e1`` . @@ -536,6 +618,22 @@ Send نقطه مقابل سطح پایین ``transfer`` است. در صورت به عنوان عملوند (توان) همیشه در ``uint256`` (برای لیترال‌های غیر منفی) یا ``int256`` (برای لیترال‌های منفی)، بدون توجه به نوع سمت راست عملوند (توان)، عمل می‌کند. +<<<<<<< HEAD +======= +.. 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 +a non-rational number). +>>>>>>> english/develop .. warning:: @@ -568,7 +666,7 @@ Send نقطه مقابل سطح پایین ``transfer`` است. در صورت uint128 a = 1; uint128 b = 2.5 + a + 0.5; -.. index:: literal, literal;string, string +.. index:: ! literal;string, string .. _string_literals: لیترال‌های string و انواع @@ -583,6 +681,10 @@ Send نقطه مقابل سطح پایین ``transfer`` است. در صورت به عنوان مثال، با b``bytes32 samevar = "stringliteral"`` لیترال رشته‌ای وقتی به نوع ``bytes32`` اختصاص یابد به معنای بایت خام تفسیر می‌شود. +<<<<<<< HEAD +======= +String literals can only contain printable ASCII characters, which means the characters between and including 0x20 .. 0x7E. +>>>>>>> english/develop لیترال‌های رشته‌ای فقط می‌توانند حاوی کارکترهای ASCII قابل چاپ باشند، این به معنای کارکترهای شامل و بین 0x1F .. 0x7E می‌باشند. @@ -627,7 +729,13 @@ Send نقطه مقابل سطح پایین ``transfer`` است. در صورت PS) برای خاتمه لیترال رشته در نظر گرفته می‌شود. Newline فقط در صورتی لیترال رشته را خاتمه می‌دهد که قبل از آن ``\`` وجود نداشته باشد. +<<<<<<< HEAD لیترال‌های Unicode +======= +.. index:: ! literal;unicode + +Unicode Literals +>>>>>>> english/develop ---------------- در حالی که لیترال‌های رشته‌ای منظم فقط می‌توانند حاوی ASCII باشند، لیترال‌های unicode - با پیشوند کلمه کلیدی – ``unicode`` می‌توانند حاوی هر توالی معتبر UTF-8 باشند. آنها همچنین از همان توالی‌های @@ -638,7 +746,7 @@ escape به عنوان لیترال‌های رشته منظم پشتیبانی string memory a = unicode"Hello 😃"; -.. index:: literal, bytes +.. index:: ! literal;hexadecimal, bytes لیترال‌های هگزادسیمال -------------------- @@ -651,8 +759,13 @@ escape به عنوان لیترال‌های رشته منظم پشتیبانی لیترال‌های مالتی هگزادسیمال جدا شده توسط فضای خالی به یک لیترال متصل می‌شوند: ``hex"00112233" hex"44556677"`` معادل با ``hex"0011223344556677"`` است. +<<<<<<< HEAD لیترال‌های هگزادسیمال مانند :ref:`لیترال‌های رشته‌ای` رفتار می‌کنند و محدودیت‌های تبدیل پذیری یکسانی دارند. +======= +Hexadecimal literals in some ways behave like :ref:`string literals ` but are not +implicitly convertible to the ``string`` type. +>>>>>>> english/develop .. index:: enum @@ -716,18 +829,18 @@ Enums حداقل به یک عضو نیاز دارد و مقدار پیش فرض .. _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. @@ -743,7 +856,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. @@ -820,7 +933,25 @@ Function types are notated as follows: +<<<<<<< HEAD تبدیل‌ها: +======= +The rule about ``payable`` and ``non-payable`` might be a little +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. +>>>>>>> english/develop یک تابع نوع ``A`` به طور ضمنی قابل تبدیل به یک تابع نوع ``B`` است اگر و فقط اگر انواع پارامترهای آنها یکسان باشد، انواع بازگشت آنها یکسان، ویژگی internal/external آنها یکسان باشد و تغییرپذیری حالت ``A`` محدود @@ -828,9 +959,39 @@ Function types are notated as follows: +<<<<<<< HEAD - توابع ``pure`` را می‌توان به ``view`` و توابع ``non-payable`` تبدیل کرد - توابع ``view`` را می‌توان به توابع ``non-payable`` پرداخت تبدیل کرد - توابع ``payable`` را می‌توان به توابع ``non-payable`` پرداخت تبدیل کرد +======= +A function of an internal type can be assigned to a variable of an internal function type regardless +of where it is defined. +This includes private, internal and public functions of both contracts and libraries as well as free +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. +>>>>>>> english/develop diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index 7f827886c9..ff8f6b4667 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -1,8 +1,10 @@ +.. index:: ! denomination + ************************************** واحدها و متغیرهای موجود در سطح جهانی ************************************** -.. index:: wei, finney, szabo, gwei, ether +.. index:: ! wei, ! finney, ! szabo, ! gwei, ! ether, ! denomination;ether واحدهای اتر =========== @@ -24,7 +26,7 @@ واحدهای ``finney`` و ``szabo`` در نسخه 0.7.0 حذف شده اند. -.. index:: time, seconds, minutes, hours, days, weeks, years +.. index:: ! seconds, ! minutes, ! hours, ! days, ! weeks, ! years, ! denomination;time واحد‌های زمان (Time Units) ========== @@ -57,7 +59,7 @@ function f(uint start, uint daysAfter) public { if (block.timestamp >= start + daysAfter * 1 days) { - // ... + // ... } } @@ -70,12 +72,13 @@ مورد بلاکچین یا توابع کاربردی عمومی استفاده می‌شوند. -.. 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 بلاک و ویژگی‌های تراکنش -------------------------------- +<<<<<<< HEAD - ``blockhash(uint blockNumber) returns (bytes32)`` : هش بلاک داده شده زمانی که ``blocknumber`` یکی از 256 بلاک اخیر باشد. در غیر این صورت صفر را برمی گرداند. - ``block.basefee`` (``uint``): بِیس فی بلاک فعلی ( `EIP-3198 `_ و `EIP-1559 `_) - ``block.chainid (uint)`` : آی دی (id) زنجیره فعلی @@ -92,6 +95,28 @@ - ``tx.gasprice (uint)`` : قیمت گَس تراکنش - ``tx.origin (address)`` : فرستنده تراکنش (فراخوانی کامل زنجیره) +======= +- ``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:: @@ -111,6 +136,7 @@ .. note:: +<<<<<<< HEAD به ``block.timestamp`` یا ``blockhash`` به عنوان منبع تصادفی اعتماد نکنید، مگر اینکه بدانید در حال انجام چه کاری هستید. timestamp و block hash تا حدی می‌توانند تحت تأثیر ماینرها قرار بگیرند. به عنوان مثال بازیگران @@ -119,6 +145,11 @@ زمانبندی بلاک فعلی باید بسیار بزرگتر از زمانبندی آخرین بلاک باشد، اما تنها تضمین در جایی است که بین زمانبندی دو بلاک متوالی در زنجیره متعارف قرار گیرد. +======= + 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 .. note:: @@ -150,6 +181,7 @@ توابع رمزگذاری و رمزگشایی ABI : ----------------------------------- +<<<<<<< HEAD // saracodic comment آ for be sorted in text - ``abi.decode(bytes memory encodedData, (...)) returns (...)`` : آABI داده‌های داده شده را رمزگشایی میکند، در حالی که انواع آن در پرانتز به عنوان آرگومان دوم آورده شده است. مثال: @@ -158,6 +190,14 @@ - ``abi.encodePacked(...) returns (bytes memory)`` : آ :ref:`packed encoding ` آرگومان‌های داده شده را انجام می‌دهد. توجه داشته باشید که رمزگذاری بسته بندی شده می‌تواند مبهم باشد ! - ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)`` : آBI-encodes آرگومان‌های داده شده را از دوم شروع می‌کند و انتخاب کننده چهار بایت داده شده را اضافه می‌کند. - ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)`` : معادل با ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`` است. +======= +- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: ABI-decodes the given data, while the types are given in parentheses as second argument. Example: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))`` +- ``abi.encode(...) returns (bytes memory)``: ABI-encodes the given arguments +- ``abi.encodePacked(...) returns (bytes memory)``: Performs :ref:`packed encoding ` of the given arguments. Note that packed encoding can be ambiguous! +- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: ABI-encodes the given arguments starting from the second and prepends the given four-byte selector +- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`` +- ``abi.encodeCall(function functionPointer, (...)) returns (bytes memory)``: ABI-encodes a call to ``functionPointer`` with the arguments found in the tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, (...))`` +>>>>>>> english/develop .. note:: @@ -179,6 +219,14 @@ - ``bytes.concat(...) returns (bytes memory)`` : :ref:`تعداد متغیر bytes و bytes1 ،… ، bytes32 آرگومان را به یک آرایه بایت متصل می‌کند` +.. 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 مدیریت خطا (Error Handling) @@ -281,9 +329,14 @@ برای امضای _transaction_ ثابت شد ( `EIP-2 `_ را مشاهده کنید )، اما تابع ecrecover بدون تغییر باقی ماند. این معمولاً مشکلی ایجاد نمی‌کند مگر اینکه شما نیاز به امضا برای منحصر به فرد بودن یا استفاده از آنها برای +<<<<<<< HEAD شناسایی آیتم‌ها داشته باشید. OpenZeppelin `دارای یک کتابخانه کمکی ECDSA `_ است که می‌توانید بدون این مشکل به عنوان یک wrapper برای ``ecrecover`` از آن استفاده کنید. +======= + 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:: @@ -355,6 +408,7 @@ از بررسی نوع، بررسی وجود تابع و بسته بندی آرگومان می‌شود. .. warning:: +<<<<<<< HEAD برخی از خطرات استفاده از ``send`` وجود دارد: اگر عمق فراخوانی پشته 1024 باشد، انتقال با شکست مواجه می‌شود (این امر همیشه می‌تواند توسط تماس گیرنده اجبار شود) و همچنین در صورت تمام شدن گَس گیرنده @@ -362,6 +416,12 @@ یا حتی بهتر است از ``transfer`` استفاده کنید: از الگویی استفاده کنید که گیرنده پول را برداشت می‌کند. +======= + 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:: @@ -412,8 +472,9 @@ -.. index:: this, selfdestruct +.. index:: this, selfdestruct, super +<<<<<<< HEAD مربوط به قرارداد (Contract Related) ---------------- @@ -421,12 +482,23 @@ قرارداد فعلی، به صراحت قابل تبدیل به :ref:`آدرس
` است +======= +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)`` قرارداد فعلی را از بین ببرید، وجوه آن را به :ref:`آدرس
` داده شده ارسال کرده و اجرا را پایان دهید. توجه داشته باشید که ``selfdestruct`` برخی از ویژگی‌های به ارث برده شده از EVM را دارد: +<<<<<<< HEAD - تابع دریافت قراردادِ دریافت کننده اجرا نمی‌شود. @@ -437,6 +509,14 @@ علاوه بر این، تمام توابع قرارداد فعلی مستقیماً از جمله تابع فعلی قابل فراخوانی هستند. +======= +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:: @@ -487,7 +567,14 @@ +<<<<<<< HEAD ``type(I).interfaceId``: +======= +``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 مقدار ``bytes4`` حاوی مشخص کننده اینترفیس `EIP-165 `_ اینترفیس ``I`` داده شده‌است. این مشخص کننده به عنوان ``XOR`` ، همه انتخاب کننده‌های تابع تعریف شده در داخل اینترفیس تعریف می‌شود - بدون @@ -504,7 +591,22 @@ ``type(T).max`` +<<<<<<< HEAD بزرگترین مقدار با تایپ ``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 813c4c3885..8dd7a34312 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -15,7 +15,7 @@ Using the Commandline Compiler Basic Usage ----------- -One of the build targets of the Solidity repository is ``solc``, the solidity commandline compiler. +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``. @@ -54,7 +54,7 @@ or ../ ` are treated as relative to the directories specified us Furthermore, the part of the path added via these options will not appear in the contract metadata. 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 +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 @@ -114,15 +114,15 @@ Setting the EVM Version to Target ********************************* When you compile your contract code you can specify the Ethereum virtual machine -version to compile for to avoid particular features or behaviours. +version to compile for to avoid particular features or behaviors. .. warning:: Compiling for the wrong EVM version can result in wrong, strange and failing - behaviour. Please ensure, especially if running a private chain, that you + 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: +On the command-line, you can select the EVM version as follows: .. code-block:: shell @@ -147,20 +147,20 @@ Target Options Below is a list of target EVM versions and the compiler-relevant changes introduced at each version. Backward compatibility is not guaranteed between each version. -- ``homestead`` +- ``homestead`` (*support deprecated*) - (oldest version) -- ``tangerineWhistle`` +- ``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`` +- ``spuriousDragon`` (*support deprecated*) - Gas cost for the ``exp`` opcode increased, relevant for gas estimation and the optimizer. -- ``byzantium`` +- ``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. + - Opcodes ``create2``, ``extcodehash``, ``shl``, ``shr`` and ``sar`` are available in assembly. - Shifting operators use shifting opcodes and thus need less gas. - ``petersburg`` - The compiler behaves the same way as with constantinople. @@ -170,9 +170,17 @@ at each version. Backward compatibility is not guaranteed between each version. - 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`` (**default**) +- ``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 `_). .. index:: ! standard JSON, ! --standard-json .. _compiler-api: @@ -200,7 +208,7 @@ Input Description .. code-block:: javascript { - // Required: Source code language. Currently supported are "Solidity" and "Yul". + // Required: Source code language. Currently supported are "Solidity", "Yul", "SolidityAST" (experimental), "EVMAssembly" (experimental). "language": "Solidity", // Required "sources": @@ -224,7 +232,7 @@ Input Description "bzzr://56ab...", "ipfs://Qma...", "/tmp/path/to/file.sol" - // If files are used, their directories should be added to the command line via + // If files are used, their directories should be added to the command-line via // `--allow-paths `. ] }, @@ -234,6 +242,33 @@ Input Description "keccak256": "0x234...", // Required (unless "urls" is used): literal contents of the source file "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) + } } }, // Optional @@ -261,9 +296,9 @@ Input Description // The peephole optimizer is always on if no details are given, // use details to switch it off. "peephole": true, - // The inliner is always on if no details are given, - // use details to switch it off. - "inliner": true, + // 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. "jumpdestRemover": true, @@ -276,6 +311,9 @@ Input Description "cse": false, // Optimize representation of literal numbers and strings in code. "constantOptimizer": false, + // 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 @@ -287,18 +325,29 @@ Input Description // Improve allocation of stack slots for variables, can free up stack slots early. // Activated by default if the Yul optimizer is activated. "stackAllocation": true, - // Select optimization steps to be applied. - // Optional, the optimizer will use the default sequence if omitted. + // 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. "optimizerSteps": "dhfoDgvulfnTUtnIf..." } } }, // Version of the EVM to compile for. // Affects type checking and code generation. Can be homestead, - // tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg, istanbul or berlin - "evmVersion": "byzantium", + // 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 a highly EXPERIMENTAL feature, not to be used for production. This is false by default. + // This is false by default. "viaIR": true, // Optional: Debugging settings "debug": { @@ -323,6 +372,9 @@ Input Description }, // Metadata settings (optional) "metadata": { + // 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) "useLiteralContent": true, // Use the given hash method for the metadata hash that is appended to the bytecode. @@ -334,7 +386,7 @@ Input Description // Addresses of the libraries. If not all libraries are given here, // it can result in unlinked objects whose output data is different. "libraries": { - // The top level key is the the name of the source file where the library is used. + // 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. @@ -366,7 +418,9 @@ Input Description // 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 @@ -380,10 +434,8 @@ Input Description // 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 - // ewasm.wast - Ewasm in WebAssembly S-expressions format - // ewasm.wasm - Ewasm in WebAssembly binary format // - // Note that using a using `evm`, `evm.bytecode`, `ewasm`, etc. will select every + // 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. // "outputSelection": { @@ -410,16 +462,27 @@ Input Description "source1.sol": ["contract1"], "source2.sol": ["contract2", "contract3"] }, - // Choose whether division and modulo operations should be replaced by - // multiplication with slack variables. Default is `true`. - // Using `false` here is recommended if you are using the CHC engine + // 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. - "divModWithSlacks": true, + "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. "solvers": ["cvc4", "smtlib2", "z3"], @@ -466,7 +529,7 @@ Output Description // Mandatory: Error type, such as "TypeError", "InternalCompilerError", "Exception", etc. // See below for complete list of types. "type": "TypeError", - // Mandatory: Component where the error originated, such as "general", "ewasm", etc. + // Mandatory: Component where the error originated, such as "general" etc. "component": "general", // Mandatory ("error", "warning" or "info", but please note that this may be extended in the future) "severity": "error", @@ -503,8 +566,14 @@ Output Description "userdoc": {}, // Developer documentation (natspec) "devdoc": {}, - // Intermediate representation (string) + // 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. "storageLayout": {"storage": [/* ... */], "types": {/* ... */} }, // EVM-related outputs @@ -582,13 +651,6 @@ Output Description "heavyLifting()": "infinite" } } - }, - // Ewasm related outputs - "ewasm": { - // S-expressions format - "wast": "", - // Binary format (hex string) - "wasm": "" } } } @@ -599,6 +661,7 @@ Output Description انواع خطا ~~~~~~~~~ +<<<<<<< HEAD 1. ``JSONError``: جیسون (JSON) ورودی طبق قالبندی مورد نیاز نیست، مثال ورودی، یک شی ای از نوع جیسون (JSON) نیست، زبان استفاده شده پشتیبانی نمی شود، وغیره 2. ``IOError``: خطا های مربوط به حین پردازش عملیات ورودی-خروجی و یا خود ورودی/خروجی، مثل لینک URL ای که توسط سرور DNS غیر قابل ترجمه باشد یا عدم تطابق هش (hash) از طرف منبع فراهم کننده. 3. ``ParserError``: کد منبع (source code) با قواعد زبان برنامه نویسی تطابق ندارد. @@ -808,3 +871,20 @@ Output Description 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 837bf72b2f..9359077ef5 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -9,11 +9,17 @@ یول ( قبلا جولیا (JULIA) یا یولیا (IULIA) نام داشت) یک زبان میانی کامپایل شده به بایت کد(bytecode) است که برای بک اند (backend) های مختلف بکار می رود. +<<<<<<< HEAD برای پشتیبانی از EVM 1.0 ، EVM1.5 و Ewasm برنامه ریزی شده است، برای استفاده کلی در تمامی پلتفرم ها طراحی شده است. در حال حاضر بصورت جداگانه و هم در داخل سالیدیتی با عنوان “inline assembly” قابل استفاده است و کامپایلر سالیدیتی از یک پیاده سازی تجربی بنام یول به عنوان زبان میانی استفاده می کند. یول گزینه خوبی برا بهینه سازی است که این بهینه سازی در تمامی پلتفرم های هدف بصورت یکسان عمل می کند. +======= +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 انگیزه و شرح سطح-بالا ======================== @@ -78,8 +84,13 @@ } } +<<<<<<< HEAD همچنین می توان بجای تابع برگشتی از یک حلقه for استفاده کرد. اینجا ``lt(a, b)`` زمانی اجرا می شوند که ``a`` کوچکتر از ``b`` باشد. مقایسه کوچکتر-از +======= +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 @@ -143,6 +154,7 @@ داخل یک بلوک کد، عناصر زیر قابل استفاده هستند ( بخش بعدی را برای کسب جزئیات بیشتر نگاه کنید): +<<<<<<< HEAD - حرف ها مثل : ``0x123`` ، ``42`` یا ``“abc”`` (رشته ها تا 32 کاراکتر) - فراخوانی های توابع داخلی مثل: ``add(1, mload(0))`` - تعریف های متغیر مثل : ``let x := 7`` , ``let x := add(y, 3)`` یا ``let x`` (مقدار اولیه صفر داده می شود) @@ -153,11 +165,29 @@ - بیانیه switch مثل : ``switch mload(0) case 0 { revert() } default { mstore(0, 1) }`` - چرخه for loop مثل : ``for { let i := 0} lt(i, 10) { i := add(i, 1) } { mstore(i, 7) }`` - تعاریف تابع مثل : ``function 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 عناصر می توانند همدیگر را دنبال کنند و توسط فاصله (فضای خالی) از هم جدا شوند، نیازی به کاراکتر اتمام خط مثل ``;`` و یا سطر جدید نیست. +<<<<<<< HEAD حروف +======= +.. index:: ! literal;in Yul + +Literals +>>>>>>> english/develop -------- به عنوان حروف شما می توانید استفاده کنید از: @@ -221,9 +251,17 @@ In the EVM dialect of Yul, literals represent 256-bit words as follows: // Here, the user-defined function `f` returns two values. let x, y := f(1, mload(0)) +<<<<<<< HEAD برای توابع داخلی EVM، عبارات عملکردی می توانند مستقیما به یک رشته ای از کد گذاری ترجمه شوند: شما فقط برای بدست آوردن کد کذاری از راست به چپ عبارات را می خوانید. در مورد اولین خط مثال : ``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 برای فراخوانی های توابع تعریف شده کاربر، مقادیر وروردی داخل پشته از راست به چپ داخل پشته قرار می گیرند این ترتیب ارزیابی لیست های وروردی است. مقادیر برگشتی، انتظار می @@ -492,9 +530,30 @@ Loops در تمام شرایط دیگر ، عبارات باید دقیقا به یک ارزش سنجیده شوند. +<<<<<<< HEAD دستورات ``continue`` و ``break`` در داخل بدنه حلقه ها قابل استفاده است و باید همان عملکرد را که در حلقه دارند نشان دهند( یا هر دو باید در سطح بالایی باشند). از دستورات ``continue`` و ``break`` نمی توان در قسمت های دیگر حلقه استفاده کرد ، حتی در داخل حلقه دوم یک حلقه تو در تو. +======= +A ``continue`` or ``break`` statement can only be used inside the body of a for-loop, as follows. +Consider the innermost loop that contains the statement. +The loop and the statement must be in the same function, or both must be at the top level. +The statement must be in the loop's body block; +it cannot be in the loop's initialization block or update block. +It is worth emphasizing that this restriction applies just +to the innermost loop that contains the ``continue`` or ``break`` statement: +this innermost loop, and therefore the ``continue`` or ``break`` statement, +may appear anywhere in an outer loop, possibly in an outer loop's initialization block or update block. +For example, the following is legal, +because the ``break`` occurs in the body block of the inner loop, +despite also occurring in the update block of the outer loop: + +.. code-block:: yul + + for {} true { for {} true {} { break } } + { + } +>>>>>>> english/develop قسمت شرط حلقه باید دقیقا یک مقدار سنجیده شود. @@ -588,10 +647,10 @@ object state) و نود AST را می گیرد و دو وضعیت آبجکت (ob 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: - let G1, L, mode = E(G, L, i1, ..., in) + let G1, L1, mode = E(G, L, i1, ..., in) // mode has to be regular or leave due to the syntactic restrictions if mode is leave then G1, L1 restricted to variables of L, leave @@ -611,7 +670,7 @@ object state) و نود AST را می گیرد و دو وضعیت آبجکت (ob 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) = @@ -653,27 +712,37 @@ object state) و نود AST را می گیرد و دو وضعیت آبجکت (ob L'[$parami] = vi and L'[$reti] = 0 for all i. Let G'', L'', mode = E(Gn, L', block) G'', Ln, L''[$ret1], ..., L''[$retm] - E(G, L, l: StringLiteral) = G, L, utf8EncodeLeftAligned(l), - where utf8EncodeLeftAligned performs a UTF-8 encoding of l - and aligns it left into 32 bytes + E(G, L, l: StringLiteral) = G, L, str(l), + where str is the string evaluation function, + which for the EVM dialect is defined in the section 'Literals' above E(G, L, n: HexNumber) = G, L, hex(n) - where hex is the hexadecimal decoding function + where hex is the hexadecimal evaluation function, + which turns a sequence of hexadecimal digits into their big endian value E(G, L, n: DecimalNumber) = G, L, dec(n), - where dec is the decimal decoding function + where dec is the decimal evaluation function, + which turns a sequence of decimal digits into their big endian value .. _opcodes: گویش EVM -------- +<<<<<<< HEAD گویش پیش فرض یول در حال حاضر گویش EVM در نشخه فعلی انتخاب شده EVM است. با نسخه ای از EVM ، تنها حالت موجود در این گویش ``u256`` است ، حالت خام 256 بیت ماشین مجازی اتریوم. از آنجایی که حالت پیش فرض گویش است می توان از آن صرف نظر کرد. +======= +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 جدول زیر (بسته به نوع نسخه EVM) تمام توابع ساخته شده را لیست می کند و شرح مختصری از عملکرد/کد گذاری را ارئه می دهد. این سند نمی خواهد شرح کاملی از ماشین مجازی اتریوم باشد. اگر علاقه مندبه معتای دقیق هستید، لطفا به سند دیگری مراجعه کنید. +<<<<<<< HEAD کد ها با علامت – نشانه گذاری شده اند نتیجه ای بر نمی گردانند و تمامی آنها یک مقدار را بر می گرداند. کد هایی که با ``F``، ``H``، ``B`` و ``C`` یا ``I`` و ``L`` نشانه گذاری شده اند به ترتیب از زمان Frontainter، Homestead ، Byzantium و Constantinople یا Istanbul و London وجود دارند. @@ -681,6 +750,15 @@ Frontainter، Homestead ، Byzantium و Constantinople یا Istanbul و London در ادامه ``(mem[a...b`` نشانگر بایت های حافظه است که از موقعیت ``a`` شروع و تا ``b`` منتهی میشوند در حالی خود خانه b شامل حافظه نیست و ``storage[p]`` بیانگر محتوای داخل فضای ذخیره سازی اسلات ``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 از آنجایی که یول متغیر های محلی و کنترل جریان را مدیریت می کند ، کد هایی که با این ویژگی ها تداخل می کنند وجود ندارند. این شامل دستور های ``dup`` و ``swap`` و همچنین دستور @@ -689,7 +767,7 @@ Frontainter، Homestead ، Byzantium و Constantinople یا Istanbul و London +-------------------------+-----+---+-----------------------------------------------------------------+ | Instruction | | | Explanation | +=========================+=====+===+=================================================================+ -| stop() + `-` | F | stop execution, identical to return(0, 0) | +| stop() | `-` | F | stop execution, identical to return(0, 0) | +-------------------------+-----+---+-----------------------------------------------------------------+ | add(x, y) | | F | x + y | +-------------------------+-----+---+-----------------------------------------------------------------+ @@ -757,6 +835,10 @@ Frontainter، Homestead ، Byzantium و Constantinople یا Istanbul و London +-------------------------+-----+---+-----------------------------------------------------------------+ | 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 | @@ -789,6 +871,8 @@ Frontainter، Homestead ، Byzantium و Constantinople یا Istanbul و London +-------------------------+-----+---+-----------------------------------------------------------------+ | 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 | @@ -824,37 +908,44 @@ Frontainter، Homestead ، Byzantium و Constantinople یا Istanbul و London | 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 without topics and data mem[p...(p+s)) | +| log0(p, s) | `-` | F | log data mem[p...(p+s)) | +-------------------------+-----+---+-----------------------------------------------------------------+ -| log1(p, s, t1) | `-` | F | log with topic t1 and 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 with topics t1, t2 and data mem[p...(p+s)) | +| log2(p, s, t1, t2) | `-` | F | log data mem[p...(p+s)) with topics t1, t2 | +-------------------------+-----+---+-----------------------------------------------------------------+ -| log3(p, s, t1, t2, t3) | `-` | F | log with topics t1, t2, t3 and data mem[p...(p+s)) | +| 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 with topics t1, t2, t3, t4 and data mem[p...(p+s)) | +| 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 | +| 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 | +-------------------------+-----+---+-----------------------------------------------------------------+ @@ -871,7 +962,26 @@ Frontainter، Homestead ، Byzantium و Constantinople یا Istanbul و London بررسی کدام بخش از حافظه شامل داده های برگشتی است، استفاده کنید. بایت های باقی مانده مقداری را برمی گردانند که توسط فراخوانی های قبلی آنها مقدار دهی شده بوده اند. +<<<<<<< HEAD بعضی از گویش های داخلی، توابع اضافی دارند: +======= +.. 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 `_. + +In some internal dialects, there are additional functions: +>>>>>>> english/develop datasize, dataoffset, datacopy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -895,10 +1005,20 @@ to ``loadimmutable("name")`` in the runtime code. linkersymbol ^^^^^^^^^^^^ +<<<<<<< HEAD تابع ``linkersymbol("fq_library_name")`` یک آدرس لیترال (literal) است که توسط لینکر( linker) جایگزین می شود. اولین و تنها ورودی باید یک رشته لیترال (literal) باشد و با گزینه ``libraries--`` که نشان دهنده نام کامل کتابخانه منتخب است استفاده می شود. +======= +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 برای مثال این کد @@ -977,12 +1097,12 @@ 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 behaviour. +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 behaviour. +undefined behavior. - Control-flow should not jump into or out of verbatim blocks, but it can jump within the same verbatim block. @@ -1038,6 +1158,11 @@ it can be removed. بالا، ``بلوک`` به ``بلوکی`` که در بخش یول قبلا توضیح داده شده است در فصل قبل اشاره می کند. +.. note:: + + 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 @@ -1071,6 +1196,7 @@ it can be removed. 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)) } @@ -1082,24 +1208,24 @@ it can be removed. datacopy(offset, dataoffset("Contract2"), size) // constructor parameter is a single number 0x1234 mstore(add(offset, size), 0x1234) - pop(create(offset, add(size, 32), 0)) + pop(create(0, offset, add(size, 32))) // now return the runtime object (the currently // executing code is the constructor code) - size := datasize("runtime") + size := datasize("Contract1_deployed") offset := allocate(size) - // This will turn into a memory->memory copy for Ewasm and - // a codecopy for EVM - datacopy(offset, dataoffset("runtime"), size) + // This will turn into a codecopy for EVM + datacopy(offset, dataoffset("Contract1_deployed"), size) 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)) } @@ -1118,7 +1244,7 @@ it can be removed. // code here ... } - object "runtime" { + object "Contract2_deployed" { code { // code here ... } @@ -1148,6 +1274,7 @@ and optionally specify the :ref:`expected number of contract executions `. +>>>>>>> english/develop .. _erc20yul: