diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4345fac9428a..91c1056ec3a4 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.20")
+set(PROJECT_VERSION "0.8.26")
# OSX target needed in order to support std::visit
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14")
project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX)
@@ -37,16 +37,23 @@ option(SOLC_STATIC_STDLIBS "Link solc against static versions of libgcc and libs
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)
+option(USE_SYSTEM_LIBRARIES "Use system libraries" OFF)
+option(ONLY_BUILD_SOLIDITY_LIBRARIES "Only build solidity libraries" OFF)
+option(STRICT_NLOHMANN_JSON_VERSION "Strictly check installed nlohmann json version" ON)
+mark_as_advanced(USE_SYSTEM_LIBRARIES)
+mark_as_advanced(ONLY_BUILD_SOLIDITY_LIBRARIES)
+mark_as_advanced(STRICT_NLOHMANN_JSON_VERSION)
# Setup cccache.
include(EthCcache)
# Let's find our dependencies
include(EthDependencies)
-include(fmtlib)
-include(jsoncpp)
-include(range-v3)
-include_directories(SYSTEM ${JSONCPP_INCLUDE_DIR})
+if (NOT USE_SYSTEM_LIBRARIES)
+ include(fmtlib)
+ include(nlohmann-json)
+ include(range-v3)
+endif()
find_package(Threads)
@@ -58,6 +65,10 @@ if (PROFILE_OPTIMIZER_STEPS)
add_definitions(-DPROFILE_OPTIMIZER_STEPS)
endif()
+if (STRICT_NLOHMANN_JSON_VERSION)
+ add_definitions(-DSTRICT_NLOHMANN_JSON_VERSION_CHECK)
+endif()
+
# Figure out what compiler and system are we using
include(EthCompilerSettings)
@@ -66,12 +77,12 @@ 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)
@@ -140,12 +151,16 @@ add_subdirectory(libevmasm)
add_subdirectory(libyul)
add_subdirectory(libsolidity)
add_subdirectory(libsolc)
-add_subdirectory(tools)
+add_subdirectory(libstdlib)
-if (NOT EMSCRIPTEN)
- add_subdirectory(solc)
-endif()
+if (NOT ONLY_BUILD_SOLIDITY_LIBRARIES)
+ add_subdirectory(tools)
-if (TESTS AND NOT EMSCRIPTEN)
- add_subdirectory(test)
+ if (NOT EMSCRIPTEN)
+ add_subdirectory(solc)
+ endif()
+
+ if (TESTS AND NOT EMSCRIPTEN)
+ add_subdirectory(test)
+ endif()
endif()
diff --git a/docs/050-breaking-changes.rst b/docs/050-breaking-changes.rst
index cc3bef34c8a9..e79aba14fd88 100644
--- a/docs/050-breaking-changes.rst
+++ b/docs/050-breaking-changes.rst
@@ -114,13 +114,19 @@ Solidity v0.5.0 突破性变化
* 在非payable函数中使用 ``msg.value`` (或通过修改器引入)是不允许的,因为这是一个安全特性。
将该函数变成 ``payable``,或为程序逻辑创建一个新的内部函数,使用 ``msg.value``。
+<<<<<<< HEAD
* 为了清晰起见,如果使用标准输入作为源,命令行界面现在需要 ``-``。
+=======
+* For clarity reasons, the command-line interface now requires ``-`` if the
+ standard input is used as source.
+>>>>>>> english/develop
废弃的元素
===================
这一节列出了废弃以前的功能或语法的变化。 请注意,其中许多变化已经在实验模式 ``v0.5.0`` 中启用。
+<<<<<<< HEAD
命令行和JSON接口
--------------------------------
@@ -130,6 +136,21 @@ Solidity v0.5.0 突破性变化
* 由于中间语言 ``Julia`` 更名为 ``Yul``,命令行选项 ``--julia`` 被更名为 ``--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
* 不允许使用空前缀的重映射。
diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst
index 4f4895dd90de..ee29e1cca9db 100644
--- a/docs/060-breaking-changes.rst
+++ b/docs/060-breaking-changes.rst
@@ -9,7 +9,12 @@ Solidity 0.6.0 版本突破性变化
编译器可能不会发出警告的变化
=========================================
+<<<<<<< HEAD
本节列出了一些变化,在这些变化中,您的代码的行为可能会发生变化,而编译器不会告诉您。
+=======
+This section lists changes where the behavior of your code might
+change without the compiler telling you about it.
+>>>>>>> english/develop
* 指数运算的结果类型是基数的类型。
就像对称运算一样,它曾经是可以同时容纳基数类型和指数类型的最小类型。
@@ -90,25 +95,45 @@ Solidity 0.6.0 版本突破性变化
接口变化
=================
+<<<<<<< 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:`合约元数据 ` ) 文档。在0.6.0之前,
编译器默认附加了 `Swarm `_ 哈希值,
为了仍然支持这种行为,引入了新的命令行选项 ``--metadata-hash``。
它允许您通过传递 ``--metadata-hash`` 命令行选项的 ``ipfs`` 或 ``swarm`` 值来选择要产生和附加的哈希。
传递 ``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:`标准JSON接口 ` 使用,并影响编译器生成的元数据JSON。
diff --git a/docs/080-breaking-changes.rst b/docs/080-breaking-changes.rst
index 1d0aed05ceae..a546e91074f3 100644
--- a/docs/080-breaking-changes.rst
+++ b/docs/080-breaking-changes.rst
@@ -8,18 +8,32 @@ Solidity v0.8.0 突破性变化
语义的微小变化
===============================
+<<<<<<< HEAD
本节列出了现有代码在编译器没有通知您的情况下改变其行为的更改。
* 算术操作在下溢和溢出时都会恢复。您可以使用 ``unchecked { ... }`` 来使用以前的包装行为。
+=======
+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 behavior.
+>>>>>>> english/develop
溢出的检查是非常普遍的,所以我们把它作为默认的检查,
以增加代码的可读性,即使它是以略微增加gas成本为代价的。
* ABI编码器v2默认是激活的。
+<<<<<<< HEAD
您可以使用 ``pragma abicoder v1;`` 来选择使用旧的行为。
语句 ``pragma experimental ABIEncoderV2;`` 仍然有效,但它已被废弃,没有效果。
如果您想显示使用,请使用 ``pragma abicoder v2;`` 代替。
+=======
+ You can choose to use the old behavior using ``pragma abicoder v1;``.
+ The pragma ``pragma experimental ABIEncoderV2;`` is still valid, but it is deprecated and has no effect.
+ If you want to be explicit, please use ``pragma abicoder v2;`` instead.
+>>>>>>> english/develop
请注意,ABI coder v2比v1支持更多的类型,并对输入进行更多的合理性检查。
ABI coder v2使一些函数调用更加昂贵,而且当合约中包含不符合参数类型的数据时,它还会使合约调用回退,
@@ -49,7 +63,12 @@ Solidity v0.8.0 突破性变化
本节列出了可能导致现有合约不再编译的变化。
+<<<<<<< HEAD
* 有一些与字面常量的显式转换有关的新限制。以前在以下情况下的行为可能是模糊的:
+=======
+* There are new restrictions related to explicit conversions of literals. The previous behavior in
+ the following cases was likely ambiguous:
+>>>>>>> english/develop
1. 不允许从负数字段和大于 ``type(uint160).max`` 的字段显式转换为 ``address``。
2. 只有当字面常量位于 ``type(T).min`` 和 ``type(T).max`` 之间时,
@@ -90,7 +109,11 @@ Solidity v0.8.0 突破性变化
* 全局函数 ``log0``, ``log1``, ``log2``, ``log3`` 和 ``log4`` 已被删除。
+<<<<<<< HEAD
这些都是低级别的函数,基本上没有被使用过。它们的行为可以通过内联汇编访问。
+=======
+ These are low-level functions that were largely unused. Their behavior can be accessed from inline assembly.
+>>>>>>> english/develop
* ``enum`` 定义包含的成员不能超过256个。
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 000000000000..a3b5f25aedbe
--- /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 000000000000..044a8f800d00
--- /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 4189fcd06cb7..25ab26544318 100644
--- a/docs/_static/css/custom.css
+++ b/docs/_static/css/custom.css
@@ -1,9 +1,173 @@
+/* ROOT DECLARATIONS */
+:root {
+ /* Text */
+ --color-a: #2B247C;
+ --color-b: #672AC8;
+ --color-c: #5554D9;
+ --color-d: #9F94E8;
+ --color-e: #AEC0F1;
+ --color-f: #E6E3EC;
+ /* Background */
+
+ --white: #FAF8FF;
+ --black: #110C4E;
+ --menu-bg: #2B247C06;
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+
+ --navHeight: 4.5rem;
+ --sideWidth: 300px;
+ --maxWidth: 80rem;
+ --desktopInlinePadding: 2rem;
+ --mobileInlinePadding: 1rem;
+ --currentVersionHeight: 45px;
+
+ text-rendering: geometricPrecision;
+ -webkit-font-smoothing: antialiased;
+}
+
+a,
+button {
+ border-radius: 0;
+}
+
+:root[style*=dark] {
+ --color-a: #E6E3EC !important;
+ --color-b: #AEC0F1 !important;
+ --color-c: #9F94E8 !important;
+ --color-d: #5554D9 !important;
+ --color-e: #672AC8 !important;
+ --color-f: #2B247C !important;
+
+ --white: #110C4E !important;
+ --black: #FAF8FF !important;
+ --menu-bg: #E6E3EC06 !important;
+}
+
+html,
+body,
+.unified-header::before,
+.wy-nav-side,
+.rst-versions,
+code,
+div,
+input[type=text],
+a,
+.wy-grid-for-nav {
+ transition: background 150ms ease-in-out;
+}
+
+html,
+body,
+.wy-grid-for-nav {
+ background-color: var(--color-f) !important;
+}
+
+body {
+ font-family: "Overpass", sans-serif;
+}
+
+a {
+ color: var(--color-c);
+}
+
+a, section {
+ scroll-margin-top: calc(var(--navHeight) + 2rem);
+}
+
+hr {
+ margin-block: 2rem;
+ border-color: var(--color-d) !important;
+}
+
+
+/* HEADER STYLES */
+h1 {
+ font-family: 'Overpass', sans-serif;
+ font-weight: 700;
+ font-size: 44px;
+ color: var(--color-a) !important;
+ line-height: 1.1;
+ text-wrap: balance;
+ margin-top: 4rem;
+ margin-bottom: 1.5rem;
+}
+
+section:first-of-type h1:first-of-type {
+ font-family: 'Overpass mono', monospace;
+ font-size: 48px;
+ margin-top: 3rem;
+ margin-bottom: 5rem;
+}
+
+h2 {
+ font-family: 'Overpass', sans-serif;
+ font-weight: 700;
+ font-size: 38px;
+ color: var(--color-a) !important;
+ line-height: 46px;
+ text-wrap: balance;
+ margin-top: 4rem;
+ margin-bottom: 1.5rem;
+}
+
+*:not([role=navigation])>p[role=heading]>span,
+h3 {
+ font-family: 'Overpass', sans-serif;
+ font-weight: 700;
+ font-size: 32px;
+ color: var(--color-a) !important;
+ line-height: 46px;
+ text-wrap: balance;
+ margin-top: 4rem;
+ margin-bottom: 1.5rem;
+}
+
+h4 {
+ font-family: 'Overpass', sans-serif;
+ font-weight: 700;
+ font-size: 32px;
+ color: var(--color-a) !important;
+ line-height: 46px;
+ text-wrap: balance;
+ margin-top: 3rem;
+ margin-bottom: 1.5rem;
+}
+
+h5 {
+ font-family: 'Overpass', sans-serif;
+ font-weight: 700;
+ font-size: 18px;
+ color: var(--color-a) !important;
+ line-height: 1.4;
+ text-wrap: balance;
+}
+
+h6 {
+ font-family: 'Overpass', sans-serif;
+ font-weight: 700;
+ font-size: 16px;
+ color: var(--color-a) !important;
+ line-height: 1.4;
+ text-wrap: balance;
+}
+
+span.pre,
pre {
- white-space: pre-wrap; /* css-3 */
- white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
- white-space: -pre-wrap; /* Opera 4-6 */
- white-space: -o-pre-wrap; /* Opera 7 */
+ /* css-3 */
+ white-space: pre-wrap;
+ /* Mozilla, since 1999 */
+ white-space: -moz-pre-wrap;
+ /* Opera 4-6 */
+ white-space: -pre-wrap;
+ /* Opera 7 */
+ white-space: -o-pre-wrap;
word-wrap: break-word;
+ font-family: 'Overpass Mono', monospace;
+}
+
+small,
+small * {
+ font-size: 12px;
}
.wy-table-responsive table td,
@@ -16,10 +180,6 @@ pre {
}
/* links */
-.rst-content a:not(:visited) {
- color: #002fa7;
-}
-
.rst-content .highlighted {
background: #eac545;
}
@@ -29,24 +189,12 @@ pre {
background: #fafafa;
}
-.wy-side-nav-search > a img.logo {
- width: 100px;
- padding: 0;
-}
-
-.wy-side-nav-search > a {
- padding: 0;
- margin: 0;
-}
-
/* project version (displayed under project logo) */
-.wy-side-nav-search > div.version {
- color: #272525;
-}
-
-/* menu section headers */
-.wy-menu p.caption {
- color: #65afff;
+.wy-side-nav-search>div.version {
+ color: var(--color-b);
+ margin-top: 0;
+ margin-bottom: 0.5rem;
+ text-align: start;
}
/* Link to Remix IDE shown next to code snippets */
@@ -58,18 +206,621 @@ pre {
}
.rst-content .remix-link-container a.remix-link {
- display: inline-block;
font-size: 0.7em;
- padding: 0.1em 0.4em;
- background: #e1e4e5;
- color: #707070;
-}
-
-.rst-content .remix-link-container a.remix-link:hover {
- background: #c8cbcc;
+ padding: 0.1em 0.5em;
+ background: transparent;
+ color: var(--color-a) !important;
+ border: 1px solid var(--color-a);
+ text-decoration: none;
}
.rst-content div.highlight-solidity,
.rst-content div.highlight-yul {
margin-top: 0;
}
+
+/* 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;
+ 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;
+}
+
+.unified-header::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ opacity: 95%;
+ background: var(--color-f);
+ z-index: -1;
+ backdrop-filter: blur(3px);
+}
+
+.unified-header .home-link {
+ display: block;
+ 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);
+}
+
+.wy-nav-side input[type=text]::placeholder {
+ font-family: "Overpass", sans-serif;
+ color: var(--color-e);
+ font-size: 16px;
+ position: relative;
+ top: 4px;
+}
+
+/* Second child: Content */
+.unified-wrapper .wy-grid-for-nav .wy-nav-content {
+ width: 100%;
+ max-width: unset !important; /* override */
+ padding-inline: var(--desktopInlinePadding);
+ margin-inline-start: var(--sideWidth);
+ margin-top: var(--navHeight);
+}
+
+.unified-wrapper .wy-grid-for-nav .wy-nav-content .rst-content {
+ max-width: min(70ch, calc(100vw - 2 * var(--desktopInlinePadding) - var(--sideWidth)));
+ margin-inline: auto;
+}
+
+.unified-wrapper.menu-open .backdrop {
+ opacity: 0.5;
+}
+
+.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 cba22066bf6f..000000000000
--- a/docs/_static/css/dark.css
+++ /dev/null
@@ -1,652 +0,0 @@
-/* links */
-
-.rst-content a:not(:visited) {
- color: #aaddff;
-}
-
-/* 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
-}
-
-
-/* Link to Remix IDE shown over code snippets */
-
-.rst-content .remix-link-container a.remix-link {
- color: black;
-}
-
-
-/* Grammar */
-
-.railroad-diagram {
- fill: white;
-}
-
-.railroad-diagram path {
- stroke: white;
-}
-
-.railroad-diagram rect {
- stroke: white;
-}
-
-.a4 .sig-name {
- background-color: transparent !important;
-}
diff --git a/docs/_static/css/fonts.css b/docs/_static/css/fonts.css
new file mode 100644
index 000000000000..1a987a6da1d2
--- /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 000000000000..0e640681de2d
--- /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 add134f6c2e2..d525ab62a78f 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,11 @@ 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;
}
+
+body {
+ font-weight: 300;
+ letter-spacing: 0.5px;
+}
\ 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 000000000000..a2b8f877a358
Binary files /dev/null and b/docs/_static/img/favicon.ico differ
diff --git a/docs/_static/img/hamburger-dark.svg b/docs/_static/img/hamburger-dark.svg
new file mode 100644
index 000000000000..26d9fed9dfa5
--- /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 000000000000..d5d0d0aed2df
--- /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 000000000000..92a12a9fedfa
--- /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 000000000000..19391843b407
--- /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 000000000000..607dc1b47f23
--- /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 000000000000..f86fd22b2dfa
--- /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 000000000000..67fa16cdb039
--- /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 000000000000..a20d4fce7190
--- /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 780ea9ee710e..6ea2dd1f801f 100644
--- a/docs/_static/js/toggle.js
+++ b/docs/_static/js/toggle.js
@@ -1,39 +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 url_root = DOCUMENTATION_OPTIONS.URL_ROOT == "./" ? "" : DOCUMENTATION_OPTIONS.URL_ROOT;
- var daysheet = $(`link[href="${url_root}_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="${url_root}_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", `${url_root}_static/css/dark.css`);
- document.getElementsByTagName("head")[0].appendChild(element);
- return;
- }
- if (nightsheet !== undefined) {
- nightsheet.sheet.disabled = isDay;
- }
- }
-
- var initial = localStorage.getItem("css-mode") != "Night";
- var checkbox = document.querySelector('input[name=mode]');
+ // Update logo
+ document
+ .querySelector(`img.${SOLIDITY_LOGO_CLASS}`)
+ .setAttribute("src", newMode === LIGHT ? LIGHT_LOGO_PATH : DARK_LOGO_PATH);
- toggleCssMode(initial);
- checkbox.checked = initial;
+ // Update color mode toggle icon
+ document
+ .querySelector(`img.${COLOR_TOGGLE_ICON_CLASS}`)
+ .setAttribute("src", newMode === LIGHT ? MOON_ICON_PATH : SUN_ICON_PATH);
- checkbox.addEventListener('change', function() {
- document.documentElement.classList.add('transition');
- window.setTimeout(() => {
- document.documentElement.classList.remove('transition');
- }, 1000)
- toggleCssMode(this.checked);
- })
+ // Update hamburger menu icon color
+ document
+ .querySelector("button.mobile-menu-button img")
+ .setAttribute(
+ "src",
+ newMode === LIGHT ? LIGHT_HAMBURGER_PATH : DARK_HAMBURGER_PATH
+ );
+}
-});
\ No newline at end of file
+function toggleMenu(options = {}) {
+ const handleClassToggle = ({ classList }, className) => {
+ if (typeof options.force !== "undefined") {
+ classList.toggle(className, options.force);
+ } else {
+ classList.toggle(className);
+ }
+ };
+ document
+ .querySelectorAll('[data-toggle="rst-versions"]')
+ .forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS));
+ document
+ .querySelectorAll('[data-toggle="wy-nav-shift"]')
+ .forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS));
+ handleClassToggle(document.querySelector(`.${WRAPPER_CLASS}`), "menu-open");
+}
diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst
index 0ebb8ce0e41b..9e9a894b0a1c 100644
--- a/docs/abi-spec.rst
+++ b/docs/abi-spec.rst
@@ -238,8 +238,27 @@ Solidity 支持上面介绍的除了元祖之外的所有同名类型。
}
+<<<<<<< HEAD
因此,对于我们的例子 ``Foo``,如果我们想用 ``69`` 和 ``true`` 做参数调用 ``baz``,
我们总共需要传送 68 字节,可以分解为:
+=======
+Thus, for our ``Foo`` example, if we wanted to call ``bar`` with the argument ``["abc", "def"]``, we would pass 68 bytes total, broken down into:
+
+- ``0xfce353f6``: the Method ID. This is derived from the signature ``bar(bytes3[2])``.
+- ``0x6162630000000000000000000000000000000000000000000000000000000000``: the first part of the first
+ parameter, a ``bytes3`` value ``"abc"`` (left-aligned).
+- ``0x6465660000000000000000000000000000000000000000000000000000000000``: the second part of the first
+ parameter, a ``bytes3`` value ``"def"`` (left-aligned).
+
+In total:
+
+.. code-block:: none
+
+ 0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000
+
+If we wanted to call ``baz`` with the parameters ``69`` and
+``true``, we would pass 68 bytes total, which can be broken down into:
+>>>>>>> english/develop
- ``0xcdcd77c0``: 方法ID。这源自ASCII格式的 ``baz(uint32,bool)`` 签名的 Keccak 哈希的前 4 字节。
- ``0x0000000000000000000000000000000000000000000000000000000000000045``: 第一个参数,
@@ -257,6 +276,7 @@ Solidity 支持上面介绍的除了元祖之外的所有同名类型。
那么它的输出将是一个字节数组 ``0x0000000000000000000000000000000000000000000000000000000000000000``,
一个 ``bool`` 值。
+<<<<<<< HEAD
如果我们想用 ``["abc", "def"]`` 做参数调用 ``bar``,我们总共需要传送 68 字节,可以分解为:
- ``0xfce353f6``: 方法ID。源自 ``bar(bytes3[2])`` 的签名。
@@ -273,6 +293,10 @@ Solidity 支持上面介绍的除了元祖之外的所有同名类型。
如果我们想用 ``"dave"``, ``true`` 和 ``[1,2,3]`` 作为参数调用 ``sam``,
我们总共需要传送 292 字节,可以分解为:
+=======
+If we wanted to call ``sam`` with the arguments ``"dave"``, ``true`` and ``[1,2,3]``, we would
+pass 292 bytes total, broken down into:
+>>>>>>> english/develop
- ``0xa5643bf2``: 方法ID。这是从签名 ``sam(bytes,bool,uint256[])`` 中导出的。注意, ``uint`` 被替换为其典型代表 ``uint256``。
- ``0x0000000000000000000000000000000000000000000000000000000000000060``: 第一个参数(动态类型)的数据部分的位置,即从参数编码块开始位置算起的字节数。在这里,是 ``0x60`` 。
@@ -537,8 +561,12 @@ JSON
``view`` (:ref:`指定为不修改区块链状态 `),
``nonpayable`` (函数不接受以太币 - 默认选项) 和 ``payable`` (函数可接收以太币)。
+<<<<<<< HEAD
构造函数(constructor), receive 函数 和 fallback 函数没有 ``name`` 或 ``outputs`` 属性。
receive 函数 和 fallback 函数也没有 ``inputs`` 属性。
+=======
+Constructor, receive, and fallback never have ``name`` or ``outputs``. Receive and fallback do not have ``inputs`` either.
+>>>>>>> english/develop
.. note::
向不接收以太币函数发送非零的以太币将使交易回滚。
diff --git a/docs/assembly.rst b/docs/assembly.rst
index 1fc814987111..480f539f375b 100644
--- a/docs/assembly.rst
+++ b/docs/assembly.rst
@@ -327,9 +327,15 @@ Solidity中内存数组中的元素总是占据32字节的倍数
自动被认为是内存安全的,不需要被注释。
.. warning::
+<<<<<<< HEAD
确保汇编块程序实际满足内存模型是您的责任。
如果您将一个汇编块注释为内存安全的,但却违反了其中一个内存假设,
那么这 **将** 导致不正确的和未定义的行为,而这些行为不容易通过测试发现。
+=======
+ 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.
+>>>>>>> english/develop
如果您正在开发一个要在多个 Solidity 版本之间兼容的库,
您可以使用一个特殊的注释将一个汇编块注释为内存安全的:
@@ -341,5 +347,10 @@ Solidity中内存数组中的元素总是占据32字节的倍数
...
}
+<<<<<<< HEAD
请注意,我们将在未来的突破性版本中不允许通过注释的方式进行注解;
因此,如果您不关心与旧编译器版本的向后兼容问题,最好使用这种写法的代码字符串形式。
+=======
+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 d47f58b09e49..8628265f7d46 100644
--- a/docs/brand-guide.rst
+++ b/docs/brand-guide.rst
@@ -56,7 +56,7 @@ Solidity标志是在
Solidity标志指南
========================
-.. image:: logo.svg
+.. image:: solidity_logo.svg
:width: 256
*(右键点击标识即可下载。)*
diff --git a/docs/bugs.json b/docs/bugs.json
index 9c9780c93582..c853f95eddea 100644
--- a/docs/bugs.json
+++ b/docs/bugs.json
@@ -1,4 +1,40 @@
[
+ {
+ "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",
diff --git a/docs/bugs.rst b/docs/bugs.rst
index 0bb35682871e..75c527de4401 100644
--- a/docs/bugs.rst
+++ b/docs/bugs.rst
@@ -6,9 +6,17 @@
已知bug列表
##################
+<<<<<<< HEAD
下面,您可以找到一个JSON格式的列表,其中包括Solidity编译器中一些已知的与安全有关的错误。
该文件本身托管在 `Github 仓库 `_。
该列表最早可以追溯到0.3.0版本,只有在此之前的版本中已知的错误没有列出。
+=======
+Below, you can find a JSON-formatted list of some of the known security-relevant bugs in the
+Solidity compiler. The file itself is hosted in the `GitHub repository
+`_.
+The list stretches back as far as version 0.3.0, bugs known to be present only
+in versions preceding that are not listed.
+>>>>>>> english/develop
还有一个文件叫
`bugs_by_version.json `_,
diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json
index 928ebe5e7c29..923b3e621abb 100644
--- a/docs/bugs_by_version.json
+++ b/docs/bugs_by_version.json
@@ -1422,6 +1422,8 @@
},
"0.6.10": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1436,6 +1438,8 @@
},
"0.6.11": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1450,6 +1454,8 @@
},
"0.6.12": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1464,6 +1470,7 @@
},
"0.6.2": {
"bugs": [
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"NestedCalldataArrayAbiReencodingSizeValidation",
@@ -1481,6 +1488,7 @@
},
"0.6.3": {
"bugs": [
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"NestedCalldataArrayAbiReencodingSizeValidation",
@@ -1498,6 +1506,7 @@
},
"0.6.4": {
"bugs": [
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"NestedCalldataArrayAbiReencodingSizeValidation",
@@ -1515,6 +1524,7 @@
},
"0.6.5": {
"bugs": [
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"NestedCalldataArrayAbiReencodingSizeValidation",
@@ -1532,6 +1542,7 @@
},
"0.6.6": {
"bugs": [
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"NestedCalldataArrayAbiReencodingSizeValidation",
@@ -1548,6 +1559,8 @@
},
"0.6.7": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"NestedCalldataArrayAbiReencodingSizeValidation",
@@ -1564,6 +1577,8 @@
},
"0.6.8": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"NestedCalldataArrayAbiReencodingSizeValidation",
@@ -1577,6 +1592,8 @@
},
"0.6.9": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1592,6 +1609,8 @@
},
"0.7.0": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1606,6 +1625,8 @@
},
"0.7.1": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1621,6 +1642,8 @@
},
"0.7.2": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1635,6 +1658,8 @@
},
"0.7.3": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1648,6 +1673,8 @@
},
"0.7.4": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1660,6 +1687,8 @@
},
"0.7.5": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1672,6 +1701,8 @@
},
"0.7.6": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1684,6 +1715,8 @@
},
"0.8.0": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1696,6 +1729,8 @@
},
"0.8.1": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1708,6 +1743,9 @@
},
"0.8.10": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1717,6 +1755,9 @@
},
"0.8.11": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1727,6 +1768,9 @@
},
"0.8.12": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1737,6 +1781,9 @@
},
"0.8.13": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"StorageWriteRemovalBeforeConditionalTermination",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
@@ -1748,6 +1795,9 @@
},
"0.8.14": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"StorageWriteRemovalBeforeConditionalTermination",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
@@ -1757,6 +1807,9 @@
},
"0.8.15": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"StorageWriteRemovalBeforeConditionalTermination",
"AbiReencodingHeadOverflowWithStaticArrayCleanup"
],
@@ -1764,24 +1817,41 @@
},
"0.8.16": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"StorageWriteRemovalBeforeConditionalTermination"
],
"released": "2022-08-08"
},
"0.8.17": {
- "bugs": [],
+ "bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess"
+ ],
"released": "2022-09-08"
},
"0.8.18": {
- "bugs": [],
+ "bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess"
+ ],
"released": "2023-02-01"
},
"0.8.19": {
- "bugs": [],
+ "bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess"
+ ],
"released": "2023-02-22"
},
"0.8.2": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1792,8 +1862,42 @@
],
"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.25": {
+ "bugs": [],
+ "released": "2024-03-14"
+ },
"0.8.3": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1805,6 +1909,8 @@
},
"0.8.4": {
"bugs": [
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1815,6 +1921,9 @@
},
"0.8.5": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1825,6 +1934,9 @@
},
"0.8.6": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1835,6 +1947,9 @@
},
"0.8.7": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1845,6 +1960,9 @@
},
"0.8.8": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
@@ -1856,6 +1974,9 @@
},
"0.8.9": {
"bugs": [
+ "VerbatimInvalidDeduplication",
+ "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
+ "MissingSideEffectsOnSelectorAccess",
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
"DirtyBytesArrayToStorage",
"DataLocationChangeInInternalOverride",
diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst
index 2db317aa44ab..3c795ce8f30c 100644
--- a/docs/cheatsheet.rst
+++ b/docs/cheatsheet.rst
@@ -14,6 +14,7 @@
ABI 编码和解码函数
===================
+<<<<<<< HEAD
- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: :ref:`ABI ` - 对提供的数据进行解码。类型在括号中作为第二个参数给出。
示例: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))``
- ``abi.encode(...) returns (bytes memory)``: :ref:`ABI ` - 对给定的参数进行编码。
@@ -25,6 +26,20 @@ ABI 编码和解码函数
参数在元组中找到。执行全面的类型检查,确保类型与函数签名相符。结果等于 ``abi.encodeWithSelector(functionPointer.selector(..))``。
- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: 等价于
``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)``
+=======
+- ``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))), ...)``
+>>>>>>> english/develop
.. index:: bytes;concat, string;concat
@@ -40,19 +55,35 @@ ABI 编码和解码函数
``address`` 类型的属性
======================
+<<<<<<< HEAD
- ``.balance`` (``uint256``): :ref:`address` 的余额,以 Wei 为单位
- ``.code`` (``bytes memory``): 在 :ref:`address` 的代码(可以是空的)
- ``.codehash`` (``bytes32``): :ref:`address` 的代码哈希值
- ``.send(uint256 amount) returns (bool)``: 向 :ref:`address` 发送给定数量的 Wei,
失败时返回 ``false``
- ``.transfer(uint256 amount)``: 向 :ref:`address` 发送给定数量的 Wei,失败时会抛出错误
-
-.. index:: blockhash, block, block;basefree, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp
+=======
+- ``.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
+>>>>>>> english/develop
+
+.. 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
区块和交易属性
====================
+<<<<<<< HEAD
- ``blockhash(uint blockNumber) returns (bytes32)``: 给定区块的哈希值 - 只对最近的256个区块有效
- ``block.basefee`` (``uint``): 当前区块的基本费用 ( `EIP-3198 `_ 和 `EIP-1559 `_ )
- ``block.chainid`` (``uint``): 当前链的ID
@@ -69,6 +100,28 @@ ABI 编码和解码函数
- ``msg.value`` (``uint``): 随消息发送的 wei 的数量
- ``tx.gasprice`` (``uint``): 交易的 gas 价格
- ``tx.origin`` (``address``): 交易发送方(完整调用链上的原始发送方)
+=======
+- ``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)
+>>>>>>> english/develop
.. index:: assert, require, revert
@@ -102,9 +155,15 @@ ABI 编码和解码函数
合约相关函数
================
+<<<<<<< HEAD
- ``this`` (当前合约的类型): 当前合约,可明确转换为 ``address`` 或 ``address payable``
- ``super``: 继承层次中高一级的合约
- ``selfdestruct(address payable recipient)``: 销毁当前合约,将其资金发送到给定的地址
+=======
+- ``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)``: send all funds to the given address and (only on EVMs before Cancun or when invoked within the transaction creating the contract) destroy the contract.
+>>>>>>> english/develop
.. index:: type;name, type;creationCode, type;runtimeCode, type;interfaceId, type;min, type;max
@@ -142,6 +201,7 @@ ABI 编码和解码函数
修改器
=========
+<<<<<<< HEAD
- ``pure`` 修饰函数时:不允许修改或访问状态。
- ``view`` 修饰函数时:不允许修改状态。
- ``payable`` 修饰函数时:允许从调用中接收以太币。
@@ -151,4 +211,17 @@ ABI 编码和解码函数
- ``indexed`` 修饰事件参数时:将参数作为 topic 存储。
- ``virtual`` 修饰函数和修改时:允许在派生合约中改变函数或修改器的行为。
- ``override`` 表示该函数、修改器或公共状态变量改变了基类合约中的函数或修改器的行为。
+=======
+- ``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 initialization), 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 f3fc741fe72e..2aabed6ad232 100644
--- a/docs/common-patterns.rst
+++ b/docs/common-patterns.rst
@@ -15,8 +15,15 @@
但这并不推荐,因为这会引入一个潜在的安全风险。
您可能需要参考 :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
在下面的合约中,如果您不再是最富有的人,您将收到取代您成为“最富有”的人发送到合约的资金。
diff --git a/docs/conf.py b/docs/conf.py
index 66e481c3e1fc..5f096a97eab6 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 ------------------------------------------------
@@ -132,7 +135,6 @@ def setup(sphinx):
# documentation.
html_theme_options = {
'logo_only': True,
- 'style_nav_header_background': '#65afff',
'display_version': True,
}
@@ -148,12 +150,12 @@ def setup(sphinx):
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
-html_logo = "logo.svg"
+# html_logo = "logo.svg"
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
-html_favicon = "_static/img/favicon.png"
+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 +164,7 @@ def setup(sphinx):
html_css_files = ["css/toggle.css"]
-html_js_files = ["js/toggle.js"]
+html_js_files = ["js/constants.js", "js/initialize.js", "js/toggle.js"]
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
@@ -210,7 +212,7 @@ def setup(sphinx):
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
+html_show_sphinx = False
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
diff --git a/docs/contracts/constant-state-variables.rst b/docs/contracts/constant-state-variables.rst
index dd46945f7bb6..dfbd2388c4c4 100644
--- a/docs/contracts/constant-state-variables.rst
+++ b/docs/contracts/constant-state-variables.rst
@@ -26,20 +26,29 @@ Constant 和 Immutable 状态变量
.. 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 ref) {
+<<<<<<< HEAD
decimals = decimals_;
// 对不可变量的赋值甚至可以访问一些全局属性。
+=======
+ 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.
+>>>>>>> english/develop
maxBalance = ref.balance;
}
@@ -66,6 +75,7 @@ Constant
Immutable
=========
+<<<<<<< HEAD
声明为 ``immutable`` 的变量比声明为 ``constant`` 的变量受到的限制要少一些。
不可变的变量可以在合约的构造函数中或在声明时被分配一个任意的值。
它们只能被分配一次,并且从那时起,即使在构造时间内也可以被读取。
@@ -80,3 +90,37 @@ Immutable
然而,您可以在合约的构造函数中这样做。
这是对状态变量初始化和构造函数执行顺序的不同解释的一种保障,特别是在继承方面。
+=======
+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/errors.rst b/docs/contracts/errors.rst
index c7ba3355d2f1..769eb1f807ee 100644
--- a/docs/contracts/errors.rst
+++ b/docs/contracts/errors.rst
@@ -1,29 +1,46 @@
-.. index:: ! error, revert, ! selector; of an error
+.. index:: ! error, revert, require, ! selector; of an error
.. _errors:
+<<<<<<< HEAD
*******************************
错误和恢复语句
*******************************
+=======
+*************
+Custom Errors
+*************
+>>>>>>> english/develop
Solidity 中的错误提供了一种方便且省gas的方式来向用户解释为什么一个操作会失败。
它们可以被定义在合约内部和外部(包括接口合约和库合约)。
+<<<<<<< HEAD
它们必须与 :ref:`恢复语句 ` 一起使用,
它导致当前调用中的所有变化被恢复,并将错误数据传回给调用者。
+=======
+They have to be used together with the :ref:`revert statement `
+or the :ref:`require function `.
+In the case of ``revert`` statements, or ``require`` calls where the condition is evaluated to be false,
+all changes in the current call are reverted, and the error data passed back to the caller.
+
+The example below shows custom error usage with the ``revert`` statement in function ``transferWithRevertError``,
+as well as the newer approach with ``require`` in function ``transferWithRequireError``.
+>>>>>>> english/develop
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
- pragma solidity ^0.8.4;
+ pragma solidity ^0.8.26;
/// 转账的余额不足。需要 `required` 数量但只有 `available` 数量可用。
/// @param 可用的余额。
/// @param 需要要求的转帐金额。
error InsufficientBalance(uint256 available, uint256 required);
+ // This will only compile via IR
contract TestToken {
mapping(address => uint) balance;
- function transfer(address to, uint256 amount) public {
+ function transferWithRevertError(address to, uint256 amount) public {
if (amount > balance[msg.sender])
revert InsufficientBalance({
available: balance[msg.sender],
@@ -32,12 +49,28 @@ Solidity 中的错误提供了一种方便且省gas的方式来向用户解释
balance[msg.sender] -= amount;
balance[to] += amount;
}
+ function transferWithRequireError(address to, uint256 amount) public {
+ require(amount <= balance[msg.sender], InsufficientBalance(balance[msg.sender], amount));
+ balance[msg.sender] -= amount;
+ balance[to] += amount;
+ }
// ...
}
+<<<<<<< HEAD
错误不能被重载或覆盖,但是可以被继承。
只要作用域不同,同一个错误可以在多个地方定义。
错误的实例只能使用 ``revert`` 语句创建。
+=======
+Another important detail to mention when it comes to using ``require`` with custom errors, is that memory
+allocation for the error-based revert reason will only happen in the reverting case, which, along with
+optimization of constants and string literals makes this about as gas-efficient as the
+``if (!condition) revert CustomError(args)`` pattern.
+
+Errors cannot be overloaded or overridden but are inherited.
+The same error can be defined in multiple places as long as the scopes are distinct.
+Instances of errors can only be created using ``revert`` statements, or as the second argument to ``require`` functions.
+>>>>>>> english/develop
错误会创建数据,然后通过还原操作传递给调用者,
使其返回到链下组件或在 :ref:`try/catch 语句 ` 中捕获它。
@@ -59,10 +92,16 @@ Solidity 中的错误提供了一种方便且省gas的方式来向用户解释
甚至因为在不同地方定义的错误而使调用者无法区分。
对于外部来说,即ABI,只有错误的名称是相关的,而不是定义它的合约或文件。
+<<<<<<< HEAD
如果您能定义 ``error Error(string)``,
那么语句 ``require(condition, "description");``
将等同于 ``if (!condition) revert Error("description")``。
但是请注意, ``Error`` 是一个内置类型,不能在用户提供的代码中定义。
+=======
+The statement ``require(condition, "description");`` would be equivalent to
+``if (!condition) revert Error("description")`` if you could define ``error Error(string)``.
+Note, however, that ``Error`` is a built-in type and cannot be defined in user-supplied code.
+>>>>>>> english/develop
同样,一个失败的 ``assert`` 或类似的条件将以一个内置的 ``Panic(uint256)`` 类型的错误来恢复。
diff --git a/docs/contracts/events.rst b/docs/contracts/events.rst
index 62a4a0370f2b..690dafcf1fc9 100644
--- a/docs/contracts/events.rst
+++ b/docs/contracts/events.rst
@@ -9,11 +9,22 @@
Solidity事件在EVM的日志功能之上给出了一个抽象。
应用程序可以通过Ethereum客户端的RPC接口订阅和监听这些事件。
+<<<<<<< HEAD
事件是合约的可继承成员。当您调用它们时,
它们会导致参数被存储在交易的日志中--区块链中的一个特殊数据结构。
这些日志与合约的地址相关联,被纳入区块链,
只要有区块可以访问,就会留在那里(目前是永远,但这可能会随着Serenity升级而改变)。
日志及其事件数据不能从合约内部访问(甚至不能从创建它们的合约访问)。
+=======
+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证明,
所以如果外部实体向合约提供这样的证明,它可以检查日志是否真的存在于区块链中。
diff --git a/docs/contracts/function-modifiers.rst b/docs/contracts/function-modifiers.rst
index 387b1c2adcf3..ee400726f581 100644
--- a/docs/contracts/function-modifiers.rst
+++ b/docs/contracts/function-modifiers.rst
@@ -6,8 +6,14 @@
函数修饰器
******************
+<<<<<<< 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`` 时,才能被重载。
@@ -17,7 +23,10 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.1 <0.9.0;
+<<<<<<< HEAD
// 这将报告一个由于废弃的 selfdestruct 而产生的警告
+=======
+>>>>>>> english/develop
contract owned {
constructor() { owner = payable(msg.sender); }
@@ -37,6 +46,7 @@
}
}
+<<<<<<< HEAD
contract destructible is owned {
// 这个合约从 `owned` 合约继承了 `onlyOwner` 修饰器,
// 并将其应用于 `destroy` 函数,
@@ -46,6 +56,8 @@
}
}
+=======
+>>>>>>> english/develop
contract priced {
// 修饰器可以接受参数:
modifier costs(uint price) {
@@ -55,7 +67,7 @@
}
}
- contract Register is priced, destructible {
+ contract Register is priced, owned {
mapping(address => bool) registeredAddresses;
uint price;
@@ -67,6 +79,9 @@
registeredAddresses[msg.sender] = true;
}
+ // This contract inherits the `onlyOwner` modifier from
+ // the `owned` contract. As a result, calls to `changePrice` will
+ // only take effect if they are made by the stored owner.
function changePrice(uint price_) public onlyOwner {
price = price_;
}
@@ -118,7 +133,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 71d913cbbfeb..ed1017acbfb9 100644
--- a/docs/contracts/functions.rst
+++ b/docs/contracts/functions.rst
@@ -233,7 +233,11 @@ Pure 函数能够使用 ``revert()`` 和 ``require()`` 函数来恢复潜在的
因为只有之前在没有 ``view`` 或 ``pure`` 限制的代码中对状态的改变才会被恢复,
并且该代码可以选择捕捉 ``revert`` 而不传递给它。
+<<<<<<< HEAD
这种行为也与 ``STATICCALL`` 操作码一致。
+=======
+This behavior is also in line with the ``STATICCALL`` opcode.
+>>>>>>> english/develop
.. warning::
在EVM层面不可能阻止函数读取状态,只可能阻止它们写入状态
diff --git a/docs/contracts/inheritance.rst b/docs/contracts/inheritance.rst
index f6e22c3a3b3c..4cd34dfc1ee8 100644
--- a/docs/contracts/inheritance.rst
+++ b/docs/contracts/inheritance.rst
@@ -33,14 +33,18 @@ Solidity支持多重继承,包括多态性。
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
+<<<<<<< HEAD
// 这将报告一个由于废弃的 selfdestruct 而产生的警告
+=======
+>>>>>>> english/develop
contract Owned {
- constructor() { owner = payable(msg.sender); }
address payable owner;
+ constructor() { owner = payable(msg.sender); }
}
+<<<<<<< HEAD
// 使用 `is` 从另一个合约派生。派生合约可以访问所有非私有成员,
// 包括内部函数和状态变量,但无法通过 `this` 来外部访问。
@@ -55,25 +59,53 @@ Solidity支持多重继承,包括多态性。
// 这些抽象合约仅用于给编译器提供接口。
// 注意函数没有函数体。
// 如果一个合约没有实现所有函数,则只能用作接口。
+=======
+ // Use `is` to derive from another contract. Derived
+ // contracts can access all non-private members including
+ // internal functions and state variables. These cannot be
+ // accessed externally via `this`, though.
+ contract Emittable is Owned {
+ event Emitted();
+
+ // The keyword `virtual` means that the function can change
+ // its behavior in derived classes ("overriding").
+ function emitEvent() virtual public {
+ if (msg.sender == owner)
+ emit Emitted();
+ }
+ }
+
+ // These abstract contracts are only provided to make the
+ // interface known to the compiler. Note the function
+ // without body. If a contract does not implement all
+ // functions it can only be used as an interface.
+>>>>>>> english/develop
abstract contract Config {
function lookup(uint id) public virtual returns (address adr);
}
-
abstract contract NameReg {
function register(bytes32 name) public virtual;
function unregister() public virtual;
}
+<<<<<<< HEAD
// 多重继承是可能的。请注意, `Owned` 也是 `Destructible` 的基类,
// 但只有一个 `Owned` 实例(就像 C++ 中的虚拟继承)。
contract Named is Owned, Destructible {
+=======
+ // Multiple inheritance is possible. Note that `Owned` is
+ // also a base class of `Emittable`, yet there is only a single
+ // instance of `Owned` (as for virtual inheritance in C++).
+ contract Named is Owned, Emittable {
+>>>>>>> english/develop
constructor(bytes32 name) {
Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);
NameReg(config.lookup(1)).register(name);
}
+<<<<<<< HEAD
// 函数可以被另一个具有相同名称和相同数量/类型输入的函数重载。
// 如果重载函数有不同类型的输出参数,会导致错误。
// 本地和基于消息的函数调用都会考虑这些重载。
@@ -85,79 +117,164 @@ Solidity支持多重继承,包括多态性。
NameReg(config.lookup(1)).unregister();
// 仍然可以调用特定的重载函数。
Destructible.destroy();
+=======
+ // Functions can be overridden by another function with the same name and
+ // the same number/types of inputs. If the overriding function has different
+ // types of output parameters, that causes an error.
+ // Both local and message-based function calls take these overrides
+ // into account.
+ // If you want the function to override, you need to use the
+ // `override` keyword. You need to specify the `virtual` keyword again
+ // if you want this function to be overridden again.
+ function emitEvent() public virtual override {
+ if (msg.sender == owner) {
+ Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);
+ NameReg(config.lookup(1)).unregister();
+ // It is still possible to call a specific
+ // overridden function.
+ Emittable.emitEvent();
+>>>>>>> english/develop
}
}
}
+<<<<<<< HEAD
// 如果构造函数接受参数,
// 则需要在声明(合约的构造函数)时提供,
// 或在派生合约的构造函数位置以修饰器调用风格提供(见下文)。
contract PriceFeed is Owned, Destructible, Named("GoldFeed") {
+=======
+ // If a constructor takes an argument, it needs to be
+ // provided in the header or modifier-invocation-style at
+ // the constructor of the derived contract (see below).
+ contract PriceFeed is Owned, Emittable, Named("GoldFeed") {
+ uint info;
+
+>>>>>>> english/develop
function updateInfo(uint newInfo) public {
if (msg.sender == owner) info = newInfo;
}
+<<<<<<< HEAD
// 在这里,我们只指定了 `override` 而没有 `virtual`。
// 这意味着从 `PriceFeed` 派生出来的合约不能再改变 `destroy` 的行为。
function destroy() public override(Destructible, Named) { Named.destroy(); }
+=======
+ // Here, we only specify `override` and not `virtual`.
+ // This means that contracts deriving from `PriceFeed`
+ // cannot change the behavior of `emitEvent` anymore.
+ function emitEvent() public override(Emittable, Named) { Named.emitEvent(); }
+>>>>>>> english/develop
function get() public view returns(uint r) { return info; }
-
- uint info;
}
+<<<<<<< HEAD
注意,在上面,我们调用 ``Destructible.destroy()`` 来 "转发" 销毁请求。
这样做的方式是有问题的,从下面的例子中可以看出:
+=======
+Note that above, we call ``Emittable.emitEvent()`` to "forward" the
+emit event request. The way this is done is problematic, as
+seen in the following example:
+>>>>>>> english/develop
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
+<<<<<<< HEAD
// 这将报告一个由于废弃的 selfdestruct 而产生的警告
+=======
+>>>>>>> english/develop
- contract owned {
- constructor() { owner = payable(msg.sender); }
+ contract Owned {
address payable owner;
+ constructor() { owner = payable(msg.sender); }
}
- contract Destructible is owned {
- function destroy() public virtual {
- if (msg.sender == owner) selfdestruct(owner);
+ contract Emittable is Owned {
+ event Emitted();
+
+ function emitEvent() virtual public {
+ if (msg.sender == owner) {
+ emit Emitted();
+ }
}
}
+<<<<<<< HEAD
contract Base1 is Destructible {
function destroy() public virtual override { /* 清除操作 1 */ Destructible.destroy(); }
}
contract Base2 is Destructible {
function destroy() public virtual override { /* 清除操作 2 */ Destructible.destroy(); }
+=======
+ contract Base1 is Emittable {
+ event Base1Emitted();
+ function emitEvent() public virtual override {
+ /* Here, we emit an event to simulate some Base1 logic */
+ emit Base1Emitted();
+ Emittable.emitEvent();
+ }
+ }
+
+ contract Base2 is Emittable {
+ event Base2Emitted();
+ function emitEvent() public virtual override {
+ /* Here, we emit an event to simulate some Base2 logic */
+ emit Base2Emitted();
+ Emittable.emitEvent();
+ }
+>>>>>>> english/develop
}
contract Final is Base1, Base2 {
- function destroy() public override(Base1, Base2) { Base2.destroy(); }
+ event FinalEmitted();
+ function emitEvent() public override(Base1, Base2) {
+ /* Here, we emit an event to simulate some Final logic */
+ emit FinalEmitted();
+ Base2.emitEvent();
+ }
}
+<<<<<<< HEAD
调用 ``Final.destroy()`` 时会调用最后的派生重载函数 ``Base2.destroy``,
但是会绕过 ``Base1.destroy``, 解决这个问题的方法是使用 ``super``:
+=======
+A call to ``Final.emitEvent()`` will call ``Base2.emitEvent`` because we specify it
+explicitly in the final override, but this function will bypass
+``Base1.emitEvent``, resulting in the following sequence of events:
+``FinalEmitted -> Base2Emitted -> Emitted``, instead of the expected sequence:
+``FinalEmitted -> Base2Emitted -> Base1Emitted -> Emitted``.
+The way around this is to use ``super``:
+>>>>>>> english/develop
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
+<<<<<<< HEAD
// 这将报告一个由于废弃的 selfdestruct 而产生的警告
+=======
+>>>>>>> english/develop
- contract owned {
- constructor() { owner = payable(msg.sender); }
+ contract Owned {
address payable owner;
+ constructor() { owner = payable(msg.sender); }
}
- contract Destructible is owned {
- function destroy() virtual public {
- if (msg.sender == owner) selfdestruct(owner);
+ contract Emittable is Owned {
+ event Emitted();
+
+ function emitEvent() virtual public {
+ if (msg.sender == owner) {
+ emit Emitted();
+ }
}
}
+<<<<<<< HEAD
contract Base1 is Destructible {
function destroy() public virtual override { /* 清除操作 1 */ super.destroy(); }
}
@@ -165,18 +282,55 @@ Solidity支持多重继承,包括多态性。
contract Base2 is Destructible {
function destroy() public virtual override { /* 清除操作 2 */ super.destroy(); }
+=======
+ contract Base1 is Emittable {
+ event Base1Emitted();
+ function emitEvent() public virtual override {
+ /* Here, we emit an event to simulate some Base1 logic */
+ emit Base1Emitted();
+ super.emitEvent();
+ }
+ }
+
+
+ contract Base2 is Emittable {
+ event Base2Emitted();
+ function emitEvent() public virtual override {
+ /* Here, we emit an event to simulate some Base2 logic */
+ emit Base2Emitted();
+ super.emitEvent();
+ }
+>>>>>>> english/develop
}
contract Final is Base1, Base2 {
- function destroy() public override(Base1, Base2) { super.destroy(); }
+ event FinalEmitted();
+ function emitEvent() public override(Base1, Base2) {
+ /* Here, we emit an event to simulate some Final logic */
+ emit FinalEmitted();
+ super.emitEvent();
+ }
}
+<<<<<<< HEAD
如果 ``Base2`` 调用 ``super`` 的函数,它不会简单在其基类合约上调用该函数。
相反,它在最终的继承关系图谱的上一个基类合约中调用这个函数,
所以它会调用 ``Base1.destroy()``
(注意最终的继承序列是——从最远派生合约开始:Final, Base2, Base1, Destructible, ownerd)。
在类中使用 super 调用的实际函数在当前类的上下文中是未知的,尽管它的类型是已知的。
这与普通的虚拟方法查找类似。
+=======
+If ``Final`` calls a function of ``super``, it does not simply
+call this function on one of its base contracts. Rather, it
+calls this function on the next base contract in the final
+inheritance graph, so it will call ``Base1.emitEvent()`` (note that
+the final inheritance sequence is -- starting with the most
+derived contract: Final, Base2, Base1, Emittable, Owned).
+The actual function that is called when using super is
+not known in the context of the class where it is used,
+although its type is known. This is similar for ordinary
+virtual method lookup.
+>>>>>>> english/develop
.. index:: ! overriding;function
@@ -262,7 +416,12 @@ Solidity支持多重继承,包括多态性。
它从所考虑的合约开始,到提到具有该签名的函数的合约结束,
而该签名没有重载。
+<<<<<<< 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::
@@ -358,8 +517,14 @@ Solidity支持多重继承,包括多态性。
构造函数
============
+<<<<<<< HEAD
构造函数是一个用 ``constructor`` 关键字声明的可选函数,
它在合约创建时被执行,您可以在这里运行合约初始化代码。
+=======
+A constructor is an optional function declared with the ``constructor`` keyword
+which is executed upon contract creation, and where you can run contract
+initialization code.
+>>>>>>> english/develop
在构造函数代码执行之前,如果您用内联编程的方式初始化状态变量,则将其初始化为指定的值;
如果您不用内联编程的方式来初始化,则将其初始化为 :ref:`默认值 `。
@@ -440,12 +605,25 @@ Solidity支持多重继承,包括多态性。
constructor() Base(10 + 10) {}
}
+<<<<<<< HEAD
一种方式是直接在继承列表中给出( ``is Base(7)`` )。
另一种是通过修改器作为派生构造函数的一部分被调用的方式( ``Base(_y * _y)`` )。
如果构造函数参数是一个常量,并且定义了合约的行为或描述了它,那么第一种方式更方便。
如果基类合约的构造函数参数依赖于派生合约的参数,则必须使用第二种方式。
参数必须在继承列表中或在派生构造函数中以修饰器的形式给出。
在两个地方都指定参数是一个错误。
+=======
+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.
+>>>>>>> english/develop
如果一个派生合约没有指定其所有基类合约的构造函数的参数,那么它必须被声明为 abstract 类型。在这种情况下,
当另一个合约从它派生时,其他合约的继承列表或构造函数必须为所有没有指定参数的基类合约提供必要的参数
@@ -535,9 +713,20 @@ Solidity 借鉴了 Python 的方式并且使用 "`C3 线性化 >>>>>> english/develop
diff --git a/docs/contracts/interfaces.rst b/docs/contracts/interfaces.rst
index 06c617752aa7..472be69f72a7 100644
--- a/docs/contracts/interfaces.rst
+++ b/docs/contracts/interfaces.rst
@@ -60,7 +60,11 @@
在接口合约和其他类似合约的结构中定义的类型可以从其他合约中访问: ``Token.TokenType`` 或 ``Token.Coin``。
+<<<<<<< HEAD
.. 警告:
+=======
+.. warning::
+>>>>>>> english/develop
接口合约从 :doc:`Solidity 0.5.0 <050-breaking-changes>` 开始支持 ``enum`` 类型,
请确保pragma版本至少指定这个版本。
diff --git a/docs/contributing.rst b/docs/contributing.rst
index 328387afa332..07dc14a69a31 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -29,7 +29,11 @@
- 每周三下午3点,中欧标准时间/中欧夏令时间。
+<<<<<<< HEAD
会议在 `Jitsi `_ 举行。
+=======
+The call takes place on `Jitsi `_.
+>>>>>>> english/develop
如何报告问题
====================
@@ -38,11 +42,19 @@
`GitHub问题跟踪器 `_。
当报告问题时,请提及以下细节:
+<<<<<<< HEAD
* Solidity版本。
* 源代码(如果可以的话)。
* 操作系统。
* 重现该问题的步骤。
* 实际行为与预期行为。
+=======
+* Solidity version.
+* Source code (if applicable).
+* Operating system.
+* Steps to reproduce the issue.
+* Actual vs. expected behavior.
+>>>>>>> english/develop
将导致问题的源代码减少到最低限度总是非常有帮助的,有时甚至可以澄清一个误解。
@@ -82,10 +94,16 @@
先决条件
-------------
+<<<<<<< HEAD
为了运行所有的编译器测试,您可能想选择性地安装一些依赖项
( `evmone `_,
`libz3 `_, 和
`libhera `_)。
+=======
+For running all compiler tests you may want to optionally install a few
+dependencies (`evmone `_,
+`libz3 `_).
+>>>>>>> english/develop
在 macOS 系统上,一些测试脚本需要安装 GNU 核心工具。
可以使用 Homebrew 很简单地完成安装: ``brew install coreutils``。
@@ -103,9 +121,16 @@ Solidity包括不同类型的测试,其中大部分捆绑在
`Boost C++测试框架 `_ 应用程序 ``soltest``。
运行 ``build/test/soltest`` 或其包装器 ``scripts/soltest.sh`` 对大多数变化来说是足够的。
+<<<<<<< HEAD
``./scripts/tests.sh`` 脚本自动执行大多数Solidity测试,
包括那些捆绑在 `Boost C++测试框架 `_ 应用程序 ``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 `_ 的位置,以运行语义测试。
@@ -116,12 +141,17 @@ Solidity包括不同类型的测试,其中大部分捆绑在
``evmone`` 主要用于运行语义和gas测试。
如果您没有安装它,您可以通过向 ``scripts/soltest.sh`` 传递 ``--no-semantic-tests`` 标志来跳过这些测试。
+<<<<<<< HEAD
运行Ewasm测试默认是禁用的,可以通过 ``./scripts/soltest.sh --ewasm`` 明确启用,
要求 `hera `_ 被 ``soltest`` 找到。
定位 ``hera`` 库的机制与 ``evmone`` 相同,只是用于指定明确位置的变量被称为 ``ETH_HERA``。
``evmone`` 和 ``hera`` 库的文件名后缀都应该
是Linux上的 ``.so``,Windows系统上的 ``.dll``,MacOS上的 ``.dylib``。
+=======
+The ``evmone`` library should end with the file name
+extension ``.so`` on Linux, ``.dll`` on Windows systems and ``.dylib`` on macOS.
+>>>>>>> english/develop
为了运行SMT测试, ``libz3`` 库必须被安装,并在编译器配置阶段被 ``cmake`` 可以找到。
@@ -231,10 +261,17 @@ CI运行额外的测试(包括 ``solc-js`` 和测试第三方Solidity框架)
它为失败的测试提供了几种选择:
+<<<<<<< HEAD
- ``edit``: ``isoltest`` 试图在一个编辑器中打开合约,以便您可以调整它。它或者使用命令行上给出的编辑器(如 ``isoltest --editor /path/to/editor``),或者在环境变量 ``EDITOR`` 中,或者只是 ``/usr/bin/editor`` (按这个顺序)。
- ``update``: 更新测试中的合约。这将会移除包含了不匹配异常的注解,或者增加缺失的预想结果。然后测试会重新开始。
- ``skip``: 跳过这一特定测试的执行。
- ``quit``: 退出 ``isoltest``。
+=======
+- ``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``.
+>>>>>>> english/develop
所有这些选项都适用于当前的合约,除了 ``quit``,它可以停止整个测试过程。
@@ -261,6 +298,62 @@ CI运行额外的测试(包括 ``solc-js`` 和测试第三方Solidity框架)
不要把一个以上的合约放在一个文件中,除非您在测试继承或跨合约的调用。
每个文件应该测试您的新功能的一个方面。
+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.
通过 AFL 运行 Fuzzer
==========================
@@ -336,11 +429,19 @@ Fuzzing 是一种测试技术,它可以通过运行多少不等的随机输入
# 从文件中摘录:
path/to/solidity/scripts/isolate_tests.py path/to/solidity/docs
+<<<<<<< HEAD
AFL 的文档指出,账册(初始的输入文件)不应该太大。
每个文件本身不应该超过 1 kB,并且每个功能最多只能有一个输入文件;
所以最好从少量的输入文件开始。
此外还有一个叫做 ``afl-cmin`` 的工具,
可以将输入文件整理为可以具有近似行为的二进制代码。
+=======
+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
现在运行 fuzzer( ``-m`` 参数将使用的内存大小扩展为 60 MB):
@@ -475,11 +576,17 @@ Solidity论坛作为提出和讨论新的语言功能及其在早期构思阶段
我们也在论坛中分享反馈调查和其他与语言设计相关的内容。
+<<<<<<< HEAD
如果您想知道团队在实施新功能方面的情况,
您可以在 `Solidity Github项目 `_ 中关注实施状况。
设计积压中的问题需要进一步规范,将在语言设计电话会议或常规团队电话会议中讨论。
您可以通过从默认分支( `develop` )到 `breaking 分支 `_
来查看下一个突破性版本即将发生的变化。
+=======
+If you want to know where the team is standing in terms or implementing new features, you can follow the implementation status in the `Solidity GitHub project `_.
+Issues in the design backlog need further specification and will either be discussed in a language design call or in a regular team call. You can
+see the upcoming changes for the next breaking release by changing from the default branch (`develop`) to the `breaking branch `_.
+>>>>>>> english/develop
对于特殊情况和问题,您可以通过 `Solidity-dev Gitter 频道 `_ 与我们联系,
- 这是一个专门用于围绕 Solidity 编译器和语言开发的聊天室。
diff --git a/docs/control-structures.rst b/docs/control-structures.rst
index 514fa09599a8..a09cdf9b1687 100644
--- a/docs/control-structures.rst
+++ b/docs/control-structures.rst
@@ -330,13 +330,24 @@ Solidity 内部允许元组 (tuple) 类型,也就是一个在编译时元素
现在这是不允许的,所以两边必须有相同数量的元素。
.. 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
数组和结构体的复杂情况
----------------------
+<<<<<<< HEAD
对于像数组和结构体这样的非值类型,包括 ``bytes`` 和 ``string``,赋值的语义更为复杂,
详见 :ref:`数据位置和赋值行为 `。
+=======
+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
在下面的例子中,调用 ``g(x)`` 对 ``x`` 没有影响,
因为它在内存中创建了一个独立的存储值的副本。然而, ``h(x)`` 成功地修改了 ``x``,
@@ -465,7 +476,11 @@ Solidity 中的作用域规则遵循了 C99(与其他很多语言一样):
从Solidity 0.8.0开始,在默认情况下所有的算术运算都会在上溢和下溢时还原,
从而使这些库的使用变得没有必要。
+<<<<<<< HEAD
为了获得以前的行为,可以使用一个 ``未检查(unchecked)`` 区块。
+=======
+To obtain the previous behavior, an ``unchecked`` block can be used:
+>>>>>>> english/develop
.. code-block:: solidity
@@ -539,8 +554,15 @@ Solidity 使用状态恢复异常来处理错误。
内置的错误 ``Error(string)`` 和 ``Panic(uint256)`` 被特殊函数使用,
解释如下。 ``Error`` 用于 "常规" 错误条件,而 ``Panic`` 用于在无错误代码中不应该出现的错误。
+<<<<<<< HEAD
通过 ``assert`` 引起Panic异常和通过 ``require`` 引起Error异常
-------------------------------------------------------------
+=======
+.. _assert-and-require-statements:
+
+Panic via ``assert`` and Error via ``require``
+----------------------------------------------
+>>>>>>> english/develop
快捷函数 ``assert`` 和 ``require`` 可以用来检查条件,如果不符合条件就抛出一个异常。
@@ -566,17 +588,38 @@ Assert应该只用于测试内部错误,以及检查不变量。
#. 0x41: 如果您分配了太多的内存空间或创建了一个太大的数组。
#. 0x51: 如果您调用一个零初始化的内部函数类型的变量。
+<<<<<<< HEAD
``require`` 函数要么创造一个没有任何数据的错误,
要么创造一个 ``Error(string)`` 类型的错误。
它应该被用来确保在执行之前无法检测到的有效条件。
这包括对输入的条件或调用外部合约的返回值。
+=======
+The ``require`` function provides three overloads:
+
+1. ``require(bool)`` which will revert without any data (not even an error selector).
+2. ``require(bool, string)`` which will revert with an ``Error(string)``.
+3. ``require(bool, error)`` which will revert with the custom, user supplied error provided as the second argument.
+>>>>>>> english/develop
.. note::
+ ``require`` arguments are evaluated unconditionally, so take special care to make sure that
+ they are not expressions with unexpected side-effects.
+ For example, in ``require(condition, CustomError(f()));`` and ``require(condition, f());``,
+ function ``f()`` will be called regardless of whether the supplied condition is ``true`` or ``false``.
+<<<<<<< HEAD
目前不能将自定义错误与 ``require`` 结合使用。
请使用 ``if (!condition) revert CustomError();`` 代替。
在下列情况下,编译器会产生一个 ``Error(string)`` 异常(或者没有数据的异常)。
+=======
+.. note::
+ Using custom errors with ``require`` is only supported by the via IR pipeline, i.e. compilation via Yul.
+ For the legacy pipeline, please use ``if (!condition) revert CustomError();`` instead.
+
+An ``Error(string)`` exception (or an exception without data) is generated
+by the compiler in the following situations:
+>>>>>>> english/develop
#. 调用 ``require(x)``,其中 ``x`` 的值为 ``false``。
#. 如果您使用 ``revert()`` 或 ``revert("错误描述")``。
@@ -595,11 +638,19 @@ Assert应该只用于测试内部错误,以及检查不变量。
#. 如果您使用 ``new`` 关键字创建一个合约,
但合约创建 :ref:`没有正常完成 `。
+<<<<<<< HEAD
您可以选择为 ``require`` 提供一个信息字符串,但不能为 ``assert`` 提供。
.. note::
如果您没有给 ``require`` 提供一个字符串参数,它将以空的错误数据进行还原,
甚至不包括错误选择器。
+=======
+You can optionally provide a message string or a custom error to ``require``, but not to ``assert``.
+
+.. note::
+ If you do not provide a string or custom error argument to ``require``, it will revert
+ with empty error data, not even including the error selector.
+>>>>>>> english/develop
下面的例子显示了如何使用 ``require`` 来检查输入的条件
@@ -616,8 +667,14 @@ Assert应该只用于测试内部错误,以及检查不变量。
require(msg.value % 2 == 0, "Even value required.");
uint balanceBeforeTransfer = address(this).balance;
addr.transfer(msg.value / 2);
+<<<<<<< HEAD
// 由于转账失败后抛出异常并且不能在这里回调,
// 因此我们应该没有办法仍然有一半的钱。
+=======
+ // Since transfer throws an exception on failure and
+ // cannot call back here, there should be no way for us to
+ // still have half of the Ether.
+>>>>>>> english/develop
assert(address(this).balance == balanceBeforeTransfer - msg.value / 2);
return address(this).balance;
}
@@ -648,8 +705,13 @@ Assert应该只用于测试内部错误,以及检查不变量。
revert CustomError(arg1, arg2);
+<<<<<<< HEAD
出于向后兼容的原因,还有一个 ``revert()`` 函数,
它使用圆括号并接受一个字符串:
+=======
+For backward-compatibility reasons, there is also the ``revert()`` function, which uses parentheses
+and accepts a string:
+>>>>>>> english/develop
revert();
revert("description");
diff --git a/docs/examples/blind-auction.rst b/docs/examples/blind-auction.rst
index 1e044dd62592..24a588e8cf9b 100644
--- a/docs/examples/blind-auction.rst
+++ b/docs/examples/blind-auction.rst
@@ -13,10 +13,19 @@
简单的公开拍卖
===================
+<<<<<<< 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
@@ -78,17 +87,33 @@
if (block.timestamp > auctionEndTime)
revert AuctionAlreadyEnded();
+<<<<<<< HEAD
// 如果出价不高,就把钱送回去
//(revert语句将恢复这个函数执行中的所有变化,
// 包括它已经收到钱)。
+=======
+ // If the bid is not higher, send the
+ // Ether back (the revert statement
+ // will revert all changes in this
+ // function execution including
+ // it having received the Ether).
+>>>>>>> english/develop
if (msg.value <= highestBid)
revert BidNotHighEnough(highestBid);
if (highestBid != 0) {
+<<<<<<< HEAD
// 简单地使用 highestBidder.send(highestBid)
// 返还出价时,是有安全风险的,
// 因为它可能执行一个不受信任的合约。
// 让接收方自己取钱总是比较安全的。
+=======
+ // Sending back the Ether by simply using
+ // highestBidder.send(highestBid) is a security risk
+ // because it could execute an untrusted contract.
+ // It is always safer to let the recipients
+ // withdraw their Ether themselves.
+>>>>>>> english/develop
pendingReturns[highestBidder] += highestBid;
}
highestBidder = msg.sender;
@@ -157,9 +182,23 @@
竞标者必须公开他们的出价:他们发送未加密的值,
合约检查出价的哈希值是否与竞标期间提供的值相同。
+<<<<<<< HEAD
另一个挑战是如何使拍卖同时做到 **绑定和秘密** :
唯一能阻止竞标者在赢得拍卖后不付款的方式是,让他们将钱和竞标一起发出。
但由于资金转移在以太坊中不能被隐藏,因此任何人都可以看到转移的资金。
+=======
+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
下面的合约通过接受任何大于最高出价的值来解决这个问题。
当然,因为这只能在揭示阶段进行检查,有些出价可能是 **无效** 的,
diff --git a/docs/examples/micropayment.rst b/docs/examples/micropayment.rst
index d94d6262292a..b3777dca80fe 100644
--- a/docs/examples/micropayment.rst
+++ b/docs/examples/micropayment.rst
@@ -49,7 +49,11 @@ Alice不需要与以太坊网络交互来签署交易,这个过程是完全离
签署内容
------------
+<<<<<<< HEAD
对于履行付款的合同,签署的信息必须包括:
+=======
+For a contract that fulfills payments, the signed message must include:
+>>>>>>> english/develop
1. 收件人的钱包地址。
2. 要转移的金额。
@@ -69,6 +73,7 @@ Alice可以通过在消息中包含合约的地址来防止这种攻击,
并且只有包含合约地址本身的消息才会被接受。
您可以在本节末尾的完整合约的 ``claimPayment()`` 函数的前两行找到这个例子。
+<<<<<<< HEAD
组装参数
---------
@@ -78,6 +83,21 @@ Alice可以通过在消息中包含合约的地址来防止这种攻击,
`ethereumjs-abi `_ 库提供了一个名为 ``soliditySHA3`` 的函数,
模仿Solidity的 ``keccak256`` 函数应用于使用 ``abi.encodePacked`` 编码的参数的行为。
这里有一个JavaScript函数,为 ``ReceiverPays`` 的例子创建了适当的签名。
+=======
+Furthermore, instead of destroying the contract by calling ``selfdestruct``,
+which is currently deprecated, we will disable the contract's functionalities by freezing it,
+resulting in the reversion of any call after it being frozen.
+
+Packing arguments
+-----------------
+
+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
@@ -130,30 +150,65 @@ web3.js 产生的签名是 ``r``, ``s`` 和 ``v`` 的拼接的,
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
+<<<<<<< HEAD
// 这将报告一个由于废弃的 selfdestruct 而产生的警告
contract ReceiverPays {
address owner = msg.sender;
+=======
+>>>>>>> english/develop
+
+ contract Owned {
+ address payable owner;
+ constructor() {
+ owner = payable(msg.sender);
+ }
+ }
+
+ contract Freezable is Owned {
+ bool private _frozen = false;
+
+ modifier notFrozen() {
+ require(!_frozen, "Inactive Contract.");
+ _;
+ }
+
+ function freeze() internal {
+ if (msg.sender == owner)
+ _frozen = true;
+ }
+ }
+ contract ReceiverPays is Freezable {
mapping(uint256 => bool) usedNonces;
constructor() payable {}
- function claimPayment(uint256 amount, uint256 nonce, bytes memory signature) external {
+ function claimPayment(uint256 amount, uint256 nonce, bytes memory signature)
+ external
+ notFrozen
+ {
require(!usedNonces[nonce]);
usedNonces[nonce] = true;
// 这将重新创建在客户端上签名的信息。
bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this)));
-
require(recoverSigner(message, signature) == owner);
-
payable(msg.sender).transfer(amount);
}
+<<<<<<< HEAD
/// 销毁合约并收回剩余的资金。
function shutdown() external {
+=======
+ /// freeze the contract and reclaim the leftover funds.
+ function shutdown()
+ external
+ notFrozen
+ {
+>>>>>>> english/develop
require(msg.sender == owner);
- selfdestruct(payable(msg.sender));
+ freeze();
+ payable(msg.sender).transfer(address(this).balance);
}
/// 签名方法。
@@ -182,7 +237,6 @@ web3.js 产生的签名是 ``r``, ``s`` 和 ``v`` 的拼接的,
returns (address)
{
(uint8 v, bytes32 r, bytes32 s) = splitSignature(sig);
-
return ecrecover(message, v, r, s);
}
@@ -282,11 +336,19 @@ Alice通过向Bob发送签名信息进行支付。
关闭支付通道
------------
+<<<<<<< HEAD
当Bob准备好接收他的资金时,
是时候通过调用智能合约上的 ``close`` 函数关闭支付通道了。
关闭通道会向接收者支付欠他们的以太币,并销毁合约,
将任何剩余的以太币送回给Alice。
为了关闭通道,Bob需要提供一个由Alice签名的信息。
+=======
+When Bob is ready to receive his funds, it is time to
+close the payment channel by calling a ``close`` function on the smart contract.
+Closing the channel pays the recipient the Ether they are owed and
+deactivates the contract by freezing it, sending any remaining Ether back to Alice. To
+close the channel, Bob needs to provide a message signed by Alice.
+>>>>>>> english/develop
智能合约必须验证该消息是否包含发送者的有效签名。
进行这种验证的过程与接收者使用签名的过程相同。
@@ -298,10 +360,17 @@ Solidity函数 ``isValidSignature`` 和 ``recoverSigner`` 的工作方式
如果允许发送者调用这个函数,他们可以提供一个金额较低的签名消息,
骗取接收者的欠款。
+<<<<<<< HEAD
该函数会验证签名的信息与给定的参数是否相符。
如果一切正常,接收者就会收到他们的那部分以太币,
而剩下的以太币将通过 ``selfdestruct`` 发送给发送者。
您可以在完整的合约中看到 ``close`` 函数。
+=======
+The function verifies the signed message matches the given parameters.
+If everything checks out, the recipient is sent their portion of the Ether,
+and the sender is sent the remaining funds via a ``transfer``.
+You can see the ``close`` function in the full contract.
+>>>>>>> english/develop
通道到期
--------
@@ -322,11 +391,32 @@ Alice需要一个方法来收回她的托管资金。在合同部署的时候,
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
+<<<<<<< HEAD
// 这将报告一个由于废弃的 selfdestruct 而产生的警告
contract SimplePaymentChannel {
address payable public sender; // 发送付款的账户。
address payable public recipient; // 接收付款的账户。
uint256 public expiration; // 超时时间,以防接收者永不关闭支付通道。
+=======
+
+ contract Frozeable {
+ bool private _frozen = false;
+
+ modifier notFrozen() {
+ require(!_frozen, "Inactive Contract.");
+ _;
+ }
+
+ function freeze() internal {
+ _frozen = true;
+ }
+ }
+
+ contract SimplePaymentChannel is Frozeable {
+ address payable public sender; // The account sending payments.
+ address payable public recipient; // The account receiving the payments.
+ uint256 public expiration; // Timeout in case the recipient never closes.
+>>>>>>> english/develop
constructor (address payable recipientAddress, uint256 duration)
payable
@@ -336,29 +426,58 @@ Alice需要一个方法来收回她的托管资金。在合同部署的时候,
expiration = block.timestamp + duration;
}
+<<<<<<< HEAD
/// 接收者可以在任何时候通过提供发送者签名的金额来关闭通道,
/// 接收者将获得该金额,其余部分将返回发送者。
function close(uint256 amount, bytes memory signature) external {
+=======
+ /// the recipient can close the channel at any time by presenting a
+ /// signed amount from the sender. the recipient will be sent that amount,
+ /// and the remainder will go back to the sender
+ function close(uint256 amount, bytes memory signature)
+ external
+ notFrozen
+ {
+>>>>>>> english/develop
require(msg.sender == recipient);
require(isValidSignature(amount, signature));
recipient.transfer(amount);
- selfdestruct(sender);
+ freeze();
+ sender.transfer(address(this).balance);
}
+<<<<<<< HEAD
/// 发送者可以在任何时候延长到期时间。
function extend(uint256 newExpiration) external {
+=======
+ /// the sender can extend the expiration at any time
+ function extend(uint256 newExpiration)
+ external
+ notFrozen
+ {
+>>>>>>> english/develop
require(msg.sender == sender);
require(newExpiration > expiration);
expiration = newExpiration;
}
+<<<<<<< HEAD
/// 如果达到超时时间而接收者没有关闭通道,
/// 那么以太就会被释放回给发送者。
function claimTimeout() external {
+=======
+ /// if the timeout is reached without the recipient closing the channel,
+ /// then the Ether is released back to the sender.
+ function claimTimeout()
+ external
+ notFrozen
+ {
+>>>>>>> english/develop
require(block.timestamp >= expiration);
- selfdestruct(sender);
+ freeze();
+ sender.transfer(address(this).balance);
}
function isValidSignature(uint256 amount, bytes memory signature)
@@ -367,6 +486,7 @@ Alice需要一个方法来收回她的托管资金。在合同部署的时候,
returns (bool)
{
bytes32 message = prefixed(keccak256(abi.encodePacked(this, amount)));
+<<<<<<< HEAD
// 检查签名是否来自付款方。
return recoverSigner(message, signature) == sender;
@@ -374,6 +494,14 @@ Alice需要一个方法来收回她的托管资金。在合同部署的时候,
/// 下面的所有功能是取自 '创建和验证签名' 的章节。
+=======
+ // check that the signature is from the payment sender
+ return recoverSigner(message, signature) == sender;
+ }
+
+ /// All functions below this are just taken from the chapter
+ /// 'creating and verifying signatures' chapter.
+>>>>>>> english/develop
function splitSignature(bytes memory sig)
internal
pure
@@ -389,7 +517,6 @@ Alice需要一个方法来收回她的托管资金。在合同部署的时候,
// 最后一个字节(下一个32字节的第一个字节)。
v := byte(0, mload(add(sig, 96)))
}
-
return (v, r, s);
}
@@ -399,7 +526,6 @@ Alice需要一个方法来收回她的托管资金。在合同部署的时候,
returns (address)
{
(uint8 v, bytes32 r, bytes32 s) = splitSignature(sig);
-
return ecrecover(message, v, r, s);
}
diff --git a/docs/examples/modular.rst b/docs/examples/modular.rst
index 82b0a189a2b2..0abcdf63e368 100644
--- a/docs/examples/modular.rst
+++ b/docs/examples/modular.rst
@@ -4,6 +4,7 @@
模块化合约
***********
+<<<<<<< HEAD
用模块化的方法来构建您的合约,可以帮助减少复杂性,提高可读性,
这将有助于在开发和代码审查中发现错误和漏洞。
如果您单独指定且控制每个模块的行为,您必须考虑的相互作用只是模块之间的相互作用,
@@ -13,6 +14,20 @@
可以正确地跟踪账户的余额。
很容易验证 ``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
diff --git a/docs/examples/safe-remote.rst b/docs/examples/safe-remote.rst
index aca8e7431477..aea51f1e4a99 100644
--- a/docs/examples/safe-remote.rst
+++ b/docs/examples/safe-remote.rst
@@ -4,6 +4,7 @@
安全的远程购买
********************
+<<<<<<< HEAD
目前,远程购买商品需要多方相互信任。最简单的关系涉及一个卖家和一个买家。
买方希望从卖方那里收到一件物品,卖方希望得到金钱(或等价物)作为回报。
这里面有问题的部分是的运输。没有办法确定物品是否到达买方手中。
@@ -13,6 +14,22 @@
只要发生这种情况,钱就会一直锁在合同里面,直到买方确认收到物品。
之后,买方会得到退回的资金(他们押金的一半),卖方得到三倍的资金(他们的押金加上物品的价值)。
这背后的想法是,双方都有动力去解决这个问题,否则他们的钱就会被永远锁定。
+=======
+Purchasing goods remotely currently requires multiple parties that need to trust each other.
+The simplest configuration involves a seller and a buyer. The buyer would like to receive
+an item from the seller and the seller would like to get some compensation, e.g. Ether,
+in return. The problematic part is the shipment here: There is no way to determine for
+sure that the item arrived at the buyer.
+
+There are multiple ways to solve this problem, but all fall short in one or the other way.
+In the following example, both parties have to put twice the value of the item into the
+contract as escrow. As soon as this happened, the Ether will stay locked inside
+the contract until the buyer confirms that they received the item. After that,
+the buyer is returned the value (half of their deposit) and the seller gets three
+times the value (their deposit plus the value). The idea behind
+this is that both parties have an incentive to resolve the situation or otherwise
+their Ether is locked forever.
+>>>>>>> english/develop
这个合约当然不能解决问题,但它概述了如何在合约内使用类似状态机的构造。
diff --git a/docs/ext/remix_code_links.py b/docs/ext/remix_code_links.py
index 31a5667689b8..55fc0ef5c26f 100644
--- a/docs/ext/remix_code_links.py
+++ b/docs/ext/remix_code_links.py
@@ -27,10 +27,10 @@ def remix_code_url(source_code, language, solidity_version):
def build_remix_link_node(url):
reference_node = docutils.nodes.reference('', 'open in Remix', internal=False, refuri=url, target='_blank')
- reference_node.set_class('remix-link')
+ reference_node['classes'].append('remix-link')
paragraph_node = docutils.nodes.paragraph()
- paragraph_node.set_class('remix-link-container')
+ paragraph_node['classes'].append('remix-link-container')
paragraph_node.append(reference_node)
return paragraph_node
diff --git a/docs/grammar/SolidityLexer.g4 b/docs/grammar/SolidityLexer.g4
index 61f00d474d66..1633bc01dc26 100644
--- a/docs/grammar/SolidityLexer.g4
+++ b/docs/grammar/SolidityLexer.g4
@@ -297,14 +297,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' | 'prevrandao'
- | '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 0d2ebced0467..f93d8c1cb748 100644
--- a/docs/grammar/SolidityParser.g4
+++ b/docs/grammar/SolidityParser.g4
@@ -16,12 +16,13 @@ sourceUnit: (
| contractDefinition
| interfaceDefinition
| libraryDefinition
- | freeFunctionDefinition
+ | functionDefinition
| constantVariableDeclaration
| structDefinition
| enumDefinition
| userDefinedValueTypeDefinition
| errorDefinition
+ | eventDefinition
)* EOF;
//@doc: inline
@@ -85,7 +86,7 @@ inheritanceSpecifier: name=identifierPath arguments=callArgumentList?;
*/
contractBodyElement:
constructorDefinition
- | contractFunctionDefinition
+ | functionDefinition
| modifierDefinition
| fallbackFunctionDefinition
| receiveFunctionDefinition
@@ -151,11 +152,17 @@ stateMutability: Pure | View | Payable;
*/
overrideSpecifier: Override (LParen overrides+=identifierPath (Comma overrides+=identifierPath)* RParen)?;
/**
+<<<<<<< HEAD
* 合约,库和接口功能的定义。
* 根据定义函数的上下文,可能会有进一步的限制。
* 例如,接口中的函数必须是未实现的,也就是说,不能包含主体块。
+=======
+ * The definition of contract, library, interface or free functions.
+ * Depending on the context in which the function is defined, further restrictions may apply,
+ * e.g. functions in interfaces have to be unimplemented, i.e. may not contain a body block.
+>>>>>>> english/develop
*/
-contractFunctionDefinition
+functionDefinition
locals[
boolean visibilitySet = false,
boolean mutabilitySet = false,
@@ -176,6 +183,7 @@ locals[
(Semicolon | body=block);
/**
+<<<<<<< HEAD
* 自由函数的定义。
*/
freeFunctionDefinition:
@@ -189,6 +197,11 @@ locals[
* 修改器的定义。
* 注意,在修改器的主体块中,下划线不能作为标识符使用,
* 而是作为占位符语句,用于修改器所应用的函数主体。
+=======
+ * The definition of a modifier.
+ * Note that within the body block of a modifier, the underscore cannot be used as identifier,
+ * but is used as placeholder statement for the body of a function to which the modifier is applied.
+>>>>>>> english/develop
*/
modifierDefinition
locals[
@@ -259,7 +272,7 @@ structMember: type=typeName name=identifier Semicolon;
/**
* 一个枚举的定义。可以出现在源代码单元的顶层,也可以出现在合约,库或接口中。
*/
-enumDefinition: Enum name=identifier LBrace enumValues+=identifier (Comma enumValues+=identifier)* RBrace;
+enumDefinition: Enum name=identifier LBrace enumValues+=identifier (Comma enumValues+=identifier)* RBrace;
/**
* 用户自定义的值类型的定义。可以出现在源代码单元的顶层,也可以出现在合约,库或接口中。
*/
@@ -345,7 +358,14 @@ userDefinableOperator:
* 使用指令将库函数和自由函数附加到类型上。
* 可以在合约和库中以及文件层面中出现。
*/
-usingDirective: Using (identifierPath | (LBrace identifierPath (As userDefinableOperator)? (Comma identifierPath (As userDefinableOperator)?)* RBrace)) For (Mul | typeName) Global? Semicolon;
+usingDirective:
+ Using (
+ identifierPath
+ | (LBrace usingAliases (Comma usingAliases)* RBrace)
+ ) For (Mul | typeName) Global? Semicolon;
+
+usingAliases: identifierPath (As userDefinableOperator)?;
+
/**
* 一个类型名称可以是一个基本类型,一个函数类型,一个映射类型,
* 一个用户定义的类型(如合约类型或结构体类型)或一个数组类型。
@@ -401,7 +421,7 @@ expression:
| New typeName # NewExpr
| tupleExpression # Tuple
| inlineArrayExpression # InlineArray
- | (
+ | (
identifier
| literal
| literalWithSubDenomination
diff --git a/docs/index.rst b/docs/index.rst
index fd8fef0295db..47878df3cb44 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -82,8 +82,14 @@ Solidity 是静态类型语言,支持继承,库和复杂的用户自定义
`以太坊开发者资源 `_ 可以为您提供有关以太坊的更多文档,
以及各种教程、工具和开发框架。
+<<<<<<< HEAD
如果您有任何问题,可以在 `以太坊 StackExchange `_ 上,
或者在我们的 `Gitter 频道 `_ 上搜索答案或提问。
+=======
+If you have any questions, you can try searching for answers or asking on the
+`Ethereum StackExchange `_,
+or our `Gitter channel `_.
+>>>>>>> english/develop
.. _translations:
diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst
index 5676f0b3bc5d..0aa566780a2d 100644
--- a/docs/installing-solidity.rst
+++ b/docs/installing-solidity.rst
@@ -9,6 +9,7 @@
版本
==========
+<<<<<<< HEAD
Solidity 的版本遵循 `语义化版本原则 `_。此外,
主版本(例如:0.x.y)的补丁级版本的发布不会包含重大更改。这意味着用 0.x.y 版本
编译的代码可望用 0.x.z 版本编译,其中 z > y。
@@ -19,6 +20,20 @@ Solidity 的版本遵循 `语义化版本原则 `_。此外
并不保证总是有效的。尽管我们尽了最大努力,
它们仍可能含有未记录的或重大的修改,这些修改不会成为实际发布版本的一部分。
它们也不会用于生产。
+=======
+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.
+>>>>>>> english/develop
当开发智能合约时,您应该使用最新版本的 Solidity。这是因为重大的改变,
以及新的特性和错误修复是定期引入的。
@@ -29,6 +44,7 @@ Remix
*我们推荐使用 Remix 来开发简单合约和快速学习 Solidity。*
+<<<<<<< HEAD
`Remix 可以在线使用 `_,而无需安装任何东西。
如果您想离线使用,可按 https://github.com/ethereum/remix-live/tree/gh-pages
的页面说明下载 ``.zip`` 文件来使用。 Remix 也是一个方便的选择,
@@ -37,6 +53,17 @@ Remix
本页的进一步选项详细说明了在您的计算机上安装 Solidity 命令行编译器。
如果您刚好要处理大型合约,或者需要更多的编译选项,
那么您应该选择使用一个命令行编译器。
+=======
+`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:
@@ -52,6 +79,13 @@ npm / Node.js
这意味着两者使用相同的编译器源代码。
因此, `solc-js` 可以直接用于JavaScript项目(如 Remix) 具体介绍请参考 `solc-js` 代码库。
+<<<<<<< HEAD
+=======
+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
@@ -59,42 +93,80 @@ npm / Node.js
.. note::
+<<<<<<< HEAD
在命令行中,可执行文件被命名为 ``solcjs``。
``solcjs`` 的命令行选项与 ``solc`` 和一些工具(如 ``geth``)是不兼容的,
因此不要期望 ``solcjs`` 能像 ``solc`` 一样工作。
+=======
+ The command-line executable is named ``solcjs``.
+
+ The command-line options of ``solcjs`` are not compatible with ``solc`` and tools (such as ``geth``)
+ expecting the behavior of ``solc`` will not work with ``solcjs``.
+>>>>>>> english/develop
Docker
======
+<<<<<<< HEAD
Solidity构建的Docker镜像可以使用从 ``ethereum`` 组织获得的 ``solc`` 镜像。
使用 ``stable`` 标签获取最新发布的版本,使用 ``nightly`` 标签获取开发分支中潜在的不稳定变更的版本。
Docker镜像会运行编译器可执行文件,所以您可以把所有的编译器参数传给它。
例如,下面的命令提取了稳定版的 ``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版本。
+=======
+You can specify release build versions in the tag. For example:
+>>>>>>> english/develop
.. code-block:: bash
- docker run ethereum/solc:0.5.4 --help
+ docker run ethereum/solc:stable --help
+<<<<<<< HEAD
要使用 Docker 镜像来编译主机上的 Solidity 文件,请安装一个本地文件夹
用于输入和输出,并指定要编译的合约。例如:
+=======
+Note
+
+Specific compiler versions are supported as the Docker image tag such as `ethereum/solc:0.8.23`. We will be passing the
+`stable` tag here instead of specific version tag to ensure that users get the latest version by default and avoid the issue of
+an out-of-date version.
+
+To use the Docker image to compile Solidity files on the host machine, mount a
+local folder for input and output, and specify the contract to compile. For example:
+>>>>>>> english/develop
.. code-block:: bash
docker run -v /local/path:/sources ethereum/solc:stable -o /sources/output --abi --bin /sources/Contract.sol
+<<<<<<< HEAD
您也可以使用标准的JSON接口(当使用工具化的编译器时建议使用这种方式)。
当使用这个接口时,不需要装载任何目录,只要输入的 JSON 是自成一体的
(即它没有引用任何外部文件,而这些文件必须要被
:ref:`由导入回调 `)。
+=======
+You can also use the standard JSON interface (which is recommended when using the compiler with tooling).
+When using this interface, it is not necessary to mount any directories as long as the JSON input is
+self-contained (i.e. it does not refer to any external files that would have to be
+:ref:`loaded by the import callback `).
+>>>>>>> english/develop
.. code-block:: bash
@@ -122,14 +194,23 @@ Solidity 的二进制安装包可在 `solidity/releases `_
+and `solidity-bin `_.
+>>>>>>> english/develop
- pacman -S solidity
+.. note::
+
+ Please be aware that `AUR `_ packages
+ are user-produced content and unofficial packages. Exercise caution when using them.
还有一个 `snap包 `_,然而,它 **目前没有维护** 。
它可以安装在所有 `支持的Linux发行版 `_ 。通过以下命令,
@@ -168,8 +249,13 @@ macOS Packages
如果您需要特定版本的 Solidity,您可以直接从 Github 上安装一个 Homebrew 列表。
+<<<<<<< HEAD
参见
`solidity.rb 在 Github 上的提交情况 `_.
+=======
+View
+`solidity.rb commits on GitHub `_.
+>>>>>>> english/develop
复制您想要的版本的提交哈希值,然后在您的机器上检出该分支。
@@ -196,6 +282,7 @@ macOS Packages
该资源库不仅是一个快速且简单的方法,让终端用户获得可以开箱即用的二进制文件,
而且它对第三方工具也很友好:
+<<<<<<< HEAD
- 这些内容被镜像到 https://binaries.soliditylang.org,在那里可以很容易地通过 HTTPS 下载,
没有任何认证、速率或需要使用git的限制。
- 提供的内容具有正确的 `Content-Type` 请求头和宽松的 CORS 配置,
@@ -215,6 +302,30 @@ macOS Packages
``solc-bin`` 资源库包含几个顶级目录,每个目录代表一个平台。
每个目录都包含一个 ``list.json`` 文件,列出可用的二进制文件。
例如,在 ``emscripten-wasm32/list.json`` 中您会发现以下关于 0.7.4 版本的信息。
+=======
+- 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.
+
+The same binaries are in most cases available on the `Solidity release page on GitHub`_. The
+difference is that we do not generally update old releases on the GitHub release page. This means
+that we do not rename them if the naming convention changes and we do not add builds for platforms
+that were not supported at the time of release. This only happens in ``solc-bin``.
+
+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
@@ -226,7 +337,6 @@ macOS Packages
"keccak256": "0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3",
"sha256": "0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2",
"urls": [
- "bzzr://16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1",
"dweb:/ipfs/QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS"
]
}
@@ -235,6 +345,7 @@ macOS Packages
- 您可以在同一目录下找到二进制文件,名称为
`solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js `_.
+<<<<<<< HEAD
注意,该文件可能是一个软链接,如果您没有使用 git 下载,或者您的文件系统不支持软链接,您需要自己解决。
- 该二进制文件也被镜像在 https://binaries.soliditylang.org/emscripten-wasm32/solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js.
在这种情况下,不需要 git,软链接的解决方式是显而易见的,要么提供一个文件的副本,要么返回一个 HTTP 重定向。
@@ -247,6 +358,21 @@ macOS Packages
或在 JavaScript 中使用 `ethereumjs-util 的 keccak256() 函数。`
- 您也可以通过比较二进制文件的sha256哈希值来验证它的完整性
``0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2``。
+=======
+ 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`_.
+ Please, be aware that the order of items in the ``urls`` array is not predetermined or guaranteed and users should not rely on it.
+- 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::
@@ -275,25 +401,28 @@ macOS Packages
``binaries.soliditylang.org`` 可以保证长期运行并保持相同的URL结构。
.. _IPFS: https://ipfs.io
-.. _Swarm: https://swarm-gateways.net/bzz:/swarm.eth
.. _solc-bin: https://github.com/ethereum/solc-bin/
-.. _Solidity release page on github: https://github.com/ethereum/solidity/releases
+.. _Solidity release page on GitHub: https://github.com/ethereum/solidity/releases
.. _sha3sum: https://github.com/maandree/sha3sum
.. _keccak256() function from ethereumjs-util: https://github.com/ethereumjs/ethereumjs-util/blob/master/docs/modules/_hash_.md#const-keccak256
.. _WebAssembly builds: https://emscripten.org/docs/compiling/WebAssembly.html
.. _QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS: https://gateway.ipfs.io/ipfs/QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS
-.. _16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1: https://swarm-gateways.net/bzz:/16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1/
.. _building-from-source:
从源代码编译
====================
+<<<<<<< HEAD
先决条件 - 所有操作系统
+=======
+Prerequisites - All Operating Systems
+>>>>>>> english/develop
-------------------------------------
以下是 Solidity 构建的所有依赖性:
+<<<<<<< HEAD
+------------------------------------------+------------------------------+
| 软件 | 备注 |
@@ -310,6 +439,23 @@ macOS Packages
+------------------------------------------+------------------------------+
| `cvc4`_ (可选) | 与SMT检查器一起使用。 |
+------------------------------------------+------------------------------+
+=======
++-----------------------------------+-------------------------------------------------------+
+| Software | Notes |
++===================================+=======================================================+
+| `CMake`_ (version 3.21.3+ on | Cross-platform build file generator. |
+| Windows, 3.13+ otherwise) | |
++-----------------------------------+-------------------------------------------------------+
+| `Boost`_ (version 1.77+ on | C++ libraries. |
+| Windows, 1.65+ otherwise) | |
++-----------------------------------+-------------------------------------------------------+
+| `Git`_ | Command-line tool for retrieving source code. |
++-----------------------------------+-------------------------------------------------------+
+| `z3`_ (version 4.8.16+, Optional) | For use with SMT checker. |
++-----------------------------------+-------------------------------------------------------+
+| `cvc4`_ (Optional) | For use with SMT checker. |
++-----------------------------------+-------------------------------------------------------+
+>>>>>>> english/develop
.. _cvc4: https://cvc4.cs.stanford.edu/web/
.. _Git: https://git-scm.com/download
@@ -318,8 +464,14 @@ macOS Packages
.. _z3: https://github.com/Z3Prover/z3
.. note::
+<<<<<<< HEAD
0.5.10 之前的 Solidity 版本可能无法与 Boost 1.70 以上版本正确链接。
一个可能的解决方法是,在运行 cmake 命令配置 Solidity 之前,暂时重命名 ``/lib/cmake/Boost-1.70.0``。
+=======
+ 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
从 0.5.10 开始,针对 Boost 1.70 以上版本的链接应该无需人工干预。
@@ -352,11 +504,22 @@ macOS Packages
先决条件 - macOS
---------------------
+<<<<<<< HEAD
对于 macOS 的构建,确保最新版本的 `Xcode 已安装 `_。
这包含了 `Clang C++ 编译器 `_,
`Xcode IDE `_ 和其他苹果公司的开发工具,
这些工具是在 OS X 上构建 C++ 应用程序所必须的。
如果您是第一次安装 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
@@ -373,6 +536,7 @@ macOS Packages
您需要为 Solidity 的 Windows 版本安装以下依赖软件包:
+<<<<<<< HEAD
+-----------------------------------+------------------------+
| 软件 | 备注 |
+===================================+========================+
@@ -382,6 +546,17 @@ macOS Packages
+-----------------------------------+------------------------+
| `Boost`_ (1.77版本) | C++ 库文件。 |
+-----------------------------------+------------------------+
+=======
++-----------------------------------+-------------------------------------------------------+
+| Software | Notes |
++===================================+=======================================================+
+| `Visual Studio 2019 Build Tools`_ | C++ compiler |
++-----------------------------------+-------------------------------------------------------+
+| `Visual Studio 2019`_ (Optional) | C++ compiler and dev environment. |
++-----------------------------------+-------------------------------------------------------+
+| `Boost`_ (version 1.77+) | C++ libraries. |
++-----------------------------------+-------------------------------------------------------+
+>>>>>>> english/develop
如果您已经有一个 IDE 并且只需要编译器和库文件。您可以安装 Visual Studio 2019 构建工具。
@@ -418,20 +593,36 @@ Visual Studio 2019 同时提供IDE和必要的编译器和库。
git clone --recursive https://github.com/ethereum/solidity.git
cd solidity
+<<<<<<< HEAD
如果您想帮助开发 Solidity,
您可以分叉 Solidity,然后将您个人的分叉库作为第二远程源添加。
+=======
+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
这种方法将导致一个预发布的构建,例如,在这种编译器产生的每个字节码中设置一个标志。
如果您想重新构建一个已发布的 Solidity 编译器,那么请使用 github 发布页上的源压缩包:
https://github.com/ethereum/solidity/releases/download/v0.X.Y/solidity_0.X.Y.tar.gz
(而不是由 github 提供的 "源代码")。
+=======
+ This method will result in a pre-release build leading to e.g. a flag
+ being set in each bytecode produced by such a compiler.
+ If you want to re-build a released Solidity compiler, then
+ please use the source tarball on the GitHub release page:
+
+ https://github.com/ethereum/solidity/releases/download/v0.X.Y/solidity_0.X.Y.tar.gz
+
+ (not the "Source code" provided by GitHub).
+>>>>>>> english/develop
命令行构建
------------------
@@ -540,6 +731,7 @@ Solidity 版本名包含四部分:
示例:
+<<<<<<< HEAD
1. 0.4.0 版本发布。
2. 从现在开始,每晚构建一个 0.4.1 版本。
3. 引入非重大变更 —— 不改变版本号。
@@ -547,3 +739,6 @@ Solidity 版本名包含四部分:
5. 0.5.0 版本发布。
该方式与 :ref:`version pragma ` 一起运行良好。
+=======
+This behavior works well with the :ref:`version pragma `.
+>>>>>>> english/develop
diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst
index 0c85a50796f4..4008f42d6f59 100644
--- a/docs/internals/optimizer.rst
+++ b/docs/internals/optimizer.rst
@@ -5,8 +5,16 @@
优化器
*************
+<<<<<<< HEAD
Solidity编译器使用两种不同的优化器模块。在操作码水平上操作的 "旧" 优化器
和在 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 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
如果它们的参数和返回值不相互依赖,我们就可以对函数调用重新排序。
同样地,如果一个函数是没有副作用的,而且其结果是乘以0的,就可以完全删除该函数调用。
+<<<<<<< HEAD
目前,参数 ``--optimize`` 会为生成的字节码激活基于操作码的优化器,
并为内部生成的 Yul 代码激活 Yul 优化器,例如当使用 ABI coder v2 时。
您可以使用 ``solc --ir optimized --optimize`` 来为 Solidity 源码产生一个优化的 Yul IR。
@@ -28,6 +37,36 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
和内联器总是默认启用的,只能通过 :ref:`标准 JSON 文件配置 ` 关闭。
您可以在下面找到关于这两个优化器模块及其优化步骤的更多细节。
+=======
+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, i.e ``:``, 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
优化Solidity代码的好处
====================================
@@ -247,11 +286,19 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
下面将解释基于Yul的优化器模块的所有组件。
以下的转换步骤是主要的组成部分:
+<<<<<<< HEAD
- SSA转换
- 通用子表达式消除器
- 表达式简化器
- 冗余赋值消除器
- 完全内联
+=======
+- SSATransform
+- CommonSubexpressionEliminator
+- ExpressionSimplifier
+- UnusedAssignEliminator
+- FullInliner
+>>>>>>> english/develop
.. _optimizer-steps:
@@ -265,7 +312,7 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
缩略语 全称
============ ===============================
``f`` :ref:`block-flattener`
-``l`` :ref:`circular-reference-pruner`
+``l`` :ref:`circular-references-pruner`
``c`` :ref:`common-subexpression-eliminator`
``C`` :ref:`conditional-simplifier`
``U`` :ref:`conditional-unsimplifier`
@@ -287,12 +334,16 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
``T`` :ref:`literal-rematerialiser`
``L`` :ref:`load-resolver`
``M`` :ref:`loop-invariant-code-motion`
+<<<<<<< HEAD
``r`` :ref:`redundant-assign-eliminator`
``R`` :ref:`reasoning-based-simplifier` - 高度实验性
+=======
+>>>>>>> english/develop
``m`` :ref:`rematerialiser`
-``V`` :ref:`SSA-reverser`
-``a`` :ref:`SSA-transform`
+``V`` :ref:`ssa-reverser`
+``a`` :ref:`ssa-transform`
``t`` :ref:`structural-simplifier`
+``r`` :ref:`unused-assign-eliminator`
``p`` :ref:`unused-function-parameter-pruner`
``S`` :ref:`unused-store-eliminator`
``u`` :ref:`unused-pruner`
@@ -302,9 +353,13 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
一些步骤依赖于 ``BlockFlattener``, ``FunctionGrouper``, ``ForLoopInitRewriter`` 所保证的属性。
由于这个原因,Yul 优化器总是在应用用户提供的任何步骤之前应用它们。
+<<<<<<< HEAD
基于推理的简化器(ReasoningBasedSimplifier)是一个优化器步骤,
目前在默认步骤集中没有启用。它使用一个 SMT 求解器来简化算术表达式和布尔条件。
此外,它还没有得到彻底的测试或验证,可能会产生不可复现的结果,所以请谨慎使用!
+=======
+.. _selecting-optimizations:
+>>>>>>> english/develop
选择优化方案
-----------------------
@@ -314,7 +369,7 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
.. code-block:: bash
- solc --optimize --ir-optimized --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul:fDnTOc'
+ solc --optimize --ir-optimized --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul:fDnTOcmu'
步骤的顺序很重要,会影响到输出的质量。
此外,应用一个步骤可能为其他已经应用的步骤发现新的优化机会。因此,重复步骤往往是有益的。
@@ -369,9 +424,15 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
函数分组器
^^^^^^^^^^^^^^^
+<<<<<<< HEAD
函数分组器必须在消歧义器和函数提升器之后应用。
它的作用是将所有不是函数定义的最上面的元素移到一个单一的块中,
这个块是根块的第一个语句。
+=======
+The function grouper has to be applied after the Disambiguator and the FunctionHoister.
+Its effect is that all topmost elements that are not function definitions are moved
+into a single block which is the first statement of the root block.
+>>>>>>> english/develop
在这一步之后,一个程序具有以下正常形式:
@@ -382,15 +443,25 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
其中 ``I`` 是一个(可能是空的)区块,不包含任何函数定义(甚至是递归的),
``F`` 是一个函数定义的列表,使得没有一个函数包含函数定义。
+<<<<<<< HEAD
这个阶段的好处是,我们总是知道功能列表的开始位置。
+=======
+The benefit of this stage is that we always know where the list of functions begins.
+>>>>>>> english/develop
.. _for-loop-condition-into-body:
循环条件进入正文
^^^^^^^^^^^^^^^^^^^^^^^^
+<<<<<<< HEAD
这种转换将for循环的循环迭代条件移动到循环体中。
我们需要这种转换,因为 :ref:`expression-splitter` 将不适用于迭代条件表达式(以下示例中的 ``C``)。
+=======
+This transformation moves the loop-iteration condition of a ``for`` loop into loop body.
+We need this transformation because :ref:`expression-splitter` will not
+apply to iteration condition expressions (the ``C`` in the following example).
+>>>>>>> english/develop
.. code-block:: text
@@ -407,15 +478,25 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
Body...
}
+<<<<<<< HEAD
当与 ``循环不变代码模式`` 搭配时,这种转换也是有用的,因为循环不变条件中的不变量可以在循环之外进行。
+=======
+This transformation can also be useful when paired with LoopInvariantCodeMotion, since
+invariants in the loop-invariant conditions can then be taken outside the loop.
+>>>>>>> english/develop
.. _for-loop-init-rewriter:
循环初始重写器
^^^^^^^^^^^^^^^^^^^
+<<<<<<< HEAD
这种转换将for-loop的初始化部分移到循环之前:
+=======
+This transformation moves the initialization part of a ``for`` loop to before
+the loop:
+>>>>>>> english/develop
.. code-block:: text
@@ -432,8 +513,13 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
Body...
}
+<<<<<<< HEAD
这简化了其余的优化过程,
因为我们可以忽略for循环初始化块的复杂范围规则。
+=======
+This eases the rest of the optimization process because we can ignore
+the complicated scoping rules of the ``for`` loop initialization block.
+>>>>>>> english/develop
.. _var-decl-initializer:
@@ -536,15 +622,21 @@ Solidity编译器使用两种不同的优化器模块。在操作码水平上操
它不适用于循环迭代条件,因为循环控制流不允许在所有情况下 “概述” 内部表达式。
我们可以通过应用 :ref:`for-loop-condition-into-body` 将迭代条件移动到循环体中,从而避开这个限制。
+<<<<<<< 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
这种形式的好处是,更容易重新排列操作码序列,
也更容易执行函数调用内联。此外,
也更简单地替换表达式的各个部分或重新组织 “表达式树”。
缺点是这样的代码对我们来说更难阅读。
-.. _SSA-transform:
+.. _ssa-transform:
SSA转换
^^^^^^^^^^^^
@@ -582,6 +674,7 @@ SSA转换
- 将 ``let a := v`` 替换为 ``let a_i := v let a := a_i``
- 将 ``a := v`` 替换为 ``let a_i := v a := a_i``, 其中 ``i`` 是一个数字,使得 ``a_i`` 尚未使用。
+<<<<<<< HEAD
此外,总是记录用于 ``a`` 的 ``i`` 的当前值,并用 ``a_i`` 替换对 ``a`` 的每次引用。
变量 ``a`` 的当前值映射在每个分配给它的块结束时被清除,
如果它被分配在for循环体或post块内,则在for循环初始块结束时被清除。
@@ -593,11 +686,35 @@ SSA转换
如果在这个阶段之前运行表达式拆分器和通用子表达式消除器,
那么这个阶段会提供最好的结果,因为这样就不会产生过多的变量。
另一方面,如果在SSA转换之后运行通用子表达式消除器,则效率更高。
-
-.. _redundant-assign-eliminator:
-
+=======
+Furthermore, always record the current value of ``i`` used for ``a`` and replace each
+reference to ``a`` by ``a_i``.
+The current value mapping is cleared for a variable ``a`` at the end of each block
+in which it was assigned to and at the end of the ``for`` loop init block if it is assigned
+inside the ``for`` loop body or post block.
+If a variable's value is cleared according to the rule above and the variable is declared outside
+the block, a new SSA variable will be created at the location where control flow joins,
+this includes the beginning of loop post/body block and the location right after
+``if``/``switch``/``for``/block statement.
+
+After this stage, the UnusedAssignEliminator is recommended to remove the unnecessary
+intermediate assignments.
+
+This stage provides best results if the ExpressionSplitter and the CommonSubexpressionEliminator
+are run right before it, because then it does not generate excessive amounts of variables.
+On the other hand, the CommonSubexpressionEliminator could be more efficient if run after the
+SSA transform.
+>>>>>>> english/develop
+
+.. _unused-assign-eliminator:
+
+<<<<<<< HEAD
冗余赋值消除器
^^^^^^^^^^^^^^^^^^^^^^^^^
+=======
+UnusedAssignEliminator
+^^^^^^^^^^^^^^^^^^^^^^
+>>>>>>> english/develop
SSA转换总是生成 ``a := a_i`` 形式的赋值,
尽管这些赋值在许多情况下可能是不必要的,比如下面的例子:
@@ -625,8 +742,14 @@ SSA转换将这个片段转换为以下内容:
sstore(a_3, 1)
}
+<<<<<<< HEAD
冗余赋值消除器将删除对 ``a`` 的所有三个赋值,因为未使用 ``a`` 的值,
因此将此代码段转换为严格的SSA形式为:
+=======
+The UnusedAssignEliminator removes all the three assignments to ``a``, because
+the value of ``a`` is not used and thus turn this
+snippet into strict SSA form:
+>>>>>>> english/develop
.. code-block:: yul
@@ -637,7 +760,12 @@ SSA转换将这个片段转换为以下内容:
sstore(a_3, 1)
}
+<<<<<<< HEAD
当然,确定分配是否多余的错综复杂的部分与加入控制流有关。
+=======
+Of course the intricate parts of determining whether an assignment is unused or not
+are connected to joining control flow.
+>>>>>>> english/develop
该组件的详细工作情况如下:
@@ -645,9 +773,17 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
在信息收集过程中,我们维护了一个从赋值语句到 “未使用(unused)”,“未决定(undecided)” 和 “已使用(used)” 三种状态的映射,
这标志着分配的值是否会在以后被变量的引用使用。
+<<<<<<< HEAD
当一个赋值被访问时,它被添加到处于 “未决定” 状态的映射中
(见下面关于for循环的注释),而其他每个仍处于 “未决定” 状态的对同一变量的赋值被改为 “未使用”。
当一个变量被引用时,任何对该变量的赋值仍处于 “未决定” 状态,其状态被改变为 “已使用”。
+=======
+When an assignment is visited, it is added to the mapping in the "undecided" state
+(see remark about ``for`` loops below) and every other assignment to the same variable
+that is still in the "undecided" state is changed to "unused".
+When a variable is referenced, the state of any assignment to that variable still
+in the "undecided" state is changed to "used".
+>>>>>>> english/develop
在控制流分叉的地方,映射的拷贝被移交给每个分支。
在控制流汇合的地方,来自两个分支的两个映射以下列方式合并:
@@ -658,8 +794,15 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
- “未使用”, “已使用” -> “已使用”
- “未决定”, “已使用” -> “已使用”
+<<<<<<< HEAD
对于For循环,考虑到条件下的连接控制流,将对条件、主体和后部进行两次访问。
换句话说,我们创建了三条控制流路径:循环的零次运行、一次运行和两次运行,然后在最后合并它们。
+=======
+For ``for`` loops, the condition, body and post-part are visited twice, taking
+the joining control-flow at the condition into account.
+In other words, we create three control flow paths: Zero runs of the loop,
+one run and two runs and then combine them at the end.
+>>>>>>> english/develop
不需要模拟第三次甚至更多的运行,这可以如下所示:
@@ -681,11 +824,16 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
.. code-block:: none
- max(s, f(s), f(f(s))) = max(s, f(s), f(f(s)), f(f(f(s))), ...).
+ max(s, f(s), f(f(s))) = max(s, f(s), f(f(s)), f(f(f(s))), ...)
总之,最多运行两次循环就足够了,因为只有三种不同的状态。
+<<<<<<< HEAD
对于有 "默认" 情况的switch语句,没有跳过switch的控制流部分。
+=======
+For ``switch`` statements that have a default case, there is no control-flow
+part that skips the ``switch``.
+>>>>>>> english/develop
当一个变量超出范围时,所有仍处于 "未决定" 状态的语句都被改为 "未使用",
除非该变量是一个函数的返回参数--如何是这样,状态变为 "已使用"。
@@ -712,6 +860,7 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
数据流分析器
^^^^^^^^^^^^^^^^
+<<<<<<< HEAD
数据流分析器本身不是一个优化步骤,而是被其他组件作为工具使用。
在遍历AST时,它跟踪每个变量的当前值,
只要该值是一个可移动的表达式。
@@ -722,6 +871,21 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
在控制流连接处,如果变量在任何控制流路径中已经或将要被分配,
那么关于这些变量的记忆就会被清除。例如,在进入for循环时,所有将在主体或后块中分配的变量都被清除。
+=======
+The DataflowAnalyzer is not an optimizer step itself but is used as a tool
+by other components. While traversing the AST, it tracks the current value of
+each variable, as long as that value is a movable expression.
+It records the variables that are part of the expression
+that is currently assigned to each other variable. Upon each assignment to
+a variable ``a``, the current stored value of ``a`` is updated and
+all stored values of all variables ``b`` are cleared whenever ``a`` is part
+of the currently stored expression for ``b``.
+
+At control-flow joins, knowledge about variables is cleared if they have or would be assigned
+in any of the control-flow paths. For instance, upon entering a
+``for`` loop, all variables are cleared that will be assigned during the
+body or the post block.
+>>>>>>> english/develop
表达式的简化
--------------------------------
@@ -733,11 +897,19 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
通用子表达式消除器
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+<<<<<<< HEAD
这一步使用数据流分析器,用对某一变量的引用来替换语法上与该变量当前值相匹配的子表达式。
这是一个等价转换,因为这种子表达式必须是可移动的。
+=======
+This step uses the DataflowAnalyzer and replaces subexpressions that
+syntactically match the current value of a variable by a reference to
+that variable. This is an equivalence transform because such subexpressions have
+to be movable.
+>>>>>>> english/develop
如果值是一个标识符,所有本身是标识符的子表达式都被其当前值替换。
+<<<<<<< HEAD
上述两条规则的结合允许计算出一个局部值的编号,
这意味着如果两个变量有相同的值,其中一个将永远是未使用的。
然后,未使用过的处理器或冗余赋值消除器将能够完全消除此类变量。
@@ -747,24 +919,53 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
如果通用子表达式消除器在它之前运行,
表达式简化器将能够进行更好的替换。
+=======
+The combination of the two rules above allow to compute a local value
+numbering, which means that if two variables have the same
+value, one of them will always be unused. The UnusedPruner or the
+UnusedAssignEliminator will then be able to fully eliminate such
+variables.
+
+This step is especially efficient if the ExpressionSplitter is run
+before. If the code is in pseudo-SSA form,
+the values of variables are available for a longer time and thus we
+have a higher chance of expressions to be replaceable.
+
+The ExpressionSimplifier will be able to perform better replacements
+if the CommonSubexpressionEliminator was run right before it.
+>>>>>>> english/develop
.. _expression-simplifier:
表达式简化器
^^^^^^^^^^^^
+<<<<<<< HEAD
表达式简化器使用数据流分析器,
并利用表达式的等价变换列表,如 ``X + 0 -> X`` 来简化代码。
+=======
+The ExpressionSimplifier uses the DataflowAnalyzer and makes use
+of a list of equivalence transforms on expressions like ``X + 0 -> X``
+to simplify the code.
+>>>>>>> english/develop
它试图在每个子表达式上匹配诸如 ``X + 0`` 的模式。
在匹配过程中,它将变量解析为当前分配的表达式,
以便能够匹配更深入的嵌套模式,
即使代码是伪SSA形式。
+<<<<<<< HEAD
一些模式如 ``X - X -> 0`` 只能在表达式 ``X`` 是可移动的情况下应用,
否则会删除其潜在的副作用。
由于变量引用总是可移动的,即使它们的当前值可能不是,
表达式简化器在拆分或伪SSA形式下又更加强大。
+=======
+Some of the patterns like ``X - X -> 0`` can only be applied as long
+as the expression ``X`` is movable, because otherwise it would remove its potential side-effects.
+Since variable references are always movable, even if their current
+value might not be, the ExpressionSimplifier is again more powerful
+in split or pseudo-SSA form.
+>>>>>>> english/develop
.. _literal-rematerialiser:
@@ -782,6 +983,7 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
如果代码是SSA形式的,效果最好。
+<<<<<<< HEAD
先决条件:消歧器,循环初始重写器。
.. _reasoning-based-simplifier:
@@ -799,11 +1001,14 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
它只对EVM语言有效,但在其他语言上使用是安全的。
先决条件:消歧器,SSA转换。
+=======
+Prerequisites: Disambiguator, ForLoopInitRewriter.
+>>>>>>> english/develop
声明规模的简化
-------------------------------
-.. _circular-reference-pruner:
+.. _circular-references-pruner:
循环引用程序
^^^^^^^^^^^^^^^^^^^^^^^^
@@ -815,7 +1020,12 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
条件简化器
^^^^^^^^^^^^^^^^^^^^^
+<<<<<<< HEAD
如果可以从控制流中确定数值,条件简化器就会插入对条件变量的赋值。
+=======
+The ConditionalSimplifier inserts assignments to condition variables if the value can be determined
+from the control-flow.
+>>>>>>> english/develop
销毁SSA表格。
@@ -824,13 +1034,23 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
当前的特性:
+<<<<<<< HEAD
- 切换条件:插入 “<条件> := <条件标签>”
- 在带有终止控制流的if语句后,插入“<条件> : =0”
+=======
+- ``switch`` cases: insert `` := ``
+- after ``if`` statement with terminating control-flow, insert `` := 0``
+>>>>>>> english/develop
未来的特性:
+<<<<<<< HEAD
- 允许用 "1" 替换
- 考虑到用户定义的终止函数
+=======
+- allow replacements by ``1``
+- take termination of user-defined functions into account
+>>>>>>> english/develop
如果之前已经运行过死代码的删除,那么使用SSA表单效果最好。
@@ -841,7 +1061,11 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
有条件的非对称性放大器
^^^^^^^^^^^^^^^^^^^^^^^
+<<<<<<< HEAD
条件简化器的反面。
+=======
+Reverse of ConditionalSimplifier.
+>>>>>>> english/develop
.. _control-flow-simplifier:
@@ -850,6 +1074,7 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
简化了几个控制流结构:
+<<<<<<< HEAD
- 用pop(条件)代替if,用空的程序体代替if
- 移除空的默认switch情况
- 如果不存在默认情况,则删除空的switch情况
@@ -859,13 +1084,30 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
- 用匹配的条件程序体的常量表达式替换switch
- 将 ``for`` 替换为终止控制流,在没有其他 break/continue 的情况下替换为 ``if``
- 移除函数末尾的 ``leave``
+=======
+- replace ``if`` with empty body with ``pop(condition)``
+- remove empty default ``switch`` case
+- remove empty ``switch`` case if no default case exists
+- replace ``switch`` with no cases with ``pop(expression)``
+- turn ``switch`` with single case into ``if``
+- replace ``switch`` with only default case with ``pop(expression)`` and body
+- replace ``switch`` with const expr with matching case body
+- replace ``for`` with terminating control flow and without other ``break``/``continue`` by ``if``
+- remove ``leave`` at the end of a function.
+>>>>>>> english/develop
这些操作都不依赖于数据流。然而结构简化器执行类似的任务,确实依赖于数据流。
控制流简化器在其遍历过程中确实记录了是否存在 ``break`` 和 ``continue`` 语句。
+<<<<<<< HEAD
先决条件:消歧器,函数提升器, 循环初始重写器。
重要提示:引入了EVM操作代码,因此目前只能用于EVM代码。
+=======
+Prerequisite: Disambiguator, FunctionHoister, ForLoopInitRewriter.
+
+Important: Introduces EVM opcodes and thus can only be used on EVM code for now.
+>>>>>>> english/develop
.. _dead-code-eliminator:
@@ -874,15 +1116,28 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
这个优化阶段删除了不可到达的代码。
+<<<<<<< HEAD
无法访问的代码是指在一个区块内的任何代码,
其前面有 leave,return,invalid,break,continue,selfdestruct,revert 或调用用户定义的函数,并无限地递归。
+=======
+Unreachable code is any code within a block which is preceded by a
+``leave``, ``return``, ``invalid``, ``break``, ``continue``, ``selfdestruct``, ``revert`` or by
+a call to a user-defined function that recurses infinitely.
+>>>>>>> english/develop
函数定义被保留下来,因为它们可能被早期的代码调用,因此被认为是可访问的。
+<<<<<<< HEAD
因为在for循环的init块中声明的变量,其范围会扩展到循环体,
所以我们要求 循环初始重写器 在此步骤之前运行。
先决条件: 循环初始重写器, 函数提升器, 函数分组器
+=======
+Because variables declared in a ``for`` loop's init block have their scope extended to the loop body,
+we require ForLoopInitRewriter to run before this step.
+
+Prerequisites: ForLoopInitRewriter, FunctionHoister, FunctionGrouper.
+>>>>>>> english/develop
.. _equal-store-eliminator:
@@ -893,10 +1148,19 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
但中间没有其他存储,并且 ``k`` 和 ``v`` 的值没有变化,
则该步骤将删除 ``mstore(k, v)`` 和 ``sstore(k, v)`` 的调用。
+<<<<<<< HEAD
如果在SSA转换和通用子表达式消除器之后运行,这个简单的步骤是有效的,
因为SSA将确保变量不会改变,而通用子表达式消除器在已知值相同的情况下会重新使用完全相同的变量。
先决条件: 消歧器, 循环初始重写器
+=======
+This simple step is effective if run after the SSATransform and the
+CommonSubexpressionEliminator, because SSA will make sure that the variables
+will not change and the CommonSubexpressionEliminator re-uses exactly the same
+variable if the value is known to be the same.
+
+Prerequisites: Disambiguator, ForLoopInitRewriter.
+>>>>>>> english/develop
.. _unused-pruner:
@@ -905,8 +1169,14 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
这一步删除了所有从未被引用的函数的定义。
+<<<<<<< HEAD
它还删除了从未被引用的变量的声明。如果声明指定了一个不可移动的值,
表达式将被保留,但其值将被丢弃。
+=======
+It also removes declarations of variables that are never referenced.
+If a declaration assigns a value that is not movable, the expression is retained,
+but its value is discarded.
+>>>>>>> english/develop
所有可移动的表达式语句(未被赋值的表达式)都被删除。
@@ -917,6 +1187,7 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
这是一个一般的步骤,在结构层面上进行各种简化:
+<<<<<<< HEAD
- 用 ``pop(条件)`` 代替 if 语句的空程序体。
- 用其主体替换带有真实条件的if语句
- 删除带有错误条件的if语句
@@ -926,14 +1197,32 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
- 用其初始化部分取代带有错误条件的for循环
该组件使用数据流分析器。
+=======
+- replace ``if`` statement with empty body by ``pop(condition)``
+- replace ``if`` statement with true condition by its body
+- remove ``if`` statement with false condition
+- turn ``switch`` with single case into ``if``
+- replace ``switch`` with only default case by ``pop(expression)`` and body
+- replace ``switch`` with literal expression by matching case body
+- replace ``for`` loop with false condition by its initialization part
+
+This component uses the DataflowAnalyzer.
+>>>>>>> english/develop
.. _block-flattener:
块展平器
^^^^^^^^^^^^^^
+<<<<<<< HEAD
这个阶段通过在外部块的适当位置插入内部块的语句来消除嵌套块。
它依赖于函数分组器,并不对最外层的块进行展平,以保持函数分组器产生的形式。
+=======
+This stage eliminates nested blocks by inserting the statements 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
@@ -970,10 +1259,16 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
只有在循环体或后块中的最高级别的语句被考虑,
即条件分支内的变量声明不会被移出循环。
+<<<<<<< HEAD
要求:
- 消歧器, 循环初始重写器和函数提升器必须提前运行。
- 表达式拆分器和SSA转换应在前期运行以获得更好的结果。
+=======
+ExpressionSplitter and SSATransform should be run upfront to obtain better results.
+
+Prerequisites: Disambiguator, ForLoopInitRewriter, FunctionHoister.
+>>>>>>> english/develop
函数级的优化
@@ -1000,7 +1295,11 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
其他优化步骤将能够对函数进行更多的简化。
优化步骤主要对那些不会被内联的函数有用。
+<<<<<<< HEAD
先决条件: 消歧器, 函数提升器
+=======
+Prerequisites: Disambiguator, FunctionHoister.
+>>>>>>> english/develop
建议将字面意义上的再物质化器(LiteralRematerialiser)作为先决条件,尽管它不是正确性的必要条件。
@@ -1030,7 +1329,7 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
``function f(x) -> y { revert(y, y} }`` 其中字面意思 ``y`` 将被其值 ``0`` 取代,
使我们能够重写该函数。
-.. index:: ! unused store eliminator
+.. index:: ! UnusedStoreEliminator
.. _unused-store-eliminator:
未使用的存储清除器
@@ -1056,7 +1355,11 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
sstore(c, 3)
}
+<<<<<<< HEAD
在运行未使用的存储消除器步骤后,将被转化为以下代码
+=======
+will be transformed into the code below after the UnusedStoreEliminator step is run
+>>>>>>> english/develop
.. code-block:: yul
@@ -1066,10 +1369,17 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
sstore(c, 3)
}
+<<<<<<< HEAD
对于内存存储操作,事情一般比较简单,至少在最外层的yul块中是这样,
因为如果在任何代码路径中从未被读取,所有这样的语句都将被删除。
然而,在函数分析层面,其方法与 ``sstore`` 类似,因为我们不知道一旦离开函数的范围,内存位置是否会被读取,
所以只有当所有的代码路径都导致内存被覆写时,语句才会被删除。
+=======
+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.
+>>>>>>> english/develop
最好以SSA形式运行。
@@ -1084,8 +1394,12 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
同时允许变量重命名,但不允许任何重新排序,
那么对其中一个函数的任何引用都会被另一个函数取代。
+<<<<<<< HEAD
实际删除的功能是由未使用过的处理器执行的。
+=======
+>>>>>>> english/develop
+The actual removal of the function is performed by the UnusedPruner.
函数内联
-----------------
@@ -1103,9 +1417,15 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
此外,对于所有的参数,以下各项都需要为真:
+<<<<<<< HEAD
- 参数是可移动的。
- 该参数在函数体中被引用不到两次,或者该参数相当便宜
( "成本" 最多为1,就像一个0xff以下的常数)。
+=======
+- The argument is movable.
+- The parameter is either referenced less than twice in the function body, or the argument is rather cheap
+ ("cost" of at most 1, like a constant up to ``0xff``).
+>>>>>>> english/develop
例如:要被内联的函数的形式是: ``function f(...) -> r { r := E }``
其中 ``E`` 是一个不引用 ``r`` 的表达式,函数调用中的所有参数都是可移动表达式。
@@ -1119,11 +1439,21 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
完全内联
^^^^^^^^^^^
+<<<<<<< HEAD
完全内联用函数的主体取代了某些函数的调用。
这在大多数情况下是没有什么帮助的,因为它只是增加了代码的大小,但并没有什么好处。
此外,代码通常是非常昂贵的,我们往往宁愿要更短的代码而不是更有效的代码。
不过,在相同的情况下,内联一个函数可以对后续的优化步骤产生积极的影响。
例如,如果一个函数参数是一个常数,就会出现这种情况。
+=======
+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 some cases, though, inlining a function
+can have positive effects on subsequent optimizer steps. This is the case
+if one of the function arguments is a constant, for example.
+>>>>>>> english/develop
在内联过程中,一个启发式方法被用来判断函数调用是否应该被内联。
目前的启发式方法是不内联到 "大" 函数,除非被调用的函数很小。
@@ -1136,7 +1466,16 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
之后,我们可以在这个专用函数上运行优化器。
如果结果有很大的收益,那么这个专门化的函数就被保留下来,否则就用原来的函数代替。
+<<<<<<< HEAD
清理
+=======
+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
-------
清理工作是在优化器运行结束时进行的。
@@ -1148,9 +1487,18 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
表达式连接器
^^^^^^^^^^^^^^^^
+<<<<<<< HEAD
这是与表达式分割器相反的操作。它把正好有一个引用的变量声明序列变成一个复杂的表达式。
这个阶段完全保留了函数调用和操作码执行的顺序。它不使用任何关于操作码的互换性的信息;
如果将一个变量的值移到它的使用位置会改变任何函数调用或操作码执行的顺序,则不执行转换。
+=======
+This is the opposite operation of the ExpressionSplitter. It turns a sequence of
+variable declarations that have exactly one reference into a complex expression.
+This stage fully preserves the order of function calls and opcode executions.
+It does not make use of any information concerning the commutativity of the opcodes;
+if moving the value of a variable to its place of use would change the order
+of any function call or opcode execution, the transformation is not performed.
+>>>>>>> english/develop
注意,组件不会移动变量赋值或被多次引用的变量的赋值。
@@ -1162,11 +1510,12 @@ AST被遍历了两次:分别在在信息收集步骤和实际删除步骤中
因此,片段 ``let x := add(0, 2) let y := mul(x, 3)`` 被转换为
``let y := mul(add(0, 2), 3)``,尽管 ``add`` 操作码将在计算字面意义 ``3`` 后执行。
-.. _SSA-reverser:
+.. _ssa-reverser:
SSA反转器
^^^^^^^^^^^
+<<<<<<< HEAD
这是一个微小的步骤,如果它与通用子表达式消除器和未使用过的处理器相结合,
则有助于扭转SSA转换的影响。
@@ -1175,6 +1524,18 @@ SSA反转器
而不是用新的变量声明。
SSA转换改写
+=======
+This is a tiny step that helps in reversing the effects of the SSATransform
+if it is combined with the CommonSubexpressionEliminator and the
+UnusedPruner.
+
+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.
+
+The SSATransform rewrites
+>>>>>>> english/develop
.. code-block:: yul
@@ -1191,9 +1552,16 @@ SSA转换改写
let a_2 := calldataload(0x20)
a := a_2
+<<<<<<< HEAD
问题是在引用 ``a`` 时使用了变量 ``a_1``,而不是 ``a``。
SSA转换改变了这种形式的语句,只需将声明和赋值互换。
上面的片段被转化为
+=======
+The problem is that instead of ``a``, the variable ``a_1`` is used
+whenever ``a`` was referenced. The SSATransform changes statements
+of this form by just swapping out the declaration and the assignment. The above
+snippet is turned into
+>>>>>>> english/develop
.. code-block:: yul
@@ -1203,9 +1571,17 @@ SSA转换改变了这种形式的语句,只需将声明和赋值互换。
a := calldataload(0x20)
let a_2 := a
+<<<<<<< HEAD
这是一个非常简单的等价转换,但是当我们现在运行通用子表达式消除器时,
它将用 ``a`` 替换所有出现的 ``a_1`` (直到 ``a`` 被重新赋值)。
然后,未使用过的处理器将完全消除变量 ``a_1``,从而完全逆转SSA的转换。
+=======
+This is a very simple equivalence transform, but when we now run the
+CommonSubexpressionEliminator, it will replace all occurrences of ``a_1``
+by ``a`` (until ``a`` is re-assigned). The UnusedPruner will then
+eliminate the variable ``a_1`` altogether and thus fully reverse the
+SSATransform.
+>>>>>>> english/develop
.. _stack-compressor:
@@ -1228,6 +1604,7 @@ SSA转换改变了这种形式的语句,只需将声明和赋值互换。
再物质化
^^^^^^^^^^^^^^
+<<<<<<< HEAD
再物质化阶段试图用最后分配给变量的表达式来替换变量引用。
当然,这只有在这个表达式的评估费用相对较低的情况下才是有益的。
此外,只有当表达式的值在赋值点和使用点之间没有变化时,
@@ -1239,6 +1616,20 @@ SSA转换改变了这种形式的语句,只需将声明和赋值互换。
这些变量总是可移动的。
如果数值非常便宜或者变量被明确要求消除,
那么变量的引用就会被其当前值所取代。
+=======
+The rematerialisation stage tries to replace variable references by the expression that
+was last assigned to the variable. This is of course only beneficial if this expression
+is comparatively cheap to evaluate. Furthermore, it is only semantically equivalent if
+the value of the expression did not change between the point of assignment and the
+point of use. The main benefit of this stage is that it can save stack slots if it
+leads to a variable being eliminated completely (see below), but it can also
+save a ``DUP`` opcode on the EVM if the expression is very cheap.
+
+The Rematerialiser uses the DataflowAnalyzer to track the current values of variables,
+which are always movable.
+If the value is very cheap or the variable was explicitly requested to be eliminated,
+the variable reference is replaced by its current value.
+>>>>>>> english/develop
.. _for-loop-condition-out-of-body:
@@ -1283,7 +1674,10 @@ SSA转换改变了这种形式的语句,只需将声明和赋值互换。
字面意义上的再物质化器应在此步骤之前运行。
+Codegen-Based Optimizer Module
+==============================
+<<<<<<< HEAD
特定的WebAssembly
--------------------
@@ -1293,3 +1687,61 @@ SSA转换改变了这种形式的语句,只需将声明和赋值互换。
将最上面的块改变为一个具有特定名称(“main”)的函数,它没有输入和输出。
取决于函数分组器。
+=======
+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/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst
index 8a1eae4220df..7982364d95c9 100644
--- a/docs/introduction-to-smart-contracts.rst
+++ b/docs/introduction-to-smart-contracts.rst
@@ -78,8 +78,9 @@ Solidity意义上的合约是代码(其 *函数*)和数据(其 *状态*)
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
- pragma solidity ^0.8.4;
+ pragma solidity ^0.8.26;
+ // This will only compile via IR
contract Coin {
// 关键字 "public" 使变量可以从其他合约中访问。
address public minter;
@@ -106,12 +107,7 @@ Solidity意义上的合约是代码(其 *函数*)和数据(其 *状态*)
// 从任何调用者那里发送一定数量的代币到一个地址
function send(address receiver, uint amount) public {
- if (amount > balances[msg.sender])
- revert InsufficientBalance({
- requested: amount,
- available: balances[msg.sender]
- });
-
+ require(amount <= balances[msg.sender], InsufficientBalance(amount, balances[msg.sender]));
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
@@ -141,11 +137,20 @@ Solidity意义上的合约是代码(其 *函数*)和数据(其 *状态*)
但它是一个更复杂的数据类型。
:ref:`映射 ` 类型将地址映射到 :ref:`无符号整数 `。
+<<<<<<< HEAD
映射可以被看作是 `哈希表 `_,
它实际上是被初始化的,因此每一个可能的键从一开始就存在,并被映射到一个值,其字节表示为全零的值。
然而,它既不可能获得一个映射的所有键的列表,也不可能获得所有值的列表。
因此,要么记住您添加到映射中的内容,要么在不需要的情况下使用它。
甚至更好的是,保留一个列表,或者使用一个更合适的数据类型。
+=======
+Mappings can be seen as `hash tables `_ which are
+virtually initialized such that every possible key exists from the start and is mapped to a
+value whose byte-representation is all zeros. However, it is neither possible to obtain a list of all keys of
+a mapping, nor a list of all values. Record what you
+added to the mapping, or use it in a context where this is not needed. Or
+even better, keep a list, or use a more suitable data type.
+>>>>>>> english/develop
而由 ``public`` 关键字创建的 :ref:`getter 函数 ` 则是更复杂一些的情况,
它大致如下所示:
@@ -198,10 +203,20 @@ Solidity意义上的合约是代码(其 *函数*)和数据(其 *状态*)
即当任意精度算术中的 ``balances[receiver] + amount`` 大于 ``uint`` 的最大值( ``2**256 - 1``)时,
交易将被恢复。对于函数 ``send`` 中的语句 ``balances[receiver] += amount;`` 也是如此。
+<<<<<<< HEAD
:ref:`错误(Errors) ` 允许您向调用者提供更多关于一个条件或操作失败原因的信息。
错误与 :ref:`恢复状态 ` 一起使用。 ``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, much like the :ref:`require function `.
+Both approaches allow 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
任何人(已经拥有一些这样的代币)都可以使用 ``send`` 函数来发送代币给其他任何人。
如果发送者没有足够的代币可以发送, 那么 ``if`` 条件就会为真。
@@ -242,9 +257,16 @@ Solidity意义上的合约是代码(其 *函数*)和数据(其 *状态*)
数据库的事务特性确保了如果从一个账户扣除金额,它总被添加到另一个账户。
如果由于某些原因,无法添加金额到目标账户时,源账户也不会发生任何变化。
+<<<<<<< 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
@@ -265,11 +287,19 @@ Solidity意义上的合约是代码(其 *函数*)和数据(其 *状态*)
区块每隔一段时间就会被添加到链上,但这些时间间隔在未来可能会发生变化。
如需了解最新信息,建议在 `Etherscan `_ 等网站上对网络进行监控。
+<<<<<<< HEAD
作为 “顺序选择机制”(也就是所谓的“挖矿”)的一部分,
可能有时会发生块(blocks)被回滚的情况,但仅在链的“末端”。
末端增加的块越多,其发生回滚的概率越小。
因此您的交易被回滚甚至从区块链中抹除,这是可能的,
但等待的时间越长,这种情况发生的概率就越小。
+=======
+As part of the "order selection mechanism", which is called `attestation `_, it may happen that
+blocks are reverted from time to time, but only at the "tip" of the chain. The more
+blocks are added on top of a particular block, the less likely this block will be reverted. So it might be that your transactions
+are reverted and even removed from the blockchain, but the longer you wait, the less
+likely it will be.
+>>>>>>> english/develop
.. note::
交易不保证被包括在下一个区块或任何特定的未来区块中,
@@ -469,9 +499,29 @@ EVM的指令集应尽量保持最小,以避免不正确或不一致的实现
因为如果有人向被删除的合约发送以太币,以太币就会永远丢失。
.. warning::
+<<<<<<< HEAD
从0.8.18及更高版本开始,在 Solidity 和 Yul 中使用 ``selfdestruct`` 将触发弃用警告,
因为 ``SELFDESTRUCT`` 操作码最终将经历 `EIP-6049 `_
中所述的行为的重大变化。
+=======
+ From ``EVM >= Cancun`` onwards, ``selfdestruct`` will **only** send all Ether in the account to the given recipient and not destroy the contract.
+ However, when ``selfdestruct`` is called in the same transaction that creates the contract calling it,
+ the behaviour of ``selfdestruct`` before Cancun hardfork (i.e., ``EVM <= Shanghai``) is preserved and will destroy the current contract,
+ deleting any data, including storage keys, code and the account itself.
+ See `EIP-6780 `_ for more details.
+
+ The new behaviour is the result of a network-wide change that affects all contracts present on
+ the Ethereum mainnet and testnets.
+ It is important to note that this change is dependent on the EVM version of the chain on which
+ the contract is deployed.
+ The ``--evm-version`` setting used when compiling the contract has no bearing on it.
+
+ Also, note that the ``selfdestruct`` opcode has been deprecated in Solidity version 0.8.18,
+ as recommended by `EIP-6049 `_.
+ The deprecation is still in effect and the compiler will still emit warnings on its use.
+ Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account.
+ Future changes to the EVM might further reduce the functionality of the opcode.
+>>>>>>> english/develop
.. warning::
即使一个合约通过 ``selfdestruct`` 删除,它仍然是区块链历史的一部分,
@@ -493,10 +543,19 @@ EVM的指令集应尽量保持最小,以避免不正确或不一致的实现
预编译合约
=====================
+<<<<<<< HEAD
有一小群合约地址是特殊的。 ``1`` 和(包括) ``8`` 之间的地址范围包含 “预编译合约“,
可以像其他合约一样被调用,但它们的行为(和它们的gas消耗)
不是由存储在该地址的EVM代码定义的(它们不包含代码),
而是由EVM执行环境本身实现。
+=======
+There is a small set of contract addresses that are special:
+The address range between ``1`` and (including) ``0x0a`` contains
+"precompiled contracts" that can be called as any other contract
+but their behavior (and their gas consumption) is not defined
+by EVM code stored at that address (they do not contain code)
+but instead is implemented in the EVM execution environment itself.
+>>>>>>> english/develop
不同的EVM兼容链可能使用不同的预编译合约集。
未来也有可能在以太坊主链上添加新的预编译合约,
diff --git a/docs/ir-breaking-changes.rst b/docs/ir-breaking-changes.rst
index f720539f4db2..952632f5b14b 100644
--- a/docs/ir-breaking-changes.rst
+++ b/docs/ir-breaking-changes.rst
@@ -14,6 +14,7 @@ Solidity 可以通过两种不同的方式生成 EVM 字节码:
引入基于 IR 的代码生成器的目的是,不仅使代码生成更加透明和可审计,
而且能够实现更强大的跨函数的优化通道。
+<<<<<<< HEAD
您可以在命令行中使用 ``--via-ir``
或在 standard-json 中使用 ``{"viaIR": true}`` 选项来启用它,
我们鼓励大家尝试一下!
@@ -21,13 +22,29 @@ Solidity 可以通过两种不同的方式生成 EVM 字节码:
由于一些原因,旧的和基于 IR 的代码生成器之间存在着微小的语义差异,
主要是在那些我们无论如何也不会期望人们依赖这种行为的领域。
本节强调了旧的和基于IR的代码生成器之间的主要区别。
+=======
+You can enable it on the command-line using ``--via-ir``
+or with the option ``{"viaIR": true}`` in standard-json and we
+encourage everyone to try it out!
+
+For several reasons, there are tiny semantic differences between the old
+and the IR-based code generator, mostly in areas where we would not
+expect people to rely on this behavior anyway.
+This section highlights the main differences between the old and the IR-based codegen.
+>>>>>>> english/develop
仅有语义上的变化
=====================
本节列出了仅有语义的变化,从而有可能在现有的代码中隐藏新的和不同的行为。
+<<<<<<< HEAD
- 在继承的情况下,状态变量初始化的顺序已经改变。
+=======
+.. _state-variable-initialization-order:
+
+- The order of state variable initialization has changed in case of inheritance.
+>>>>>>> english/develop
以前的顺序是:
diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst
index be97420c298b..b094b78eb154 100644
--- a/docs/layout-of-source-files.rst
+++ b/docs/layout-of-source-files.rst
@@ -34,7 +34,12 @@ Solidity 遵循 `npm 的推荐 `_ 中找到。
+=======
+More information about how to use SPDX license identifiers
+can be found at the `SPDX website `_.
+>>>>>>> english/develop
.. index:: ! pragma
diff --git a/docs/logo.svg b/docs/logo.svg
index 86b9f4995b24..19391843b407 100644
--- a/docs/logo.svg
+++ b/docs/logo.svg
@@ -1,27 +1,8 @@
-
-
-
-