diff --git a/.circleci/README.md b/.circleci/README.md deleted file mode 100644 index 6af7fd45cc3d..000000000000 --- a/.circleci/README.md +++ /dev/null @@ -1,30 +0,0 @@ -## CircleCI integration - -### Docker images - -The docker images are build locally on the developer machine: - -```sh -cd .circleci/docker/ - -docker build -t ethereum/solidity-buildpack-deps:ubuntu2204- -f Dockerfile.ubuntu2204 . -docker push ethereum/solidity-buildpack-deps:ubuntu2204- -``` - -The current revisions per docker image are stored in [circle ci pipeline parameters](https://github.com/CircleCI-Public/api-preview-docs/blob/master/docs/pipeline-parameters.md#pipeline-parameters) called `-docker-image-rev` (e.g., `ubuntu-2204-docker-image-rev`). Please update the value assigned to the parameter(s) corresponding to the docker image(s) being updated at the time of the update. Please verify that the value assigned to the parameter matches the revision part of the docker image tag (`` in the docker build/push snippet shown above). Otherwise, the docker image used by circle ci and the one actually pushed to docker hub will differ. - -Once the docker image has been built and pushed to Dockerhub, you can find it at: - - https://hub.docker.com/r/ethereum/solidity-buildpack-deps:ubuntu2204- - -where the image tag reflects the target OS and revision to build Solidity and run its tests on. - -### Testing docker images locally - -```sh -cd solidity -# Mounts your local solidity directory in docker container for testing -docker run -v `pwd`:/src/solidity -ti ethereum/solidity-buildpack-deps:ubuntu2204- /bin/bash -cd /src/solidity - -``` diff --git a/.circleci/build_win.ps1 b/.circleci/build_win.ps1 deleted file mode 100644 index 730bb6319586..000000000000 --- a/.circleci/build_win.ps1 +++ /dev/null @@ -1,26 +0,0 @@ -$ErrorActionPreference = "Stop" - -cd "$PSScriptRoot\.." - -if ("$Env:FORCE_RELEASE" -Or "$Env:CIRCLE_TAG") { - New-Item prerelease.txt -type file - Write-Host "Building release version." -} -else { - # Use last commit date rather than build date to avoid ending up with builds for - # different platforms having different version strings (and therefore producing different bytecode) - # if the CI is triggered just before midnight. - $last_commit_timestamp = git log -1 --date=unix --format=%cd HEAD - $last_commit_date = (Get-Date -Date "1970-01-01 00:00:00Z").toUniversalTime().addSeconds($last_commit_timestamp).ToString("yyyy.M.d") - -join("ci.", $last_commit_date) | out-file -encoding ascii prerelease.txt -} - -mkdir build -cd build -$boost_dir=(Resolve-Path $PSScriptRoot\..\deps\boost\lib\cmake\Boost-*) -..\deps\cmake\bin\cmake -G "Visual Studio 16 2019" -DBoost_DIR="$boost_dir\" -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_INSTALL_PREFIX="$PSScriptRoot\..\upload" -DUSE_Z3=OFF .. -if ( -not $? ) { throw "CMake configure failed." } -msbuild solidity.sln /p:Configuration=Release /m:10 /v:minimal -if ( -not $? ) { throw "Build failed." } -..\deps\cmake\bin\cmake --build . -j 10 --target install --config Release -if ( -not $? ) { throw "Install target failed." } diff --git a/.circleci/cln-asan.supp b/.circleci/cln-asan.supp deleted file mode 100644 index b16becf29bf6..000000000000 --- a/.circleci/cln-asan.supp +++ /dev/null @@ -1 +0,0 @@ -leak:*libcln* diff --git a/.circleci/compare_bytecode_reports.sh b/.circleci/compare_bytecode_reports.sh deleted file mode 100755 index 7b62656bf24e..000000000000 --- a/.circleci/compare_bytecode_reports.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -#------------------------------------------------------------------------------ -# Compares bytecode reports generated by prepare_report.py/.js. -# -# ------------------------------------------------------------------------------ -# This file is part of solidity. -# -# solidity is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# solidity is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with solidity. If not, see -# -# (c) 2023 solidity contributors. -#------------------------------------------------------------------------------ - -no_cli_platforms=( - emscripten -) -native_platforms=( - ubuntu2004-static - ubuntu - osx - windows -) -interfaces=( - cli - standard-json -) - -for preset in "$@"; do - report_files=() - for platform in "${no_cli_platforms[@]}"; do - report_files+=("bytecode-report-${platform}-${preset}.txt") - done - for platform in "${native_platforms[@]}"; do - for interface in "${interfaces[@]}"; do - report_files+=("bytecode-report-${platform}-${interface}-${preset}.txt") - done - done - - echo "Reports to compare:" - printf -- "- %s\n" "${report_files[@]}" - - if ! diff --brief --report-identical-files --from-file "${report_files[@]}"; then - diff --unified=0 --report-identical-files --from-file "${report_files[@]}" | head --lines 50 - zip "bytecode-reports-${preset}.zip" "${report_files[@]}" - exit 1 - fi -done diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 7ec500e2e823..000000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,1875 +0,0 @@ -# vim:ts=2:sw=2:et -# -------------------------------------------------------------------------- -# Prefixes used in order to keep CircleCI workflow overview more readable: -# - b: build -# - t: test -# - ubu: ubuntu -# - ems: Emscripten -version: 2.1 -parameters: - ubuntu-2004-docker-image: - type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-20 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:7a1e1b01eda0d1e20704279672bcfd53dbbc481898ff960958a225dea76345bd" - ubuntu-2204-docker-image: - type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-5 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:4df420b7ccd96f540a4300a4fae0fcac2f4d3f23ffff9e3777c1f2d7c37ef901" - ubuntu-2204-clang-docker-image: - type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-4 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:538596bf55961197f8b5670d8a6742d9bcd502b6a1045ae9d372cdf35ce69d93" - ubuntu-clang-ossfuzz-docker-image: - type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-2 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:a4fc3a41240c3bc58882d3f504e446c6931b547119012f5c45f79b0df91dbdd1" - emscripten-docker-image: - type: string - # NOTE: Please remember to update the `build_emscripten.sh` whenever the hash of this image changes. - # solbuildpackpusher/solidity-buildpack-deps:emscripten-16 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:19fcb5ac029bbc27ec36e10f7d14ea224d8010145f9690562ef084fd16146b0c" - evm-version: - type: string - default: london - -orbs: - win: circleci/windows@2.2.0 - -commands: - matrix_notify_unless_pr: - description: "Posts a notification to the solidity-dev room on Matrix (if not running on a PR)." - parameters: - event: - type: enum - enum: ["failure", "success", "release"] - condition: - type: string - steps: - - run: - name: "Matrix notification" - when: << parameters.condition >> - command: scripts/ci/notification/matrix_notification.sh << parameters.event >> - - matrix_notify_failure_unless_pr: - description: "Posts a failure notification to the main room on Matrix (if not running on a PR)." - steps: - - matrix_notify_unless_pr: - event: failure - condition: on_fail - - matrix_notify_success_unless_pr: - description: "Posts a success notification to the main room on Matrix (if not running on a PR)." - steps: - - matrix_notify_unless_pr: - event: success - condition: on_success - - matrix_notify_release_unless_pr: - description: "Posts a release notification to the main room on Matrix (if not running on a PR)." - steps: - - matrix_notify_unless_pr: - event: release - condition: on_success - - prepare_bytecode_report: - description: "Generate bytecode report and upload it as an artifact." - parameters: - label: - type: string - binary_type: - type: enum - enum: - - solcjs - - native - binary_path: - type: string - preset: - type: string - steps: - - run: - name: Generate bytecode reports for the selected preset - no_output_timeout: 30m - command: | - .circleci/parallel_bytecode_report.sh \ - "<< parameters.label >>" \ - "<< parameters.binary_type >>" \ - "${PWD}/<< parameters.binary_path >>" \ - "<< parameters.preset >>" - - store_artifacts: - path: bytecode-report-<< parameters.label >>-standard-json-<< parameters.preset >>.txt - - store_artifacts: - path: bytecode-report-<< parameters.label >>-cli-<< parameters.preset >>.txt - - store_artifacts: - path: bytecode-report-<< parameters.label >>-<< parameters.preset >>.txt - - persist_to_workspace: - root: . - paths: - - bytecode-report-<< parameters.label >>*.txt - - matrix_notify_failure_unless_pr - - install_python3: - description: "Install python3 and given packages." - parameters: - packages: - description: "List of extra Python packages to be installed (separated by space)." - type: string - default: "" - steps: - - run: - name: Install python and dependencies - command: | - sudo apt update - sudo apt install python3 python3-pip --assume-yes --no-install-recommends - if [[ "<< parameters.packages >>" != "" ]] - then - echo "Installing additional packages..." - python3 -m pip install --user << parameters.packages >> - fi - - install_foundry: - description: "Install Foundry." - parameters: - version: - type: string - default: "nightly" - install_path: - type: string - default: /home/circleci/bin - steps: - - run: - name: Setup Foundry environment variables - command: | - FOUNDRY_REPO="foundry-rs/foundry" - FOUNDRY_VERSION="<< parameters.version >>" - # Make authenticated requests when the Github token is available - if [[ -n "$GITHUB_ACCESS_TOKEN" ]]; then - EXTRA_HEADERS=(--header 'Authorization: Bearer '"${GITHUB_ACCESS_TOKEN}") - fi - FOUNDRY_RELEASE_SHA=$(curl \ - --silent \ - --fail \ - --show-error \ - "${EXTRA_HEADERS[@]}" \ - "https://api.github.com/repos/${FOUNDRY_REPO}/git/refs/tags/${FOUNDRY_VERSION}" \ - | jq --raw-output .object.sha \ - ) - echo "export FOUNDRY_REPO=$FOUNDRY_REPO" >> "$BASH_ENV" - echo "export FOUNDRY_VERSION=$FOUNDRY_VERSION" >> "$BASH_ENV" - echo "export FOUNDRY_RELEASE_TAG='nightly-${FOUNDRY_RELEASE_SHA}'" >> "$BASH_ENV" - # Save commit sha for caching - echo "$FOUNDRY_RELEASE_SHA" > /tmp/workspace/foundry-release-sha - - restore_cache: - keys: - - foundry-<< parameters.version >>-{{ arch }}-{{ checksum "/tmp/workspace/foundry-release-sha" }} - # WARNING! If you edit anything between here and save_cache, remember to invalidate the cache manually. - - run: - name: Install foundry - command: | - ! forge --version 2> /dev/null - curl \ - --fail \ - --location \ - --output /tmp/foundry.tar.gz \ - "https://github.com/${FOUNDRY_REPO}/releases/download/${FOUNDRY_RELEASE_TAG}/foundry_${FOUNDRY_VERSION}_linux_amd64.tar.gz" - cd "<< parameters.install_path >>" - tar --extract --gzip --file /tmp/foundry.tar.gz --one-top-level - ln --symbolic --force foundry/{forge,anvil,cast,chisel} . - - save_cache: - key: foundry-<< parameters.version >>-{{ arch }}-{{ checksum "/tmp/workspace/foundry-release-sha" }} - paths: - - << parameters.install_path >> - - # -------------------------------------------------------------------------- - # Build Commands - - setup_prerelease_commit_hash: - steps: - - run: - name: Store commit hash and prerelease - command: | - if [[ $CIRCLE_BRANCH == release || -n $CIRCLE_TAG ]]; then - echo -n > prerelease.txt; - else - date -u +"nightly.%Y.%-m.%-d" > prerelease.txt; - fi - echo -n "$CIRCLE_SHA1" > commit_hash.txt - - run_build: - steps: - - run: - name: Build - command: scripts/ci/build.sh - - run_build_ossfuzz: - steps: - - run: - name: Build_ossfuzz - command: scripts/ci/build_ossfuzz.sh - - run_proofs: - steps: - - run: - name: Correctness proofs for optimization rules - command: scripts/run_proofs.sh - - run_soltest: - steps: - - run: - name: soltest - no_output_timeout: 30m - command: .circleci/soltest.sh - - run_soltest_all: - steps: - - run: - name: soltest_all - no_output_timeout: 30m - command: .circleci/soltest_all.sh - - run_cmdline_tests: - steps: - - run: - name: command line tests - no_output_timeout: 30m - command: .circleci/parallel_cli_tests.py - - run_docs_pragma_min_version: - steps: - - run: - name: docs pragma version check - command: scripts/docs_version_pragma_check.sh - - # -------------------------------------------------------------------------- - # Artifact Commands - - store_artifacts_solc: - description: Store compiled solc executable as artifact - steps: - - store_artifacts: - path: build/solc/solc - destination: solc - - store_artifacts_yul_phaser: - steps: - - store_artifacts: - path: build/tools/yul-phaser - destination: yul-phaser - - persist_executables_to_workspace: - description: Persist compiled target executables to workspace - steps: - - persist_to_workspace: - root: build - paths: - - solc/solc - - test/soltest - - test/tools/solfuzzer - - persist_executables_to_workspace_osx: - description: Persist compiled target executables to workspace on macOS - steps: - - persist_to_workspace: - root: . - paths: - - build/solc/solc - - build/test/soltest - - build/test/tools/solfuzzer - - persist_ossfuzz_executables_to_workspace: - description: Persist compiled OSSFUZZ executables to workspace - steps: - - persist_to_workspace: - root: build - paths: - - test/tools/ossfuzz/abiv2_proto_ossfuzz - - test/tools/ossfuzz/abiv2_isabelle_ossfuzz - - test/tools/ossfuzz/const_opt_ossfuzz - - test/tools/ossfuzz/solc_mutator_ossfuzz - - test/tools/ossfuzz/solc_ossfuzz - - test/tools/ossfuzz/stack_reuse_codegen_ossfuzz - - test/tools/ossfuzz/strictasm_assembly_ossfuzz - - test/tools/ossfuzz/strictasm_diff_ossfuzz - - test/tools/ossfuzz/strictasm_opt_ossfuzz - - test/tools/ossfuzz/yul_proto_diff_ossfuzz - - test/tools/ossfuzz/yul_proto_diff_custom_mutate_ossfuzz - - test/tools/ossfuzz/yul_proto_ossfuzz - - test/tools/ossfuzz/sol_proto_ossfuzz - - store_artifacts_test_results: - description: Store test output dir as artifact - steps: - - store_artifacts: - path: test_results/ - destination: test_results/ - - # -------------------------------------------------------------------------- - # Complex Build Commands - - soltest: - steps: - - checkout - - attach_workspace: - at: build - # NOTE: Different build jobs produce different soltest executables (release/debug, - # clang/gcc, windows/linux/macos, etc.). The executable used by these steps comes from the - # attached workspace and we only see the items added to the workspace by jobs we depend on. - - run_soltest - - store_test_results: - path: test_results/ - - store_artifacts_test_results - - matrix_notify_failure_unless_pr - - test_lsp: - steps: - - checkout - - attach_workspace: - at: build - - run: - name: Install dependencies - command: pip install --user deepdiff colorama - - run: - name: Executing solc LSP test suite - command: test/lsp.py build/solc/solc --non-interactive - - matrix_notify_failure_unless_pr - - build: - steps: - - checkout - - run_build - - store_artifacts_solc - - store_artifacts_yul_phaser - - persist_executables_to_workspace - - matrix_notify_failure_unless_pr - - soltest_all: - steps: - - checkout - - attach_workspace: - at: build - - run_soltest_all - - store_test_results: - path: test_results/ - - store_artifacts_test_results - - matrix_notify_failure_unless_pr - - cmdline_tests: - steps: - - checkout - - attach_workspace: - at: build - - run_cmdline_tests - - store_test_results: - path: test_results/ - - store_artifacts_test_results - - matrix_notify_failure_unless_pr - - install_dependencies_osx: - steps: - # FIXME: We used to cache dependencies on macOS but now it takes longer than just installing - # them each time. See https://github.com/ethereum/solidity/issues/12925. - - run: - name: Install build dependencies - command: .circleci/osx_install_dependencies.sh - -defaults: - - # -------------------------------------------------------------------------- - # Matrix templates - - - bytecode_compare_env_presets: &bytecode_compare_env_presets - PRESETS: - legacy-optimize - legacy-no-optimize - via-ir-optimize - via-ir-no-optimize - - - bytecode_compare_preset_matrix: &bytecode_compare_preset_matrix - parameters: - preset: - # NOTE: Keep in sync with preset list in bytecode_compare_env_presets - - legacy-optimize - - legacy-no-optimize - - via-ir-optimize - - via-ir-no-optimize - - # -------------------------------------------------------------------------- - # -------------------------------------------------------------------------- - # Base Image Templates - - - base_archlinux: &base_archlinux - docker: - - image: archlinux:base - environment: &base_archlinux_env - TERM: xterm - MAKEFLAGS: -j 3 - CPUs: 3 - - - base_archlinux_large: &base_archlinux_large - <<: *base_archlinux - resource_class: large - environment: &base_archlinux_large_env - <<: *base_archlinux_env - MAKEFLAGS: -j 5 - CPUs: 5 - - - base_cimg_small: &base_cimg_small - docker: - - image: cimg/base:current - resource_class: small - environment: &base_cimg_small_env - TERM: xterm - MAKEFLAGS: -j 2 - CPUs: 2 - - - base_ems_large: &base_ems_large - docker: - - image: << pipeline.parameters.emscripten-docker-image >> - resource_class: large - environment: &base_ems_large_env - TERM: xterm - MAKEFLAGS: -j 5 - CPUs: 5 - - - base_node_small: &base_node_small - docker: - - image: cimg/node:current - resource_class: small - environment: &base_node_small_env - TERM: xterm - MAKEFLAGS: -j 2 - CPUs: 2 - - - base_osx: &base_osx - macos: - xcode: "14.2.0" - resource_class: macos.x86.medium.gen2 - environment: &base_osx_env - TERM: xterm - MAKEFLAGS: -j5 - CPUs: 5 - - - base_python_small: &base_python_small - docker: - - image: cimg/python:3.6 - resource_class: small - environment: &base_python_small_env - TERM: xterm - MAKEFLAGS: -j 2 - CPUs: 2 - - - base_ubuntu_clang: &base_ubuntu_clang - docker: - - image: << pipeline.parameters.ubuntu-clang-ossfuzz-docker-image >> - environment: &base_ubuntu_clang_env - TERM: xterm - MAKEFLAGS: -j 3 - CPUs: 3 - - - base_ubuntu_clang_small: &base_ubuntu_clang_small - <<: *base_ubuntu_clang - resource_class: small - environment: &base_ubuntu_clang_small_env - <<: *base_ubuntu_clang_env - MAKEFLAGS: -j 2 - CPUs: 2 - - - base_ubuntu2004: &base_ubuntu2004 - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> - environment: &base_ubuntu2004_env - TERM: xterm - MAKEFLAGS: -j 3 - CPUs: 3 - - - base_ubuntu2004_small: &base_ubuntu2004_small - <<: *base_ubuntu2004 - resource_class: small - environment: &base_ubuntu2004_small_env - <<: *base_ubuntu2004_env - MAKEFLAGS: -j 2 - CPUs: 2 - - - base_ubuntu2004_xlarge: &base_ubuntu2004_xlarge - <<: *base_ubuntu2004 - resource_class: xlarge - environment: &base_ubuntu2004_xlarge_env - <<: *base_ubuntu2004_env - MAKEFLAGS: -j 10 - CPUs: 10 - - - base_ubuntu2204: &base_ubuntu2204 - docker: - - image: << pipeline.parameters.ubuntu-2204-docker-image >> - environment: &base_ubuntu2204_env - TERM: xterm - MAKEFLAGS: -j 3 - CPUs: 3 - - - base_ubuntu2204_clang: &base_ubuntu2204_clang - docker: - - image: << pipeline.parameters.ubuntu-2204-clang-docker-image >> - environment: &base_ubuntu2204_clang_env - TERM: xterm - CC: clang - CXX: clang++ - MAKEFLAGS: -j 3 - CPUs: 3 - - - base_ubuntu2204_clang_large: &base_ubuntu2204_clang_large - <<: *base_ubuntu2204_clang - resource_class: large - environment: &base_ubuntu2204_clang_large_env - <<: *base_ubuntu2204_clang_env - MAKEFLAGS: -j 5 - CPUs: 5 - - - base_ubuntu2204_small: &base_ubuntu2204_small - <<: *base_ubuntu2204 - resource_class: small - environment: &base_ubuntu2204_small_env - <<: *base_ubuntu2204_env - MAKEFLAGS: -j 2 - CPUs: 2 - - - base_ubuntu2204_large: &base_ubuntu2204_large - <<: *base_ubuntu2204 - resource_class: large - environment: &base_ubuntu2204_large_env - <<: *base_ubuntu2204_env - MAKEFLAGS: -j 5 - CPUs: 5 - - - base_ubuntu2204_xlarge: &base_ubuntu2204_xlarge - <<: *base_ubuntu2204 - resource_class: xlarge - environment: &base_ubuntu2204_xlarge_env - <<: *base_ubuntu2204_env - MAKEFLAGS: -j 10 - CPUs: 10 - - - base_win: &base_win - executor: - name: win/default - shell: bash.exe - - - base_win_large: &base_win_large - executor: - name: win/default - size: large - shell: bash.exe - - # -------------------------------------------------------------------------- - # Workflow Templates - - - on_all_tags_and_branches: &on_all_tags_and_branches - filters: - tags: - only: /.*/ - - - on_version_tags: &on_version_tags - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - - - on_develop: &on_develop - filters: - branches: - only: - - develop - - - requires_nothing: &requires_nothing - <<: *on_all_tags_and_branches - - - requires_b_ubu: &requires_b_ubu - <<: *on_all_tags_and_branches - requires: - - b_ubu - - - requires_b_ubu_clang: &requires_b_ubu_clang - <<: *on_all_tags_and_branches - requires: - - b_ubu_clang - - - requires_b_ubu_force_release: &requires_b_ubu_force_release - <<: *on_all_tags_and_branches - requires: - - b_ubu_force_release - - - requires_b_ubu_static: &requires_b_ubu_static - <<: *on_all_tags_and_branches - requires: - - b_ubu_static - - - requires_b_archlinux: &requires_b_archlinux - <<: *on_all_tags_and_branches - requires: - - b_archlinux - - - requires_b_ubu_codecov: &requires_b_ubu_codecov - <<: *on_all_tags_and_branches - requires: - - b_ubu_codecov - - - requires_b_osx: &requires_b_osx - <<: *on_all_tags_and_branches - requires: - - b_osx - - - requires_b_ubu_asan: &requires_b_ubu_asan - <<: *on_all_tags_and_branches - requires: - - b_ubu_asan - - - requires_b_ubu_asan_clang: &requires_b_ubu_asan_clang - <<: *on_all_tags_and_branches - requires: - - b_ubu_asan_clang - - - requires_b_ubu_ubsan_clang: &requires_b_ubu_ubsan_clang - <<: *on_all_tags_and_branches - requires: - - b_ubu_ubsan_clang - - - requires_b_ems: &requires_b_ems - <<: *on_all_tags_and_branches - requires: - - b_ems - - - requires_b_ubu_ossfuzz: &requires_b_ubu_ossfuzz - <<: *on_all_tags_and_branches - requires: - - b_ubu_ossfuzz - - - requires_b_win: &requires_b_win - <<: *on_all_tags_and_branches - requires: - - b_win - - # -------------------------------------------------------------------------- - # Parameterized Job Templates - - # Separate compile-only runs of those external tests where a full run takes much longer. - # Also see https://github.com/ethereum/solidity/pull/14234 for why we excluded those - # external tests from the nightly jobs. - - job_ems_compile_ext_colony: &job_ems_compile_ext_colony - <<: *requires_b_ems - name: t_ems_compile_ext_colony - project: colony - binary_type: solcjs - compile_only: 1 - image: cimg/node:14.20 - python2: true - - - job_native_test_ext_gnosis: &job_native_test_ext_gnosis - <<: *requires_b_ubu_static - name: t_native_test_ext_gnosis - project: gnosis - binary_type: native - image: cimg/node:18.16 - - - job_native_test_ext_zeppelin: &job_native_test_ext_zeppelin - <<: *requires_b_ubu_static - name: t_native_test_ext_zeppelin - project: zeppelin - binary_type: native - image: cimg/node:18.16 - resource_class: large - - - job_native_test_ext_ens: &job_native_test_ext_ens - <<: *requires_b_ubu_static - name: t_native_test_ext_ens - project: ens - binary_type: native - image: cimg/node:18.16 - - - job_native_test_ext_trident: &job_native_test_ext_trident - <<: *requires_b_ubu_static - name: t_native_test_ext_trident - project: trident - binary_type: native - image: cimg/node:18.16 - - - job_native_test_ext_euler: &job_native_test_ext_euler - <<: *requires_b_ubu_static - name: t_native_test_ext_euler - project: euler - binary_type: native - resource_class: medium - - - job_native_test_ext_yield_liquidator: &job_native_test_ext_yield_liquidator - <<: *requires_b_ubu_static - name: t_native_test_ext_yield_liquidator - project: yield-liquidator - binary_type: native - image: cimg/node:18.16 - - - job_native_test_ext_bleeps: &job_native_test_ext_bleeps - <<: *requires_b_ubu_static - name: t_native_test_ext_bleeps - project: bleeps - binary_type: native - resource_class: medium - - - job_native_test_ext_pool_together: &job_native_test_ext_pool_together - <<: *requires_b_ubu_static - name: t_native_test_ext_pool_together - project: pool-together - binary_type: native - image: cimg/node:18.16 - - - job_native_test_ext_perpetual_pools: &job_native_test_ext_perpetual_pools - <<: *requires_b_ubu_static - name: t_native_test_ext_perpetual_pools - project: perpetual-pools - binary_type: native - image: cimg/node:18.16 - - - job_native_test_ext_uniswap: &job_native_test_ext_uniswap - <<: *requires_b_ubu_static - name: t_native_test_ext_uniswap - project: uniswap - binary_type: native - image: cimg/node:18.16 - - - job_native_test_ext_prb_math: &job_native_test_ext_prb_math - <<: *requires_b_ubu_static - name: t_native_test_ext_prb_math - project: prb-math - binary_type: native - image: cimg/rust:1.70 - - - job_native_test_ext_elementfi: &job_native_test_ext_elementfi - <<: *requires_b_ubu_static - name: t_native_test_ext_elementfi - project: elementfi - binary_type: native - image: cimg/node:18.16 - resource_class: medium - - - job_native_test_ext_brink: &job_native_test_ext_brink - <<: *requires_b_ubu_static - name: t_native_test_ext_brink - project: brink - binary_type: native - image: cimg/node:18.16 - - - job_native_test_ext_chainlink: &job_native_test_ext_chainlink - <<: *requires_b_ubu_static - name: t_native_test_ext_chainlink - project: chainlink - binary_type: native - image: cimg/node:18.16 - resource_class: large # Tests run out of memory on a smaller machine - - - job_native_test_ext_gp2: &job_native_test_ext_gp2 - <<: *requires_b_ubu_static - name: t_native_test_ext_gp2 - project: gp2 - binary_type: native - image: cimg/node:18.16 - - - job_b_ubu_asan_clang: &job_b_ubu_asan_clang - <<: *on_all_tags_and_branches - name: b_ubu_asan_clang - cmake_options: -DSANITIZE=address - - - job_b_ubu_ubsan_clang: &job_b_ubu_ubsan_clang - <<: *on_all_tags_and_branches - name: b_ubu_ubsan_clang - cmake_options: -DSANITIZE=undefined - -# ----------------------------------------------------------------------------------------------- -jobs: - - chk_spelling: - <<: *base_python_small - steps: - - checkout - - attach_workspace: - at: build - - run: - name: Install dependencies - command: | - pip install --user codespell - - run: - name: Check spelling - command: | - ~/.local/bin/codespell \ - --skip "*.enc,.git,Dockerfile*,LICENSE,codespell_whitelist.txt,codespell_ignored_lines.txt" \ - --ignore-words scripts/codespell_whitelist.txt \ - --exclude-file scripts/codespell_ignored_lines.txt - - matrix_notify_failure_unless_pr - - chk_docs_examples: - <<: *base_node_small - steps: - - checkout - - attach_workspace: - at: build - - run: - name: JS deps - command: sudo npm install -g solhint - - run: - name: Test Docs examples - command: test/docsCodeStyle.sh - - matrix_notify_failure_unless_pr - - chk_coding_style: - <<: *base_cimg_small - steps: - - checkout - - run: - name: Install shellcheck - command: | - sudo apt -q update - sudo apt install -y shellcheck - - run: - name: Check for C++ coding style - command: scripts/check_style.sh - - run: - name: checking shell scripts - command: scripts/chk_shellscripts/chk_shellscripts.sh - - run: - name: Check for broken symlinks - command: scripts/check_symlinks.sh - - matrix_notify_failure_unless_pr - - chk_errorcodes: - <<: *base_python_small - steps: - - checkout - - run: - name: Check for error codes - command: scripts/error_codes.py --check - - matrix_notify_failure_unless_pr - - chk_pylint: - <<: *base_cimg_small - steps: - - checkout - - install_python3: - packages: > - pylint - z3-solver - pygments-lexer-solidity - parsec - tabulate - deepdiff - colorama - requests - - run: pylint --version - - run: - name: Linting Python Scripts - command: scripts/pylint_all.py - - matrix_notify_failure_unless_pr - - chk_antlr_grammar: - <<: *base_cimg_small - steps: - - checkout - - run: - name: Install Java - command: | - sudo apt -q update - sudo apt install -y openjdk-17-jdk - - run: - name: Run tests - command: scripts/test_antlr_grammar.sh - - matrix_notify_failure_unless_pr - - chk_buglist: - <<: *base_node_small - steps: - - checkout - - run: - name: JS deps - command: | - npm install download - npm install JSONPath - npm install mktemp - - run: - name: Test buglist - command: test/buglistTests.js - - matrix_notify_failure_unless_pr - - chk_proofs: - <<: *base_cimg_small - steps: - - checkout - - install_python3: - packages: z3-solver - - run_proofs - - matrix_notify_failure_unless_pr - - chk_docs_pragma_min_version: - <<: *base_ubuntu2204_small - steps: - - checkout - - run_docs_pragma_min_version - - matrix_notify_failure_unless_pr - - t_ubu_pyscripts: - <<: *base_ubuntu2204_small - steps: - - checkout - - run: - name: Python unit tests - command: python3 test/pyscriptTests.py - - matrix_notify_failure_unless_pr - - t_win_pyscripts: - <<: *base_win - steps: - - run: git config --global core.autocrlf false - - checkout - - run: - name: Python unit tests - command: python.exe test/pyscriptTests.py - - matrix_notify_failure_unless_pr - - b_ubu: &b_ubu - # this runs 2x faster on xlarge but takes 4x more resources (compared to medium). - # Enough other jobs depend on it that it's worth it though. - <<: *base_ubuntu2204_xlarge - steps: - - build - - # x64 ASAN build, for testing for memory related bugs - b_ubu_asan: &b_ubu_asan - # Runs slightly faster on large and xlarge but we only run it nightly so efficiency matters more. - <<: *base_ubuntu2204 - environment: - <<: *base_ubuntu2204_env - CMAKE_OPTIONS: -DSANITIZE=address - CMAKE_BUILD_TYPE: Release - steps: - - build - - b_ubu_clang: &b_ubu_clang - <<: *base_ubuntu2204_clang_large - environment: - <<: *base_ubuntu2204_clang_large_env - MAKEFLAGS: -j 10 - steps: - - build - - b_ubu_san_clang: - # This runs a bit faster on large and xlarge but on nightly efficiency matters more. - parameters: - cmake_options: - type: string - <<: *base_ubuntu2204_clang - environment: - <<: *base_ubuntu2204_clang_env - CMAKE_OPTIONS: << parameters.cmake_options >> - steps: - - build - - b_ubu_force_release: &b_ubu_force_release - <<: *b_ubu - environment: - <<: *base_ubuntu2204_xlarge_env - FORCE_RELEASE: ON - - b_ubu_static: - # We temporarily keep building static release binaries on ubuntu 20.04 - # to avoid glibc incompatibilities. - # See: https://github.com/ethereum/solidity/issues/13954 - # On large runs 2x faster than on medium. 3x on xlarge. - <<: *base_ubuntu2004_xlarge - environment: - <<: *base_ubuntu2204_xlarge_env - CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DUSE_Z3_DLOPEN=ON -DUSE_CVC4=OFF -DSOLC_STATIC_STDLIBS=ON - steps: - - checkout - - run_build - - run: - name: strip binary - command: strip build/solc/solc - - store_artifacts: - path: build/solc/solc - destination: solc-static-linux - - run: mv build/solc/solc build/solc/solc-static-linux - - persist_to_workspace: - root: build - paths: - - solc/solc-static-linux - - matrix_notify_failure_unless_pr - - b_ubu_codecov: - # Runs ~30% faster on large but we only run it nightly so efficiency matters more. - <<: *base_ubuntu2204 - environment: - <<: *base_ubuntu2204_env - COVERAGE: ON - CMAKE_BUILD_TYPE: Debug - steps: - - checkout - - run_build - - persist_executables_to_workspace - - matrix_notify_failure_unless_pr - - t_ubu_codecov: - <<: *base_ubuntu2204_large - environment: - <<: *base_ubuntu2204_large_env - EVM: << pipeline.parameters.evm-version >> - OPTIMIZE: 1 - steps: - - checkout - - attach_workspace: - at: build - - run: - name: "soltest: Syntax Tests" - command: build/test/soltest -t 'syntaxTest*' -- --testpath test - - run: - name: "Code Coverage: Syntax Tests" - command: codecov --flags syntax --gcov-root build - - run_soltest - - run: - name: "Coverage: All" - command: codecov --flags all --gcov-root build - - store_artifacts_test_results - - matrix_notify_failure_unless_pr - - # Builds in C++20 mode and uses debug build in order to speed up. - # Do *NOT* store any artifacts or workspace as we don't run tests on this build. - b_ubu_cxx20: - <<: *base_ubuntu2204_large - environment: - <<: *base_ubuntu2204_large_env - CMAKE_BUILD_TYPE: Debug - CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 -DUSE_CVC4=OFF - MAKEFLAGS: -j 10 - steps: - - checkout - - run_build - - matrix_notify_failure_unless_pr - - b_ubu_ossfuzz: &b_ubu_ossfuzz - <<: *base_ubuntu_clang - steps: - - checkout - - setup_prerelease_commit_hash - - run_build_ossfuzz - - persist_ossfuzz_executables_to_workspace - - matrix_notify_failure_unless_pr - - t_ubu_ossfuzz: &t_ubu_ossfuzz - <<: *base_ubuntu_clang_small - steps: - - checkout - - attach_workspace: - at: build - - run: - name: Regression tests - command: | - git clone https://github.com/ethereum/solidity-fuzzing-corpus /tmp/solidity-fuzzing-corpus - mkdir -p test_results - scripts/regressions.py -o test_results - - store_test_results: - path: test_results/ - - store_artifacts_test_results - - b_archlinux: - <<: *base_archlinux_large - environment: - <<: *base_archlinux_large_env - # This can be switched off if we run out of sync with Arch. - USE_Z3: ON - steps: - - run: - name: Install build dependencies - command: | - pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake cvc4 git openssh tar - - checkout - - run_build - - store_artifacts_solc - - persist_executables_to_workspace - - matrix_notify_failure_unless_pr - - b_osx: - <<: *base_osx - environment: - <<: *base_osx_env - CMAKE_BUILD_TYPE: Release - steps: - - checkout - - install_dependencies_osx - - run_build - - store_artifacts_solc - - store_artifacts_yul_phaser - - persist_executables_to_workspace_osx - - matrix_notify_failure_unless_pr - - t_osx_soltest: &t_osx_soltest - <<: *base_osx - environment: - <<: *base_osx_env - EVM: << pipeline.parameters.evm-version >> - OPTIMIZE: 0 - steps: - - checkout - - install_dependencies_osx - - attach_workspace: - at: . - - run_soltest - - store_test_results: - path: test_results/ - - store_artifacts_test_results - - matrix_notify_failure_unless_pr - - t_osx_cli: - <<: *base_osx - parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py - steps: - - checkout - - install_dependencies_osx - - attach_workspace: - at: . - - run_cmdline_tests - - store_artifacts_test_results - - matrix_notify_failure_unless_pr - - b_ems: - <<: *base_ems_large - environment: - <<: *base_ems_large_env - MAKEFLAGS: -j 10 - steps: - - checkout - - run: - name: Build - command: | - scripts/ci/build_emscripten.sh - - store_artifacts: - path: upload/soljson.js - destination: soljson.js - - run: mkdir -p workspace - - run: cp upload/soljson.js workspace/soljson.js - - run: scripts/get_version.sh > workspace/version.txt - - persist_to_workspace: - root: workspace - paths: - - soljson.js - - version.txt - - matrix_notify_failure_unless_pr - - b_docs: - <<: *base_ubuntu2204_small - steps: - - checkout - - setup_prerelease_commit_hash - - run: - name: Build documentation - command: docs/docs.sh - - store_artifacts: - path: docs/_build/html/ - destination: docs-html - - matrix_notify_failure_unless_pr - - t_ubu_soltest_all: &t_ubu_soltest_all - <<: *base_ubuntu2204_large - parallelism: 50 - steps: - - soltest_all - - t_ubu_lsp: &t_ubu_lsp - <<: *base_ubuntu2204_small - steps: - - test_lsp - - t_archlinux_soltest: &t_archlinux_soltest - <<: *base_archlinux - parallelism: 20 - environment: - <<: *base_archlinux_env - EVM: << pipeline.parameters.evm-version >> - OPTIMIZE: 0 - # For Archlinux we do not have prebuilt docker images and we would need to build evmone from source, - # thus we forgo semantics tests to speed things up. - SOLTEST_FLAGS: --no-semantic-tests --no-smt - steps: - - run: - name: Install runtime dependencies - command: | - pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake z3 cvc4 git openssh tar - - soltest - - t_ubu_clang_soltest: &t_ubu_clang_soltest - <<: *base_ubuntu2204_clang - parallelism: 20 - environment: - <<: *base_ubuntu2204_clang_env - EVM: << pipeline.parameters.evm-version >> - OPTIMIZE: 0 - # The high parallelism in this job is causing the SMT tests to run out of memory, - # so disabling for now. - SOLTEST_FLAGS: --no-smt - steps: - - soltest - - t_ubu_force_release_soltest_all: &t_ubu_force_release_soltest_all - # NOTE: This definition is identical to t_ubu_soltest_all but in the workflow we make it depend on - # a different job (b_ubu_force_release) so the workspace it attaches contains a different executable. - <<: *t_ubu_soltest_all - - t_ubu_cli: &t_ubu_cli - <<: *base_ubuntu2204_small - parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py - steps: - - cmdline_tests - - t_ubu_force_release_cli: &t_ubu_force_release_cli - <<: *t_ubu_cli - - t_ubu_locale: - <<: *base_ubuntu2204_small - steps: - - checkout - - attach_workspace: - at: build - - run: test/localeTest.sh build/solc/solc - - matrix_notify_failure_unless_pr - - t_ubu_asan_cli: - # Runs slightly faster on medium but we only run it nightly so efficiency matters more. - <<: *base_ubuntu2204 - parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py - environment: - <<: *base_ubuntu2204_env - ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2 - # Suppress CLN memory leak. - # See: https://github.com/ethereum/solidity/issues/13891 for details. - LSAN_OPTIONS: suppressions=/root/project/.circleci/cln-asan.supp:print_suppressions=0 - steps: - - cmdline_tests - - t_ubu_asan_soltest: - <<: *base_ubuntu2204 - parallelism: 20 - environment: - <<: *base_ubuntu2204_env - EVM: << pipeline.parameters.evm-version >> - OPTIMIZE: 0 - SOLTEST_FLAGS: --no-smt - ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2 - # Suppress CLN memory leak. - # See: https://github.com/ethereum/solidity/issues/13891 for details. - LSAN_OPTIONS: suppressions=/root/project/.circleci/cln-asan.supp - steps: - - soltest - - t_ubu_asan_clang_soltest: - <<: *base_ubuntu2204_clang - parallelism: 20 - environment: - <<: *base_ubuntu2204_clang_env - EVM: << pipeline.parameters.evm-version >> - OPTIMIZE: 0 - SOLTEST_FLAGS: --no-smt - ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2 - steps: - - soltest - - t_ubu_ubsan_clang_soltest: - <<: *base_ubuntu2204_clang - parallelism: 20 - environment: - <<: *base_ubuntu2204_clang_env - EVM: << pipeline.parameters.evm-version >> - SOLTEST_FLAGS: --no-smt - steps: - - soltest - - t_ubu_ubsan_clang_cli: - <<: *base_ubuntu2204_clang - parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py - steps: - - cmdline_tests - - t_ems_solcjs: - # Unlike other t_ems jobs this one actually runs 2x faster on medium (compared to small). - <<: *base_ubuntu2204 - steps: - - checkout - - attach_workspace: - at: /tmp/workspace - - run: - name: Install test dependencies - command: | - apt-get update - apt-get install -qqy --no-install-recommends nodejs npm - - run: - name: Test solcjs - no_output_timeout: 30m - command: | - node --version - npm --version - test/externalTests/solc-js/solc-js.sh /tmp/workspace/soljson.js $(cat /tmp/workspace/version.txt) - - matrix_notify_failure_unless_pr - - t_ems_ext_hardhat: - <<: *base_node_small - docker: - - image: cimg/node:18.16 - environment: - <<: *base_node_small_env - HARDHAT_TESTS_SOLC_PATH: /tmp/workspace/soljson.js - steps: - - checkout - - attach_workspace: - at: /tmp/workspace - - run: git clone --depth 1 https://github.com/nomiclabs/hardhat.git - - run: - name: Install dependencies - command: | - cd hardhat - yarn - - run: - name: Run hardhat-core test suite - command: | - HARDHAT_TESTS_SOLC_VERSION=$(scripts/get_version.sh) - export HARDHAT_TESTS_SOLC_VERSION - - # NOTE: This is expected to work without running `yarn build` first. - cd hardhat/packages/hardhat-core - yarn test - - matrix_notify_failure_unless_pr - - t_ext: - parameters: - project: - type: string - binary_type: - type: enum - enum: - - solcjs - - native - compile_only: - type: integer - default: 0 - image: - type: string - default: cimg/node:current - resource_class: - type: string - default: small - python2: - type: boolean - default: false - docker: - - image: << parameters.image >> - resource_class: << parameters.resource_class >> - # NOTE: Each external test runs up to 6 independent settings presets. If parallelism is higher than - # actual preset count, some runs will exit immediately. If it's lower, some runs will get more than one preset. - parallelism: 6 - environment: - TERM: xterm - COMPILE_ONLY: << parameters.compile_only >> - steps: - - checkout - - attach_workspace: - at: /tmp/workspace - - install_foundry - - install_python3: - packages: requests - - run: - name: Install lsof - command: | - # lsof is used by Colony in its stop-blockchain-client.sh script - sudo apt update - sudo apt-get --quiet --assume-yes --no-install-recommends install lsof - - when: - condition: << parameters.python2 >> - steps: - - run: - name: Install Python 2 and make it the default - command: | - # python is used by node-gyp to build native modules (needed for Colony). - # In the 14.x image node-gyp still requires Python 2. - sudo apt install python2 --assume-yes --no-install-recommends - sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 1 - - when: - condition: - equal: [<< parameters.binary_type >>, "solcjs"] - steps: - - run: - name: External << parameters.project >> tests (<< parameters.binary_type >>) - command: | - test/external_tests.py test --solc-binary-type "<< parameters.binary_type >>" --solc-binary-path /tmp/workspace/soljson.js --run "<< parameters.project >>" - - when: - condition: - equal: [<< parameters.binary_type >>, "native"] - steps: - - run: - name: External << parameters.project >> tests (<< parameters.binary_type >>) - command: | - test/external_tests.py test --solc-binary-type "<< parameters.binary_type >>" --solc-binary-path /tmp/workspace/solc/solc-static-linux --run "<< parameters.project >>" - - store_artifacts: - path: reports/externalTests/ - # persist_to_workspace fails if the directory does not exist and the test script will create - # it only if it actually has benchmark results. - - run: mkdir -p reports/externalTests/ - - persist_to_workspace: - root: . - paths: - - reports/externalTests/ - - matrix_notify_failure_unless_pr - - c_ext_benchmarks: - <<: *base_node_small - steps: - - install_python3: - packages: requests - - checkout - - attach_workspace: - at: . - - run: - name: Combine benchmark reports - command: cat reports/externalTests/benchmark-*.json | scripts/externalTests/merge_benchmarks.sh > reports/externalTests/all-benchmarks.json - - run: - name: Summarize reports - command: cat reports/externalTests/all-benchmarks.json | scripts/externalTests/summarize_benchmarks.sh > reports/externalTests/summarized-benchmarks.json - - run: - name: Download reports from base branch - command: | - if [[ $CIRCLE_PULL_REQUEST != "" ]]; then - mkdir reports/externalTests/base-branch/ - cd reports/externalTests/base-branch/ - - pr_id=$(echo "$CIRCLE_PULL_REQUEST" | sed 's|\(.*\)\/||') - scripts_dir=../../../scripts - - # Our main goal here is to provide new benchmarks, the diff is optional. When benchmarks from - # the previous run are not available for whatever reason, we still succeed and just skip the diff. - # download_benchmarks.py exits with status 2 in that case. - if "${scripts_dir}/externalTests/download_benchmarks.py" --base-of-pr "$pr_id" || [[ $? == 2 ]]; then - echo 'export SKIP_BENCHMARK_DIFF=true' >> $BASH_ENV - fi - fi - - run: - name: Diff benchmarks - command: | - if [[ $CIRCLE_PULL_REQUEST != "" && $SKIP_BENCHMARK_DIFF != "true" ]]; then - cd reports/externalTests/ - mkdir diff/ - scripts_dir=../../scripts - - "${scripts_dir}/externalTests/benchmark_diff.py" table \ - --output-format markdown \ - --style humanized \ - base-branch/summarized-benchmarks-*.json \ - summarized-benchmarks.json > diff/benchmark-diff-summarized-table-markdown-humanized.md - "${scripts_dir}/externalTests/benchmark_diff.py" table \ - --output-format markdown \ - --style absolute \ - base-branch/summarized-benchmarks-*.json \ - summarized-benchmarks.json > diff/benchmark-diff-summarized-table-markdown-absolute.md - "${scripts_dir}/externalTests/benchmark_diff.py" inplace \ - --style absolute \ - base-branch/summarized-benchmarks-*.json \ - summarized-benchmarks.json > diff/benchmark-diff-summarized-inplace-absolute.md - "${scripts_dir}/externalTests/benchmark_diff.py" inplace \ - --style absolute \ - base-branch/all-benchmarks-*.json \ - all-benchmarks.json > diff/benchmark-diff-all-table-inplace-absolute.md - fi - - store_artifacts: - path: reports/externalTests/all-benchmarks.json - - store_artifacts: - path: reports/externalTests/summarized-benchmarks.json - - store_artifacts: - path: reports/externalTests/diff/ - - store_artifacts: - path: reports/externalTests/base-branch/ - - b_win: &b_win - <<: *base_win_large - steps: - # NOTE: Not disabling git's core.autocrlf here because we want to build using the typical Windows config. - - checkout - - restore_cache: - keys: - - dependencies-win-{{ arch }}-{{ checksum "scripts/install_deps.ps1" }} - # DO NOT EDIT between here and save_cache, but rather edit .\scripts\install_deps.ps1 - # WARNING! If you do edit anything here instead, remember to invalidate the cache manually. - - run: - name: "Installing dependencies" - command: .\scripts\install_deps.ps1 - shell: powershell.exe - - save_cache: - key: dependencies-win-{{ arch }}-{{ checksum "scripts/install_deps.ps1" }} - paths: - - .\deps - - run: - name: "Building solidity" - command: .circleci/build_win.ps1 - shell: powershell.exe - - run: - name: "Run solc.exe to make sure build was successful." - command: .\build\solc\Release\solc.exe --version - shell: powershell.exe - - store_artifacts: - path: upload/ - - persist_to_workspace: - root: build - paths: - - .\solc\*\solc.exe - - .\test\*\soltest.exe - - matrix_notify_failure_unless_pr - - t_win_soltest: &t_win_soltest - <<: *base_win - steps: - # NOTE: Git's default core.autocrlf is fine for running soltest. We get additional coverage - # for files using CRLF that way. - - checkout - - attach_workspace: - at: build - - run: - name: "Install evmone" - command: scripts/install_evmone.ps1 - shell: powershell.exe - - run: - name: "Run soltest" - command: .circleci/soltest.ps1 - shell: powershell.exe - - run: - name: Install LSP test dependencies - command: python -m pip install --user deepdiff colorama - - run: - name: Executing solc LSP test suite - command: python test/lsp.py build\solc\Release\solc.exe --non-interactive - shell: powershell.exe - - store_test_results: - path: test_results/ - - store_artifacts_test_results - - matrix_notify_failure_unless_pr - - # Note: b_bytecode_ubu_static is required because b_ubu_static and b_ubu - # are currently built on different Ubuntu base images. - # It can be safely removed once we move both to the same Ubuntu version. - b_bytecode_ubu_static: - parameters: - preset: - type: string - <<: *base_ubuntu2004_small - parallelism: 2 # For prepare_bytecode_report - steps: - - checkout - - attach_workspace: - at: build - - prepare_bytecode_report: - label: "ubuntu2004-static" - binary_type: native - binary_path: "build/solc/solc-static-linux" - preset: "<< parameters.preset >>" - - b_bytecode_ubu: - parameters: - preset: - type: string - <<: *base_ubuntu2204_small - parallelism: 2 # For prepare_bytecode_report - steps: - - checkout - - attach_workspace: - at: build - - prepare_bytecode_report: - label: "ubuntu" - binary_type: native - binary_path: "build/solc/solc" - preset: "<< parameters.preset >>" - - b_bytecode_osx: - parameters: - preset: - type: string - <<: *base_osx - parallelism: 2 # For prepare_bytecode_report - steps: - - checkout - - attach_workspace: - at: . - - prepare_bytecode_report: - label: "osx" - binary_type: native - binary_path: "build/solc/solc" - preset: "<< parameters.preset >>" - - b_bytecode_win: - parameters: - preset: - type: string - <<: *base_win - parallelism: 2 # For prepare_bytecode_report - steps: - # NOTE: For bytecode generation we need the input files to be byte-for-byte identical on all - # platforms so line ending conversions must absolutely be disabled. - - run: git config --global core.autocrlf false - - checkout - # Ensure windows has python3 alias required by prepare_bytecode_report - - run: ln -s /c/tools/miniconda3/python /c/tools/miniconda3/python3 - - attach_workspace: - at: build - - prepare_bytecode_report: - label: "windows" - binary_type: native - binary_path: "build/solc/Release/solc.exe" - preset: "<< parameters.preset >>" - - b_bytecode_ems: - parameters: - preset: - type: string - <<: *base_node_small - steps: - - checkout - - attach_workspace: - at: emscripten_build/libsolc - - prepare_bytecode_report: - label: "emscripten" - binary_type: solcjs - binary_path: "emscripten_build/libsolc/soljson.js" - preset: "<< parameters.preset >>" - - t_bytecode_compare: - <<: *base_ubuntu2204_small - environment: - <<: *base_ubuntu2204_small_env - <<: *bytecode_compare_env_presets - steps: - - checkout - - attach_workspace: - at: . - - run: .circleci/compare_bytecode_reports.sh $PRESETS - - store_artifacts: - # NOTE: store_artifacts does not support the 'when' attribute. - # Fortunately when the artifact does not exist it just says "No artifact files found" and ignores it. - path: bytecode-reports-*.zip - - matrix_notify_failure_unless_pr - - c_release_binaries: - <<: *base_ubuntu2204 - steps: - - checkout - - attach_workspace: - at: workspace - - run: - name: Gather and rename binaries from dependent jobs - command: | - mkdir github/ - cp workspace/solc/solc-static-linux github/solc-static-linux - cp workspace/build/solc/solc github/solc-macos - cp workspace/solc/Release/solc.exe github/solc-windows.exe - cp workspace/soljson.js github/soljson.js - - cd github/ - tar --create --file ../github-binaries.tar * - - store_artifacts: - path: github-binaries.tar - - run: - name: Rename binaries to solc-bin naming convention - command: | - full_version=$( - github/solc-static-linux --version | - sed -En 's/^Version: ([0-9.]+.*\+commit\.[0-9a-f]+(\.mod)?).*$/\1/p' - ) - - mkdir -p solc-bin/{linux-amd64,macosx-amd64,windows-amd64,bin} - - mv github/solc-static-linux "solc-bin/linux-amd64/solc-linux-amd64-v${full_version}" - mv github/solc-macos "solc-bin/macosx-amd64/solc-macosx-amd64-v${full_version}" - mv github/solc-windows.exe "solc-bin/windows-amd64/solc-windows-amd64-v${full_version}.exe" - mv github/soljson.js "solc-bin/bin/soljson-v${full_version}.js" - - cd solc-bin/ - tar --create --file ../solc-bin-binaries.tar * - - store_artifacts: - path: solc-bin-binaries.tar - - matrix_notify_failure_unless_pr - - matrix_notify_release_unless_pr - -workflows: - version: 2 - - main: - jobs: - # basic checks - - chk_spelling: *requires_nothing - - chk_coding_style: *requires_nothing - # DISABLED FOR 0.6.0 - chk_docs_examples: *requires_nothing - - chk_buglist: *requires_nothing - - chk_proofs: *requires_nothing - - chk_pylint: *requires_nothing - - chk_errorcodes: *requires_nothing - - chk_antlr_grammar: *requires_nothing - - chk_docs_pragma_min_version: *requires_nothing - - t_ubu_pyscripts: *requires_nothing - - t_win_pyscripts: *requires_nothing - - # build-only - - b_docs: *requires_nothing - # DISABLED FOR 0.8.18 - b_ubu_cxx20: *requires_nothing - # Issue: https://github.com/ethereum/solidity/issues/13868 - - b_ubu_ossfuzz: *requires_nothing - - # OS/X build and tests - - b_osx: *requires_nothing - - t_osx_cli: *requires_b_osx - - t_osx_soltest: *requires_b_osx - - # ArchLinux build and tests - - b_archlinux: *requires_nothing - - t_archlinux_soltest: *requires_b_archlinux - - # Static build - - b_ubu_static: *requires_nothing - - # Ubuntu build and tests - - b_ubu: *requires_nothing - - t_ubu_cli: *requires_b_ubu - - t_ubu_locale: *requires_b_ubu - - t_ubu_soltest_all: *requires_b_ubu - - b_ubu_clang: *requires_nothing - - t_ubu_clang_soltest: *requires_b_ubu_clang - - t_ubu_lsp: *requires_b_ubu - - # Ubuntu fake release build and tests - - b_ubu_force_release: *requires_nothing - - t_ubu_force_release_cli: *requires_b_ubu_force_release - - t_ubu_force_release_soltest_all: *requires_b_ubu_force_release - - # Emscripten build and tests that take 15 minutes or less - - b_ems: *requires_nothing - - t_ems_solcjs: *requires_b_ems - - t_ems_ext_hardhat: *requires_b_ems - - - t_ext: *job_ems_compile_ext_colony - - # NOTE: We are disabling the gnosis test suite due to version discrepancies that are difficult to fix. - # Check again after (and if) https://github.com/safe-global/safe-contracts/pull/644 is merged. - #- t_ext: *job_native_test_ext_gnosis - - t_ext: *job_native_test_ext_zeppelin - - t_ext: *job_native_test_ext_ens - - t_ext: *job_native_test_ext_yield_liquidator - - t_ext: *job_native_test_ext_perpetual_pools - - t_ext: *job_native_test_ext_uniswap - - t_ext: *job_native_test_ext_prb_math - - t_ext: *job_native_test_ext_elementfi - - t_ext: *job_native_test_ext_brink - # NOTE: We are disabling gp2 tests due to constant failures. - # - t_ext: *job_native_test_ext_gp2 - # NOTE: The external tests below were commented because they - # depend on a specific version of hardhat which does not support shanghai EVM. - #- t_ext: *job_native_test_ext_trident - #- t_ext: *job_native_test_ext_euler - #- t_ext: *job_native_test_ext_bleeps - #- t_ext: *job_native_test_ext_pool_together - #- t_ext: *job_native_test_ext_chainlink - - - c_ext_benchmarks: - <<: *requires_nothing - requires: - - t_ems_compile_ext_colony - # NOTE: We are disabling the gnosis test suite due to version discrepancies that are difficult to fix. - # Check again after (and if) https://github.com/safe-global/safe-contracts/pull/644 is merged. - #- t_native_test_ext_gnosis - - t_native_test_ext_zeppelin - - t_native_test_ext_ens - - t_native_test_ext_yield_liquidator - - t_native_test_ext_perpetual_pools - - t_native_test_ext_uniswap - - t_native_test_ext_elementfi - - t_native_test_ext_brink - # NOTE: We are disabling gp2 tests due to constant failures. - #- t_native_test_ext_gp2 - # TODO: Dropping prb-math from the benchmarks since it is not implemented yet - # in the new Foundry external testing infrastructure. - # - t_native_test_ext_prb_math - # NOTE: The external tests below were commented because they - # depend on a specific version of hardhat which does not support shanghai EVM. - #- t_native_test_ext_trident - #- t_native_test_ext_euler - #- t_native_test_ext_bleeps - #- t_native_test_ext_pool_together - #- t_native_test_ext_chainlink - - # Windows build and tests - - b_win: *requires_nothing - - t_win_soltest: *requires_b_win - - # Bytecode comparison: - - b_bytecode_ubu_static: - <<: *on_all_tags_and_branches - matrix: *bytecode_compare_preset_matrix - requires: - - b_ubu_static - - b_bytecode_ubu: - <<: *on_all_tags_and_branches - matrix: *bytecode_compare_preset_matrix - requires: - - b_ubu - - b_bytecode_win: - <<: *on_all_tags_and_branches - matrix: *bytecode_compare_preset_matrix - requires: - - b_win - - b_bytecode_osx: - <<: *on_all_tags_and_branches - matrix: *bytecode_compare_preset_matrix - requires: - - b_osx - - b_bytecode_ems: - <<: *on_all_tags_and_branches - matrix: *bytecode_compare_preset_matrix - requires: - - b_ems - - t_bytecode_compare: - <<: *on_all_tags_and_branches - requires: - - b_bytecode_ubu_static - - b_bytecode_ubu - - b_bytecode_win - - b_bytecode_osx - - b_bytecode_ems - - # Final artifacts - - c_release_binaries: - <<: *on_version_tags - requires: - - b_ubu_static - - b_osx - - b_win - - b_ems - - nightly: - - triggers: - - schedule: - cron: "0 0 * * *" - <<: *on_develop - - jobs: - # OSSFUZZ builds and (regression) tests - - b_ubu_ossfuzz: *requires_nothing - - t_ubu_ossfuzz: *requires_b_ubu_ossfuzz - - # Code Coverage enabled build and tests - - b_ubu_codecov: *requires_nothing - - t_ubu_codecov: *requires_b_ubu_codecov - - # ASan build and tests - - b_ubu_asan: *requires_nothing - - b_ubu_san_clang: *job_b_ubu_asan_clang - - t_ubu_asan_soltest: *requires_b_ubu_asan - - t_ubu_asan_clang_soltest: *requires_b_ubu_asan_clang - - t_ubu_asan_cli: *requires_b_ubu_asan - - # UBSan build and tests - - b_ubu_san_clang: *job_b_ubu_ubsan_clang - - t_ubu_ubsan_clang_soltest: *requires_b_ubu_ubsan_clang - - t_ubu_ubsan_clang_cli: *requires_b_ubu_ubsan_clang diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh deleted file mode 100755 index 8e795b1dc833..000000000000 --- a/.circleci/osx_install_dependencies.sh +++ /dev/null @@ -1,85 +0,0 @@ -#! /bin/bash -#------------------------------------------------------------------------------ -# Bash script to install osx dependencies -# -# The documentation for solidity is hosted at: -# -# https://docs.soliditylang.org -# -# ------------------------------------------------------------------------------ -# This file is part of solidity. -# -# solidity is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# solidity is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with solidity. If not, see -# -# (c) 2016-2019 solidity contributors. -# ------------------------------------------------------------------------------ - -# note that the following directories may be cached by circleci: -# - /usr/local/bin -# - /usr/local/sbin -# - /usr/local/lib -# - /usr/local/include -# - /usr/local/Cellar -# - /usr/local/Homebrew - -set -eu - -function validate_checksum { - local package="$1" - local expected_checksum="$2" - - local actual_checksum - actual_checksum=$(sha256sum "$package") - if [[ $actual_checksum != "${expected_checksum} ${package}" ]] - then - >&2 echo "ERROR: Wrong checksum for package $package." - >&2 echo "Actual: $actual_checksum" - >&2 echo "Expected: $expected_checksum" - exit 1 - fi -} - -if [ ! -f /usr/local/lib/libz3.a ] # if this file does not exists (cache was not restored), rebuild dependencies -then - brew update - brew upgrade - brew install boost - brew install cmake - brew install wget - brew install coreutils - brew install diffutils - ./scripts/install_obsolete_jsoncpp_1_7_4.sh - - # z3 - z3_version="4.12.1" - z3_dir="z3-${z3_version}-x64-osx-10.16" - z3_package="${z3_dir}.zip" - wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_package}" - validate_checksum "$z3_package" 7601f844de6d906235140d0f76cca58be7ac716f3e2c29c35845aa24b24f73b9 - unzip "$z3_package" - rm "$z3_package" - cp "${z3_dir}/bin/libz3.a" /usr/local/lib - cp "${z3_dir}/bin/z3" /usr/local/bin - cp "${z3_dir}/include/"* /usr/local/include - rm -r "$z3_dir" - - # evmone - evmone_version="0.10.0" - evmone_package="evmone-${evmone_version}-darwin-x86_64.tar.gz" - wget "https://github.com/ethereum/evmone/releases/download/v${evmone_version}/${evmone_package}" - validate_checksum "$evmone_package" 1b7773779287d7908baca6b8d556a98800cbd7d6e5c910b55fa507642bc0a15c - tar xzpf "$evmone_package" -C /usr/local - rm "$evmone_package" - -fi diff --git a/.circleci/parallel_bytecode_report.sh b/.circleci/parallel_bytecode_report.sh deleted file mode 100755 index 4a19015ce62f..000000000000 --- a/.circleci/parallel_bytecode_report.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -#------------------------------------------------------------------------------ -# Splits all test source code into multiple files, generates bytecode and metadata -# for each file and combines it into a single report.txt file. -# -# The script is meant to be executed in CI on all supported platforms. All generated -# reports must be identical for a given compiler version. -# -# ------------------------------------------------------------------------------ -# This file is part of solidity. -# -# solidity is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# solidity is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with solidity. If not, see -# -# (c) 2023 solidity contributors. -#------------------------------------------------------------------------------ - -(( $# == 4 )) || { >&2 echo "Wrong number of arguments."; exit 1; } -label="$1" -binary_type="$2" -binary_path="$3" # This path must be absolute -preset="$4" - -[[ $binary_type == native || $binary_type == solcjs ]] || { >&2 echo "Invalid binary type: ${binary_type}"; exit 1; } - -# NOTE: Locale affects the order of the globbed files. -export LC_ALL=C - -mkdir test-cases/ -cd test-cases/ - -echo "Preparing input files" -python3 ../scripts/isolate_tests.py ../test/ - -# FIXME: These cases crash because of https://github.com/ethereum/solidity/issues/13583 -rm ./*_bytecode_too_large_*.sol ./*_combined_too_large_*.sol - -if [[ $binary_type == native ]]; then - interface=$(echo -e "standard-json\ncli" | circleci tests split) - echo "Selected interface: ${interface}" - - echo "Generating bytecode reports" - python3 ../scripts/bytecodecompare/prepare_report.py \ - "$binary_path" \ - --interface "$interface" \ - --preset "$preset" \ - --report-file "../bytecode-report-${label}-${interface}-${preset}.txt" -else - echo "Installing solc-js" - git clone --depth 1 https://github.com/ethereum/solc-js.git solc-js - cp "$binary_path" solc-js/soljson.js - - cd solc-js/ - npm install - npm run build - - cd .. - npm install ./solc-js/dist - - cp ../scripts/bytecodecompare/prepare_report.js . - - echo "Generating bytecode reports" - # shellcheck disable=SC2035 - ./prepare_report.js \ - --preset "$preset" \ - *.sol > "../bytecode-report-${label}-${preset}.txt" -fi diff --git a/.circleci/parallel_cli_tests.py b/.circleci/parallel_cli_tests.py deleted file mode 100755 index 45cc83aec318..000000000000 --- a/.circleci/parallel_cli_tests.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 - -import subprocess -import sys - -# Slowest CLI tests, whose execution takes time on the order of minutes (as of June 2023). -# When adding/removing items here, remember to update `parallelism` value in jobs that run this script. -# TODO: We should switch to time-based splitting but that requires JUnit XML report support in cmdlineTests.sh. -tests_to_run_in_parallel = [ - '~ast_import_export', # ~7 min - '~evmasm_import_export', # ~5 min - '~ast_export_with_stop_after_parsing', # ~4 min - '~soljson_via_fuzzer', # ~3 min - '~via_ir_equivalence', # ~1 min - '~compilation_tests', # ~1 min - '~documentation_examples', # ~1 min - '*', # This item represents all the remaining tests -] - -# Ask CircleCI to select a subset of tests for this parallel execution. -# If `parallelism` in CI config is set correctly, we should get just one but we can handle any split. -selected_tests = subprocess.check_output( - ['circleci', 'tests', 'split'], - input='\n'.join(tests_to_run_in_parallel), - encoding='ascii', -).strip().split('\n') -selected_tests = set(selected_tests) - {''} -excluded_tests = set(tests_to_run_in_parallel) - selected_tests -assert selected_tests.issubset(set(tests_to_run_in_parallel)) - -if len(selected_tests) == 0: - print("No tests to run.") - sys.exit(0) - -if '*' in selected_tests: - filters = [arg for test_name in excluded_tests for arg in ['--exclude', test_name]] -else: - filters = list(selected_tests) - -subprocess.run( - ['test/cmdlineTests.sh'] + filters, - stdin=sys.stdin, - stdout=sys.stdout, - stderr=sys.stderr, - check=True, -) diff --git a/.circleci/soltest.ps1 b/.circleci/soltest.ps1 deleted file mode 100755 index 3c800903be11..000000000000 --- a/.circleci/soltest.ps1 +++ /dev/null @@ -1,12 +0,0 @@ -$ErrorActionPreference = "Stop" - -cd "$PSScriptRoot\.." - -.\build\solc\Release\solc.exe --version -if ( -not $? ) { throw "Cannot execute solc --version." } - -mkdir test_results -.\build\test\Release\soltest.exe --color_output=no --show_progress=yes --logger=JUNIT,error,test_results/result.xml --logger=HRF,error,stdout -- --no-smt -if ( -not $? ) { throw "Unoptimized soltest run failed." } -.\build\test\Release\soltest.exe --color_output=no --show_progress=yes --logger=JUNIT,error,test_results/result_opt.xml --logger=HRF,error,stdout -- --optimize --no-smt -if ( -not $? ) { throw "Optimized soltest run failed." } diff --git a/.circleci/soltest.sh b/.circleci/soltest.sh deleted file mode 100755 index 488201bae3ff..000000000000 --- a/.circleci/soltest.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env bash -#------------------------------------------------------------------------------ -# Bash script to execute the Solidity tests by CircleCI. -# -# The documentation for solidity is hosted at: -# -# https://docs.soliditylang.org -# -# ------------------------------------------------------------------------------ -# Configuration Environment Variables: -# -# EVM=version_string Specifies EVM version to compile for (such as homestead, etc) -# OPTIMIZE=1 Enables backend optimizer -# ABI_ENCODER_V1=1 Forcibly enables ABI coder version 1 -# SOLTEST_FLAGS= Appends to default SOLTEST_ARGS -# -# ------------------------------------------------------------------------------ -# This file is part of solidity. -# -# solidity is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# solidity is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with solidity. If not, see -# -# (c) 2016-2019 solidity contributors. -# ------------------------------------------------------------------------------ -set -e - -OPTIMIZE=${OPTIMIZE:-"0"} -EVM=${EVM:-"invalid"} -CPUs=${CPUs:-3} -REPODIR="$(realpath "$(dirname "$0")/..")" - -IFS=" " read -r -a BOOST_TEST_ARGS <<< "$BOOST_TEST_ARGS" -IFS=" " read -r -a SOLTEST_FLAGS <<< "$SOLTEST_FLAGS" - -# shellcheck source=scripts/common.sh -source "${REPODIR}/scripts/common.sh" -# Test result output directory (CircleCI is reading test results from here) -mkdir -p test_results - -# in case we run with ASAN enabled, we must increase stack size. -ulimit -s 16384 - -get_logfile_basename() { - local run="$1" - local filename="${EVM}" - test "${OPTIMIZE}" = "1" && filename="${filename}_opt" - test "${ABI_ENCODER_V1}" = "1" && filename="${filename}_abiv1" - filename="${filename}_${run}" - - echo -ne "${filename}" -} - -[ -z "$CIRCLE_NODE_TOTAL" ] || [ "$CIRCLE_NODE_TOTAL" = 0 ] && CIRCLE_NODE_TOTAL=1 -[ -z "$CIRCLE_NODE_INDEX" ] && CIRCLE_NODE_INDEX=0 -[ -z "$INDEX_SHIFT" ] && INDEX_SHIFT=0 - -# Multiply by a prime number to get better spread, just in case -# long-running test cases are next to each other. -CIRCLE_NODE_INDEX=$(((CIRCLE_NODE_INDEX + 23 * INDEX_SHIFT) % CIRCLE_NODE_TOTAL)) - -PIDs=() -for run in $(seq 0 $((CPUs - 1))) -do - BOOST_TEST_ARGS_RUN=( - "--color_output=no" - "--show_progress=yes" - "--logger=JUNIT,error,test_results/$(get_logfile_basename "$((CPUs * CIRCLE_NODE_INDEX + run))").xml" - "--logger=HRF,error,stdout" - "${BOOST_TEST_ARGS[@]}" - ) - SOLTEST_ARGS=("--evm-version=$EVM" "${SOLTEST_FLAGS[@]}") - - test "${OPTIMIZE}" = "1" && SOLTEST_ARGS+=(--optimize) - test "${ABI_ENCODER_V1}" = "1" && SOLTEST_ARGS+=(--abiencoderv1) - - BATCH_ARGS=("--batches" "$((CPUs * CIRCLE_NODE_TOTAL))" "--selected-batch" "$((CPUs * CIRCLE_NODE_INDEX + run))") - - echo "Running ${REPODIR}/build/test/soltest ${BOOST_TEST_ARGS_RUN[*]} -- ${SOLTEST_ARGS[*]}" - - "${REPODIR}/build/test/soltest" -l test_suite "${BOOST_TEST_ARGS_RUN[@]}" -- "${SOLTEST_ARGS[@]}" "${BATCH_ARGS[@]}" & - PIDs+=($!) -done - -# wait for individual processes to get their exit status -for pid in "${PIDs[@]}" -do - wait "$pid" -done diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh deleted file mode 100755 index 4be427f192d2..000000000000 --- a/.circleci/soltest_all.sh +++ /dev/null @@ -1,68 +0,0 @@ -#! /bin/bash -#------------------------------------------------------------------------------ -# Bash script to execute the Solidity tests by CircleCI. -# -# The documentation for solidity is hosted at: -# -# https://docs.soliditylang.org -# -# ------------------------------------------------------------------------------ -# This file is part of solidity. -# -# solidity is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# solidity is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with solidity. If not, see -# -# (c) 2016-2019 solidity contributors. -# ------------------------------------------------------------------------------ -set -e - -REPODIR="$(realpath "$(dirname "$0")"/..)" - -# shellcheck source=scripts/common.sh -source "${REPODIR}/scripts/common.sh" - -EVM_VALUES=(homestead byzantium constantinople petersburg istanbul berlin london paris shanghai) -DEFAULT_EVM=shanghai -[[ " ${EVM_VALUES[*]} " =~ $DEFAULT_EVM ]] -OPTIMIZE_VALUES=(0 1) - -# Run for ABI encoder v1, without SMTChecker tests. -EVM="${DEFAULT_EVM}" \ -OPTIMIZE=1 \ -ABI_ENCODER_V1=1 \ -BOOST_TEST_ARGS="-t !smtCheckerTests" \ -"${REPODIR}/.circleci/soltest.sh" - -# We shift the batch index so that long-running tests -# do not always run in the same executor for all EVM versions -INDEX_SHIFT=0 -for OPTIMIZE in "${OPTIMIZE_VALUES[@]}" -do - for EVM in "${EVM_VALUES[@]}" - do - ENFORCE_GAS_ARGS="" - [ "${EVM}" = "${DEFAULT_EVM}" ] && ENFORCE_GAS_ARGS="--enforce-gas-cost" - # Run SMTChecker tests only when OPTIMIZE == 0 - DISABLE_SMTCHECKER="" - [ "${OPTIMIZE}" != "0" ] && DISABLE_SMTCHECKER="-t !smtCheckerTests" - - EVM="$EVM" \ - OPTIMIZE="$OPTIMIZE" \ - SOLTEST_FLAGS="$SOLTEST_FLAGS $ENFORCE_GAS_ARGS" \ - BOOST_TEST_ARGS="-t !@nooptions $DISABLE_SMTCHECKER" \ - INDEX_SHIFT="$INDEX_SHIFT" \ - "${REPODIR}/.circleci/soltest.sh" - - INDEX_SHIFT=$((INDEX_SHIFT + 1)) - done -done diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 95b0feba1eb4..000000000000 --- a/.clang-format +++ /dev/null @@ -1,41 +0,0 @@ -# Formatting approximately used in Solidity's C++ -# -# See https://clang.llvm.org/docs/ClangFormatStyleOptions.html -# For an online formatter to test settings, see -# https://zed0.co.uk/clang-format-configurator/ -# Note that clang-format cannot express the style that closing parentheses -# behave similar to closing curly braces in a multi-line setting in that -# they have to be on a line of their own at the same indentation level -# as the opening part (aka "dangling parenthesis", see https://reviews.llvm.org/D33029). - -Language: Cpp -BasedOnStyle: LLVM -AccessModifierOffset: -4 -AlignAfterOpenBracket: AlwaysBreak -AlignEscapedNewlines: Left -AlwaysBreakAfterReturnType: None -AlwaysBreakTemplateDeclarations: Yes -BinPackArguments: false -BinPackParameters: false -BreakBeforeBinaryOperators: All -BreakBeforeBraces: Allman -ColumnLimit: 120 -ContinuationIndentWidth: 4 -FixNamespaceComments: false -IndentWidth: 4 -KeepEmptyLinesAtTheStartOfBlocks: false -MaxEmptyLinesToKeep: 2 -PenaltyBreakBeforeFirstCallParameter: 2000 -PointerAlignment: Left -SpaceAfterCStyleCast: true -SpaceAfterTemplateKeyword: false -SpaceBeforeCtorInitializerColon: false -SpaceBeforeInheritanceColon: false -SpaceBeforeParens: ControlStatements -SpaceBeforeRangeBasedForLoopColon: false -TabWidth: 4 -UseTab: Always - -# Local Variables: -# mode: yaml -# End: diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index ab452ecf2823..000000000000 --- a/.dockerignore +++ /dev/null @@ -1,6 +0,0 @@ -# out-of-tree builds usually go here. This helps improving performance of uploading -# the build context to the docker image build server -/build - -# in-tree builds -/deps diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 0bb3fce2eceb..000000000000 --- a/.editorconfig +++ /dev/null @@ -1,23 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - -[*.{cpp,h}] -indent_style = tab -indent_size = 4 - -[*.{py,rst,sh,yml}] -indent_style = space -indent_size = 4 - -[*.{sol,yul}] -indent_style = space -indent_size = 4 - -[*.{txt,cmake,json}] -indent_style = tab -indent_size = 4 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index d50c44566a89..000000000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -/docs/style-guide.rst @fulldecent diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 30c09039ef79..000000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -name: Bug Report -about: Problems, deficiencies, inaccuracies or crashes discovered on Solidity. -title: '' -labels: 'bug :bug:' -assignees: '' - ---- - - - -## Description - - - -## Environment - -- Compiler version: -- Target EVM version (as per compiler settings): -- Framework/IDE (e.g. Truffle or Remix): -- EVM execution environment / backend / blockchain client: -- Operating system: - -## Steps to Reproduce - - diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 69f42abb0fe0..000000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,5 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: Initiate a language design or feedback discussion - url: https://forum.soliditylang.org - about: Open a thread on the Solidity forum. diff --git a/.github/ISSUE_TEMPLATE/documentation_issue.md b/.github/ISSUE_TEMPLATE/documentation_issue.md deleted file mode 100644 index 91082a9aaf6b..000000000000 --- a/.github/ISSUE_TEMPLATE/documentation_issue.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Documentation Issue -about: Corrections, improvements or requests for new content on Solidity's documentation. -title: '' -labels: 'documentation :book:' -assignees: '' - ---- - -## Page - - - -## Abstract - - - -## Pull request - - diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 7ec729b1c7a3..000000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -name: Feature Request -about: Ideas, comments or messages asking for a particular functionality to be added - to Solidity. -title: '' -labels: feature -assignees: '' - ---- - - - -## Abstract - - - -## Motivation - - - -## Specification - - - -## Backwards Compatibility - - diff --git a/.github/workflows/buildpack-deps.yml b/.github/workflows/buildpack-deps.yml deleted file mode 100644 index 6a261bd2eb9c..000000000000 --- a/.github/workflows/buildpack-deps.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: buildpack-deps - -on: - pull_request: - branches: [ develop ] - paths: - - 'scripts/docker/buildpack-deps/Dockerfile.emscripten' - - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz' - - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2004' - - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang' - - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204' - -jobs: - buildpack-deps: - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - DOCKER_REPOSITORY: solbuildpackpusher/solidity-buildpack-deps - IMAGE_NAME: buildpack-deps - - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2204.clang, ubuntu2204] - - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Upgrade ${{ env.IMAGE_NAME }}-${{ matrix.image_variant }} - run: | - echo ${DOCKERHUB_TOKEN} | docker login -u solbuildpackpusher --password-stdin - scripts/ci/docker_upgrade.sh ${{ env.IMAGE_NAME }} ${{ matrix.image_variant }} ${{ env.DOCKER_REPOSITORY }} - docker logout - - - name: comment PR - if: "env.DOCKER_IMAGE" - # NOTE: Can't update to v1.3.1 due to an error: `/entrypoint.sh:5:in 'require_relative': cannot load such file -- /lib/github (LoadError)` - uses: unsplash/comment-on-pr@ffe8f97ccc63ce12c3c23c6885b169db67958d3b #v1.3.0 - with: - msg: "`${{ env.DOCKER_IMAGE }} ${{ env.DOCKER_REPO_DIGEST }}`." - check_for_duplicate_msg: false - diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index d982c43f2b59..000000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: Check stale issues and pull requests - -on: - workflow_dispatch: - schedule: - - cron: '0 12 * * *' - -permissions: - issues: write - pull-requests: write - -env: - BEFORE_ISSUE_STALE: 90 - BEFORE_ISSUE_CLOSE: 7 - BEFORE_PR_STALE: 14 - BEFORE_PR_CLOSE: 7 - -jobs: - stale: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v6 - with: - debug-only: false - days-before-issue-stale: ${{ env.BEFORE_ISSUE_STALE }} - days-before-issue-close: ${{ env.BEFORE_ISSUE_CLOSE }} - stale-issue-message: | - This issue has been marked as stale due to inactivity for the last ${{ env.BEFORE_ISSUE_STALE }} days. - It will be automatically closed in ${{ env.BEFORE_ISSUE_CLOSE }} days. - close-issue-message: | - Hi everyone! This issue has been automatically closed due to inactivity. - If you think this issue is still relevant in the latest Solidity version and you have something to [contribute](https://docs.soliditylang.org/en/latest/contributing.html), feel free to reopen. - However, unless the issue is a concrete proposal that can be implemented, we recommend starting a language discussion on the [forum](https://forum.soliditylang.org) instead. - ascending: true - stale-issue-label: stale - close-issue-label: 'closed due inactivity' - exempt-issue-labels: 'bug :bug:,epic,roadmap,selected for development,must have,must have eventually,smt' - stale-pr-message: | - This pull request is stale because it has been open for ${{ env.BEFORE_PR_STALE }} days with no activity. - It will be closed in ${{ env.BEFORE_PR_CLOSE }} days unless the `stale` label is removed. - close-pr-message: | - This pull request was closed due to a lack of activity for ${{ env.BEFORE_PR_CLOSE }} days after it was stale. - stale-pr-label: stale - close-pr-label: closed-due-inactivity - days-before-pr-stale: ${{ env.BEFORE_PR_STALE }} - days-before-pr-close: ${{ env.BEFORE_PR_CLOSE }} - exempt-pr-labels: 'external contribution :star:,roadmap,epic' - exempt-draft-pr: false - exempt-all-milestones: true - remove-stale-when-updated: true - operations-per-run: 256 diff --git a/.github/workflows/welcome-external-pr.yml b/.github/workflows/welcome-external-pr.yml deleted file mode 100644 index ac8d1362eac3..000000000000 --- a/.github/workflows/welcome-external-pr.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: External contributor greeter - -on: - pull_request_target: - types: - - opened - -env: - DRY_RUN: false - -jobs: - comment-external-pr: - runs-on: ubuntu-latest - steps: - # Note: this step requires that the INTERNAL_CONTRIBUTORS environment variable - # is already defined in the repository with the current json list of internal contributors. - - name: Comment on external contribution PR - if: "!contains(fromJSON(vars.INTERNAL_CONTRIBUTORS), github.event.pull_request.user.login)" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR: ${{ github.event.pull_request.html_url }} - run: | - echo "Commenting in a newly submitted or reopened external PR: $PR" - if [[ $DRY_RUN == 'false' ]]; then - gh pr edit "$PR" --add-label "external contribution :star:" - comment_body=( - "Thank you for your contribution to the Solidity compiler! A team member will follow up shortly." - "\n\n" - "If you haven't read our [contributing guidelines](https://docs.soliditylang.org/en/latest/contributing.html) and our " - "[review checklist](https://github.com/ethereum/solidity/blob/develop/ReviewChecklist.md) before, " - "please do it now, this makes the reviewing process and accepting your contribution smoother." - "\n\n" - "If you have any questions or need our help, feel free to post them in the PR or talk to us directly on the " - "[#solidity-dev](https://matrix.to/#/#ethereum_solidity-dev:gitter.im) channel on Matrix." - ) - gh pr comment $PR --body "$(IFS='' ; echo -e "${comment_body[*]}")" - fi diff --git a/.gitignore b/.gitignore index 8ca5f86e7e43..9322b0c81564 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,11 @@ -/commit_hash.txt -/prerelease.txt - -# Auth config for ppa release -/.release_ppa_auth +commit_hash.txt +prerelease.txt # Compiled Object files *.slo *.lo *.o *.obj -*.pyc -__pycache__ # Precompiled Headers *.gch @@ -21,15 +16,15 @@ __pycache__ *.dylib *.dll +# Fortran module files +*.mod + # Compiled Static libraries *.lai *.la *.a *.lib -# ignore git mergetool backup files -*.orig - # Executables *.exe *.out @@ -38,10 +33,14 @@ __pycache__ # Build directory /build* emscripten_build/ -/docs/_build -/docs/_static/robots.txt -/deps -/reports +docs/_build +docs/_static/robots.txt +__pycache__ +docs/utils/*.pyc +/deps/downloads/ +deps/install +deps/cache +cmake-build-*/ # vim stuff [._]*.sw[a-p] @@ -51,15 +50,14 @@ emscripten_build/ *~ # IDE files -/.idea/ -/.vscode/ -/browse.VC.db -/CMakeLists.txt.user +.idea +.vscode +browse.VC.db +CMakeLists.txt.user /CMakeSettings.json /.vs /.cproject /.project -# OS specific local files -.DS_Store -Thumbs.db +# place to put local temporary files +tmp diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000000..3cce948f67db --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "restructuredtext.confPath": "" +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 73e7930b7222..18af34d26bf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ include(EthPolicy) eth_policy() # project name and version should be set after cmake_policy CMP0048 -set(PROJECT_VERSION "0.8.22") +set(PROJECT_VERSION "0.8.25") # OSX target needed in order to support std::visit set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14") project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 4c75649ae8a0..000000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,74 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at solidity@ethereum.org. -To report an issue involving the Solidity team please email José Pedro Cabrita at zepedro@ethereum.org. -All complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html - -[homepage]: https://www.contributor-covenant.org diff --git a/CODING_STYLE.md b/CODING_STYLE.md deleted file mode 100644 index 5b9129fbd07b..000000000000 --- a/CODING_STYLE.md +++ /dev/null @@ -1,243 +0,0 @@ -## 0. Formatting - -**GOLDEN RULE**: Follow the style of the existing code when you make changes. - -1. Use tabs for leading indentation: - - tab stops are every 4 characters (only relevant for line length). - - one indentation level -> exactly one byte (i.e. a tab character) in the source file. -2. Line widths: - - Lines should be at most 99 characters wide to make diff views readable and reduce merge conflicts. - - Lines of comments should be formatted according to ease of viewing, but simplicity is to be preferred over beauty. -3. Single-statement blocks should not have braces, unless required for clarity. -4. Never place condition bodies on same line as condition. -5. Space between keyword and opening parenthesis, but not following opening parenthesis or before final parenthesis. -6. No spaces for unary operators, `->` or `.`. -7. No space before `:` but one after it, except in the ternary operator: one on both sides. -8. Add spaces around all other operators. -9. Braces, when used, always have their own lines and are at same indentation level as "parent" scope. -10. If lines are broken, a list of elements enclosed with parentheses (of any kind) and separated by a separator (of any kind) are formatted such that there is exactly one element per line, followed by the separator, the opening parenthesis is on the first line, followed by a line break and the closing parenthesis is on a line of its own unindented). See example below. - -Yes: -```cpp -if (a == b[i]) - printf("Hello\n"); // NOTE spaces used instead of tab here for clarity - first byte should be '\t'. -foo->bar( - someLongVariableName, - anotherLongVariableName, - anotherLongVariableName, - anotherLongVariableName, - anotherLongVariableName -); -cout << - "some very long string that contains completely irrelevant " << - "text that talks about this and that and contains the words " << - "\"lorem\" and \"ipsum\"" << - endl; -``` - -No: -```cpp -if( a==b[ i ] ) { printf ("Hello\n"); } -foo->bar(someLongVariableName, - anotherLongVariableName, - anotherLongVariableName, - anotherLongVariableName, - anotherLongVariableName); -cout << "some very long string that contains completely irrelevant text that talks about this and that and contains the words \"lorem\" and \"ipsum\"" << endl; -``` - -To set indentation and tab width settings uniformly, the repository contains an [EditorConfig](https://editorconfig.org/) [`.editorconfig`](https://github.com/ethereum/solidity/blob/develop/.editorconfig) file, which describes some of the styles used and which is recognized by many IDE's and editors. - -## 1. Namespaces - -1. No `using namespace` declarations in header files. -2. `using namespace solidity;` and other project local namespaces is fine in cpp files, and generally encouraged. -3. Avoid `using namespace` at file level for third party libraries, such as boost, ranges, etc. -4. All symbols should be declared in a namespace except for final applications. -5. Use anonymous namespaces for helpers whose scope is a cpp file only. -6. Preprocessor symbols should be prefixed with the namespace in all-caps and an underscore. - -Only in the header: -```cpp -#include -namespace myNamespace -{ -std::tuple meanAndSigma(std::vector const& _v); -} -``` - -## 2. Preprocessor - -1. File comment is always at top, and includes: - - Copyright - - License (e.g. see COPYING) -2. Never use `#ifdef`/`#define`/`#endif` file guards. Prefer `#pragma` once as first line below file comment. -3. Prefer static constexpr variables to value macros. -4. Prefer inline constexpr functions to function macros. -5. Split complex macro on multiple lines with `\`. - -## 3. Capitalization - -**GOLDEN RULE**: Preprocessor: `ALL_CAPS`; C++: `camelCase`. - -1. Use camelCase for splitting words in names, except where obviously extending STL/boost functionality in which case follow those naming conventions. -2. The following entities' first alpha is upper case: - - Type names - - Template parameters - - Enum members - - static const variables that form an external API. -3. All preprocessor symbols (macros, macro arguments) in full uppercase with underscore word separation. - -All other entities' first alpha is lower case. - -## 4. Variable prefixes - -1. Leading underscore "_" to parameter names: - - Exception: "o_parameterName" when it is used exclusively for output. See 6(f). - - Exception: "io_parameterName" when it is used for both input and output. See 6(f). -2. Leading "g_" to global (non-const) variables. -3. Leading "s_" to static (non-const, non-global) variables. - -## 5. Assertions - -Use `solAssert` and `solUnimplementedAssert` generously to check assumptions that span across different parts of the code base, for example before dereferencing a pointer. - -## 6. Declarations - -1. {Typename} + {qualifiers} + {name}. -2. Only one per line. -3. Associate */& with type, not variable (at ends with parser, but more readable, and safe if in conjunction with (b)). -4. Favour declarations close to use; do not habitually declare at top of scope ala C. -5. Pass non-trivial parameters as const reference, unless the data is to be copied into the function, then either pass by const reference or by value and use std::move. -6. If a function returns multiple values, use std::tuple (std::pair acceptable) or better introduce a struct type. Do not use */& arguments. -7. Use parameters of pointer type only if ``nullptr`` is a valid argument, use references otherwise. Often, ``std::optional`` is better suited than a raw pointer. -8. Never use a macro where adequate non-preprocessor C++ can be written. -9. Only use ``auto`` if the type is very long and rather irrelevant. -10. Do not pass bools: prefer enumerations instead. -11. Prefer enum class to straight enum. -12. Always initialize POD variables, even if their value is overwritten later. - -Yes: -```cpp -enum class Accuracy -{ - Approximate, - Exact -}; -struct MeanSigma -{ - float mean = 0.0f; - float standardDeviation = 1.0f; -}; -double const d = 0; -int i = 0; -int j = 0; -char* s = nullptr; -MeanAndSigma ms meanAndSigma(std::vector const& _v, Accuracy _a); -Derived* x = dynamic_cast(base); -for (auto i = x->begin(); i != x->end(); ++i) {} -``` - -No: -```cpp -const double d = 0; -int i, j; -char *s; -float meanAndSigma(std::vector _v, float* _sigma, bool _approximate); -Derived* x(dynamic_cast(base)); -for (map::iterator i = l.begin(); i != l.end(); ++l) {} -``` - -## 7. Structs & classes - -1. Structs to be used when all members public and no virtual functions: - - In this case, members should be named naturally and not prefixed with `m_`. -2. Classes to be used in all other circumstances. - -## 8. Members - -1. One member per line only. -2. Private, non-static, non-const fields prefixed with `m_`. -3. Avoid public fields, except in structs. -4. Use override, final and const as much as possible. -5. No implementations with the class declaration, except: - - template or force-inline method (though prefer implementation at bottom of header file). - - one-line implementation (in which case include it in same line as declaration). -6. For a property `foo` - - Member: `m_foo` - - Getter: `foo()` [ also: for booleans, `isFoo()` ] - - Setter: `setFoo()` - -## 9. Naming - -1. Avoid unpronounceable names. -2. Names should be shortened only if they are extremely common, but shortening should be generally avoided -3. Avoid prefixes of initials (e.g. do not use `IMyInterface`, `CMyImplementation`) -4. Find short, memorable & (at least semi-) descriptive names for commonly used classes or name-fragments: - - A dictionary and thesaurus are your friends; - - Spell correctly; - - Think carefully about the class's purpose; - - Imagine it as an isolated component to try to decontextualise it when considering its name; - - Don't be trapped into naming it (purely) in terms of its implementation. - -## 10. Type definitions - -1. Prefer `using` to `typedef`. e.g. `using ints = std::vector;` rather than typedef `std::vector ints;` -2. Generally avoid shortening a standard form that already includes all important information: - - e.g. stick to `shared_ptr` rather than shortening to `ptr`. -3. Where there are exceptions to this (due to excessive use and clear meaning), note the change prominently and use it consistently: - - e.g. `using Guard = std::lock_guard;` ///< Guard is used throughout the codebase since it is clear in meaning and used commonly. -4. In general expressions should be roughly as important/semantically meaningful as the space they occupy. -5. Avoid introducing aliases for types unless they are very complicated. Consider the number of items a brain can keep track of at the same time. - -## 11. Commenting - -1. Comments should be doxygen-compilable, using @notation rather than \notation. -2. Document the interface, not the implementation: - - Documentation should be able to remain completely unchanged, even if the method is reimplemented; - - Comment in terms of the method properties and intended alteration to class state (or what aspects of the state it reports); - - Be careful to scrutinise documentation that extends only to intended purpose and usage; - - Reject documentation that is simply an English transaction of the implementation. -3. Avoid in-code comments. Instead, try to extract blocks of functionality into functions. This often already eliminates the need for an in-code comment. - -## 12. Include Headers - -1. Includes should go in increasing order of generality (`libsolidity` -> `libevmasm` -> `libsolutil` -> `boost` -> `STL`). -2. The corresponding `.h` file should be the first include in the respective `.cpp` file. -3. Insert empty lines between blocks of include files. - -Example: -```cpp -#include - -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include - -#include -#include -``` - -See [this issue](https://stackoverflow.com/questions/614302/c-header-order/614333#614333 "C header order") for the reason: this makes it easier to find missing includes in header files. - -## 13. Recommended reading - -- Herb Sutter and Bjarne Stroustrup: - - [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md) - -- Herb Sutter and Andrei Alexandrescu: - - "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices" - -- Scott Meyers: - - "Effective C++: 55 Specific Ways to Improve Your Programs and Designs (3rd Edition)" - - "More Effective C++: 35 New Ways to Improve Your Programs and Designs" - - "Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index e071a2290dab..000000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,5 +0,0 @@ -# Contribution Guidelines - -Please see our contribution guidelines in [the Solidity documentation](https://docs.soliditylang.org/en/latest/contributing.html). - -Thank you for your help! diff --git a/Changelog.md b/Changelog.md deleted file mode 100644 index 279fbec6348f..000000000000 --- a/Changelog.md +++ /dev/null @@ -1,2664 +0,0 @@ -### 0.8.22 (unreleased) - -Language Features: - * Allow defining events at file level. - - -Compiler Features: - * Code Generator: Remove redundant overflow checks of certain ``for`` loops when the counter variable cannot overflow. - * Commandline Interface: Add ``--no-import-callback`` option that prevents the compiler from loading source files not given explicitly on the CLI or in Standard JSON input. - * Commandline Interface: Add an experimental ``--import-asm-json`` option that can import EVM assembly in the format used by ``--asm-json``. - * Commandline Interface: Use proper severity and coloring also for error messages produced outside of the compilation pipeline. - * EVM: Deprecate support for "homestead", "tangerineWhistle", "spuriousDragon" and "byzantium" EVM versions. - * Parser: Remove the experimental error recovery mode (``--error-recovery`` / ``settings.parserErrorRecovery``). - * SMTChecker: Support user-defined operators. - * Yul Optimizer: If ``PUSH0`` is supported, favor zero literals over storing zero values in variables. - * Yul Optimizer: Run the ``Rematerializer`` and ``UnusedPruner`` steps at the end of the default clean-up sequence. - - -Bugfixes: - * AST: Fix wrong initial ID for Yul nodes in the AST. - * Code Generator: Fix output from via-IR code generator being dependent on which files were discovered by import callback. In some cases, a different AST ID assignment would alter the order of functions in internal dispatch, resulting in superficially different but semantically equivalent bytecode. - * NatSpec: Fix internal error when requesting userdoc or devdoc for a contract that emits an event defined in a foreign contract or interface. - * SMTChecker: Fix encoding error that causes loops to unroll after completion. - * SMTChecker: Fix inconsistency on constant condition checks when ``while`` or ``for`` loops are unrolled before the condition check. - * Yul Optimizer: Fix replacement decisions during CSE being affected by Yul variable names generated by the compiler, resulting in different (but equivalent) bytecode in some situations. - - -### 0.8.21 (2023-07-19) - -Important Bugfixes: - * Code Generator: Always generate code for the expression in ``.selector`` in the legacy code generation pipeline. - * Yul Optimizer: Fix ``FullInliner`` step (``i``) not preserving the evaluation order of arguments passed into inlined functions in code that is not in expression-split form (i.e. when using a custom optimizer sequence in which the step not preceded by ``ExpressionSplitter`` (``x``)). - - -Language Features: - * Allow qualified access to events from other contracts. - * Relax restrictions on initialization of immutable variables. Reads and writes may now happen at any point at construction time outside of functions and modifiers. Explicit initialization is no longer mandatory. - - -Compiler Features: - * Commandline Interface: Add ``--ast-compact-json`` output in assembler mode. - * Commandline Interface: Add ``--ir-ast-json`` and ``--ir-optimized-ast-json`` outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR. - * Commandline Interface: Respect ``--optimize-yul`` and ``--no-optimize-yul`` in compiler mode and accept them in assembler mode as well. ``--optimize --no-optimize-yul`` combination now allows enabling EVM assembly optimizer without enabling Yul optimizer. - * EWasm: Remove EWasm backend. - * Parser: Introduce ``pragma experimental solidity``, which will enable an experimental language mode that in particular has no stability guarantees between non-breaking releases and is not suited for production use. - * SMTChecker: Add ``--model-checker-print-query`` CLI option and ``settings.modelChecker.printQuery`` JSON option to output the SMTChecker queries in the SMTLIB2 format. This requires using ``smtlib2`` solver only. - * Standard JSON Interface: Add ``ast`` file-level output for Yul input. - * Standard JSON Interface: Add ``irAst`` and ``irOptimizedAst`` contract-level outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR. - * Yul Optimizer: Remove experimental ``ReasoningBasedSimplifier`` optimization step. - * Yul Optimizer: Stack-to-memory mover is now enabled by default whenever possible for via IR code generation and pure Yul compilation. - - -Bugfixes: - * Code Generator: Disallow complex expressions whose results are types, built-ins, modules or some unassignable functions. The legacy code generation pipeline would not actually evaluate them, discarding any side-effects they might have. - * Code Generator: Fix not entirely deterministic order of functions in unoptimized Yul output. The choice of C++ compiler in some cases would result in different (but equivalent) bytecode (especially from native binaries vs emscripten binaries). - * Commandline Interface: Fix internal error when using ``--stop-after parsing`` and requesting some of the outputs that require full analysis or compilation. - * Commandline Interface: It is no longer possible to specify both ``--optimize-yul`` and ``--no-optimize-yul`` at the same time. - * SMTChecker: Fix encoding of side-effects inside ``if`` and ``ternary conditional``statements in the BMC engine. - * SMTChecker: Fix false negative when a verification target can be violated only by trusted external call from another public function. - * SMTChecker: Fix generation of invalid SMT-LIB2 scripts in BMC engine with trusted mode for external calls when CHC engine times out. - * SMTChecker: Fix internal error caused by incorrectly classifying external function call using function pointer as a public getter. - * SMTChecker: Fix internal error caused by using external identifier to encode member access to functions that take an internal function as a parameter. - * Standard JSON Interface: Fix an incomplete AST being returned when analysis is interrupted by certain kinds of fatal errors. - * Type Checker: Disallow using certain unassignable function types in complex expressions. - * Type Checker: Function declaration types referring to different declarations are no longer convertible to each other. - * Yul Optimizer: Ensure that the assignment of memory slots for variables moved to memory does not depend on AST IDs that may depend on whether additional files are included during compilation. - * Yul Optimizer: Fix ``FullInliner`` step not ignoring code that is not in expression-split form. - * Yul Optimizer: Fix optimized IR being unnecessarily passed through the Yul optimizer again before bytecode generation. - - -AST Changes: - * AST: Add the ``experimentalSolidity`` field to the ``SourceUnit`` nodes, which indicate whether the experimental parsing mode has been enabled via ``pragma experimental solidity``. - - -### 0.8.20 (2023-05-10) - -Compiler Features: - * Assembler: Use ``push0`` for placing ``0`` on the stack for EVM versions starting from "Shanghai". This decreases the deployment and runtime costs. - * EVM: Set default EVM version to "Shanghai". - * EVM: Support for the EVM Version "Shanghai". - * NatSpec: Add support for NatSpec documentation in ``enum`` definitions. - * NatSpec: Add support for NatSpec documentation in ``struct`` definitions. - * NatSpec: Include NatSpec from events that are emitted by a contract but defined outside of it in userdoc and devdoc output. - * Optimizer: Re-implement simplified version of ``UnusedAssignEliminator`` and ``UnusedStoreEliminator``. It can correctly remove some unused assignments in deeply nested loops that were ignored by the old version. - * Parser: Unary plus is no longer recognized as a unary operator in the AST and triggers an error at the parsing stage (rather than later during the analysis). - * SMTChecker: Add CLI option ``--model-checker-bmc-loop-iterations`` and a JSON option ``settings.modelChecker.bmcLoopIterations`` that specify how many loop iterations the BMC engine should unroll. Note that false negatives are possible when unrolling loops. This is due to the possibility that bmc loop iteration setting is less than actual number of iterations needed to complete a loop. - * SMTChecker: Group all messages about unsupported language features in a single warning. The CLI option ``--model-checker-show-unsupported`` and the JSON option ``settings.modelChecker.showUnsupported`` can be enabled to show the full list. - * SMTChecker: Properties that are proved safe are now reported explicitly at the end of analysis. By default, only the number of safe properties is shown. The CLI option ``--model-checker-show-proved-safe`` and the JSON option ``settings.modelChecker.showProvedSafe`` can be enabled to show the full list of safe properties. - * Standard JSON Interface: Add experimental support for importing ASTs via Standard JSON. - * Yul EVM Code Transform: If available, use ``push0`` instead of ``codesize`` to produce an arbitrary value on stack in order to create equal stack heights between branches. - - -Bugfixes: - * ABI: Include events in the ABI that are emitted by a contract but defined outside of it. - * Immutables: Disallow initialization of immutables in try/catch statements. - * SMTChecker: Fix false positives in ternary operators that contain verification targets in its branches, directly or indirectly. - - -AST Changes: - * AST: Add the ``internalFunctionIDs`` field to the AST nodes of contracts containing IDs of functions that may be called via the internal dispatch. The field is a map from function AST IDs to internal dispatch function IDs. These IDs are always generated, but they are only used in via-IR code generation. - * AST: Add the ``usedEvents`` field to ``ContractDefinition`` which contains the AST IDs of all events emitted by the contract as well as all events defined and inherited by the contract. - - -### 0.8.19 (2023-02-22) - -Language Features: - * Allow defining custom operators for user-defined value types via ``using {f as +} for T global`` syntax. - - -Compiler Features: - * SMTChecker: New trusted mode that assumes that any compile-time available code is the actual used code even in external calls. This can be used via the CLI option ``--model-checker-ext-calls trusted`` or the JSON field ``settings.modelChecker.extCalls: "trusted"``. - - -Bugfixes: - * Assembler: Avoid duplicating subassembly bytecode where possible. - * Code Generator: Avoid including references to the deployed label of referenced functions if they are called right away. - * ContractLevelChecker: Properly distinguish the case of missing base constructor arguments from having an unimplemented base function. - * SMTChecker: Fix internal error caused by unhandled ``z3`` expressions that come from the solver when bitwise operators are used. - * SMTChecker: Fix internal error when using the custom NatSpec annotation to abstract free functions. - * TypeChecker: Also allow external library functions in ``using for``. - - -AST Changes: - * AST: Add ``function`` field to ``UnaryOperation`` and ``BinaryOperation`` AST nodes. ``functionList`` in ``UsingForDirective`` AST nodes will now contain ``operator`` and ``definition`` members instead of ``function`` when the list entry defines an operator. - - -### 0.8.18 (2023-02-01) - -Language Features: - * Allow named parameters in mapping types. - - -Compiler Features: - * Commandline Interface: Add ``--no-cbor-metadata`` that skips CBOR metadata from getting appended at the end of the bytecode. - * Commandline Interface: Return exit code ``2`` on uncaught exceptions. - * EVM: Deprecate ``block.difficulty`` and disallow ``difficulty()`` in inline assembly for EVM versions >= paris. The change is due to the renaming introduced by [EIP-4399](https://eips.ethereum.org/EIPS/eip-4399). - * EVM: Introduce ``block.prevrandao`` in Solidity and ``prevrandao()`` in inline assembly for EVM versions >= paris. - * EVM: Set the default EVM version to "Paris". - * EVM: Support for the EVM version "Paris". - * Language Server: Add basic document hover support. - * Natspec: Add event Natspec inheritance for devdoc. - * Optimizer: Added optimization rule ``and(shl(X, Y), shl(X, Z)) => shl(X, and(Y, Z))``. - * Parser: More detailed error messages about invalid version pragmas. - * SMTChecker: Make ``z3`` the default solver for the BMC and CHC engines instead of all solvers. - * SMTChecker: Support Eldarica as a Horn solver for the CHC engine when using the CLI option ``--model-checker-solvers eld``. The binary ``eld`` must be available in the system. - * Solidity Upgrade Tool: Remove ``solidity-upgrade`` tool. - * Standard JSON: Add a boolean field ``settings.metadata.appendCBOR`` that skips CBOR metadata from getting appended at the end of the bytecode. - * TypeChecker: Warn when using deprecated builtin ``selfdestruct``. - * Yul EVM Code Transform: Generate more optimal code for user-defined functions that always terminate a transaction. No return labels will be pushed for calls to functions that always terminate. - * Yul Optimizer: Allow replacing the previously hard-coded cleanup sequence by specifying custom steps after a colon delimiter (``:``) in the sequence string. - * Yul Optimizer: Eliminate ``keccak256`` calls if the value was already calculated by a previous call and can be reused. - - -Bugfixes: - * Parser: Disallow several ``indexed`` attributes for the same event parameter. - * Parser: Disallow usage of the ``indexed`` attribute for modifier parameters. - * SMTChecker: Fix display error for negative integers that are one more than powers of two. - * SMTChecker: Fix internal error on chain assignments using static fully specified state variables. - * SMTChecker: Fix internal error on multiple wrong SMTChecker natspec entries. - * SMTChecker: Fix internal error when a public library function is called internally. - * SMTChecker: Fix internal error when deleting struct member of function type. - * SMTChecker: Fix internal error when using user-defined types as mapping indices or struct members. - * SMTChecker: Improved readability for large integers that are powers of two or almost powers of two in error messages. - * TypeChecker: Fix bug where private library functions could be attached with ``using for`` outside of their declaration scope. - * Yul Optimizer: Hash hex and decimal literals according to their value instead of their representation, improving the detection of equivalent functions. - - -### 0.8.17 (2022-09-08) - -Important Bugfixes: - * Yul Optimizer: Prevent the incorrect removal of storage writes before calls to Yul functions that conditionally terminate the external EVM call. - - -Compiler Features: - * Code Generator: More efficient overflow checks for multiplication. - * Language Server: Analyze all files in a project by default (can be customized by setting ``'file-load-strategy'`` to ``'directly-opened-and-on-import'`` in LSP settings object). - * Yul Optimizer: Simplify the starting offset of zero-length operations to zero. - - -Bugfixes: - * Type Checker: Fix internal compiler error on tuple assignments with invalid left-hand side. - * Yul IR Code Generation: Fix internal compiler error when accessing the ``.slot`` member of a mapping through a storage reference in inline assembly. - - -Build System: - * Allow disabling pedantic warnings and do not treat warnings as errors during compiler build when ``-DPEDANTIC=OFF`` flag is passed to CMake. - * Update emscripten to version 3.1.19. - - -### 0.8.16 (2022-08-08) - -Important Bugfixes: - * Code Generation: Fix data corruption that affected ABI-encoding of calldata values represented by tuples: structs at any nesting level; argument lists of external functions, events and errors; return value lists of external functions. The 32 leading bytes of the first dynamically-encoded value in the tuple would get zeroed when the last component contained a statically-encoded array. - - -Compiler Features: - * Code Generator: More efficient code for checked addition and subtraction. - * TypeChecker: Support using library constants in initializers of other constants. - * Yul IR Code Generation: Improved copy routines for arrays with packed storage layout. - * Yul Optimizer: Add rule to convert ``mod(add(X, Y), A)`` into ``addmod(X, Y, A)``, if ``A`` is a power of two. - * Yul Optimizer: Add rule to convert ``mod(mul(X, Y), A)`` into ``mulmod(X, Y, A)``, if ``A`` is a power of two. - - -Bugfixes: - * Commandline Interface: Disallow the following options outside of the compiler mode: ``--via-ir``,``--metadata-literal``, ``--metadata-hash``, ``--model-checker-show-unproved``, ``--model-checker-div-mod-no-slacks``, ``--model-checker-engine``, ``--model-checker-invariants``, ``--model-checker-solvers``, ``--model-checker-timeout``, ``--model-checker-contracts``, ``--model-checker-targets``. - * Type Checker: Fix compiler crash on tuple assignments involving certain patterns with unary tuples on the left-hand side. - * Type Checker: Fix compiler crash when ``abi.encodeCall`` received a tuple expression instead of an inline tuple. - * Type Checker: Fix null dereference in ``abi.encodeCall`` type checking of free function. - - -### 0.8.15 (2022-06-15) - -Important Bugfixes: - * Code Generation: Avoid writing dirty bytes to storage when copying ``bytes`` arrays. - * Yul Optimizer: Keep all memory side-effects of inline assembly blocks. - - -Language Features: - * Add `E.selector` for a non-anonymous event `E` to access the 32-byte selector topic. - - -Compiler Features: - * Language Server: Add rudimentary support for semantic highlighting. - * Language Server: Adds support for configuring ``include-paths`` JSON settings object that can be passed during LSP configuration stage. - * Language Server: Always add ``{project_root}/node_modules`` to include search paths. - * Type Checker: Warn about assignments involving multiple pushes to storage ``bytes`` that may invalidate references. - * Yul Optimizer: Improve inlining heuristics for via IR code generation and pure Yul compilation. - -Bugfixes: - * ABI Encoder: When encoding an empty string coming from storage do not add a superfluous empty slot for data. - * Common Subexpression Eliminator: Process assembly items in chunks with maximum size of 2000. It helps to avoid extremely time-consuming searches during code optimization. - * DocString Parser: Fix ICE caused by an immutable struct with mapping. - * Yul IR Code Generation: More robust cleanup in corner cases during memory to storage copies. - * Yul Optimizer: Do not remove ``returndatacopy`` in cases in which it might perform out-of-bounds reads that unconditionally revert as out-of-gas. Previously, any ``returndatacopy`` that wrote to memory that was never read from was removed without accounting for the out-of-bounds condition. - - -### 0.8.14 (2022-05-17) - -Important Bugfixes: - * ABI Encoder: When ABI-encoding values from calldata that contain nested arrays, correctly validate the nested array length against ``calldatasize()`` in all cases. - * Override Checker: Allow changing data location for parameters only when overriding external functions. - - -Compiler Features: - * Assembly-Json Exporter: Include source list in `sourceList` field. - * Commandline Interface: Option ``--pretty-json`` works also with the following options: ``--abi``, ``--asm-json``, ``--ast-compact-json``, ``--devdoc``, ``--storage-layout``, ``--userdoc``. - * Language Server: Allow full filesystem access to language server. - * Peephole Optimizer: Remove operations without side effects before simple terminations. - * SMTChecker: Support ``abi.encodeCall`` taking into account the called selector. - - -Bugfixes: - * Assembly-Json Exporter: Fix assembly json export to store jump types of operations in `jumpType` field instead of `value`. - * SMTChecker: Fix ABI compatibility with z3 >=4.8.16. - * SMTChecker: Fix bug when z3 is selected but not available at runtime. - * Type Checker: Properly check restrictions of ``using ... global`` in conjunction with libraries. - * TypeChecker: Convert parameters of function type to how they would be called for ``abi.encodeCall``. - - -### 0.8.13 (2022-03-16) - -Important Bugfixes: - * Code Generator: Correctly encode literals used in ``abi.encodeCall`` in place of fixed bytes arguments. - - -Language Features: - * General: Allow annotating inline assembly as memory-safe to allow optimizations and stack limit evasion that rely on respecting Solidity's memory model. - * General: ``using M for Type;`` is allowed at file level and ``M`` can now also be a brace-enclosed list of free functions or library functions. - * General: ``using ... for T global;`` is allowed at file level where the user-defined type ``T`` has been defined, resulting in the effect of the statement being available everywhere ``T`` is available. - - -Compiler Features: - * Commandline Interface: Allow the use of ``--via-ir`` in place of ``--experimental-via-ir``. - * Compilation via Yul IR is no longer marked as experimental. - * JSON-AST: Added selector field for errors and events. - * Language Server: Implements goto-definition. - * Peephole Optimizer: Optimize comparisons in front of conditional jumps and conditional jumps across a single unconditional jump. - * Yul EVM Code Transform: Avoid unnecessary ``pop``s on terminating control flow. - * Yul IR Code Generation: When the result of an external call is statically-sized, ignore any returndata past the size expected by the compiler. - * Yul Optimizer: Remove ``sstore`` and ``mstore`` operations that are never read from. - - -Bugfixes: - * General: Fix internal error for locales with unusual capitalization rules. Locale set in the environment is now completely ignored. - * Type Checker: Fix incorrect type checker errors when importing overloaded functions. - * Yul IR Code Generation: Optimize embedded creation code with correct settings. This fixes potential mismatches between the constructor code of a contract compiled in isolation and the bytecode in ``type(C).creationCode``, resp. the bytecode used for ``new C(...)``. - - -### 0.8.12 (2022-02-16) - -Language Features: - * General: Add equality-comparison operators for external function types. - * General: Support ``ContractName.functionName`` for ``abi.encodeCall``, in addition to external function pointers. - - -Compiler Features: - * Commandline Interface: Event and error signatures are also returned when using ``--hashes``. - * Yul Optimizer: Remove ``mstore`` and ``sstore`` operations if the slot already contains the same value. - * Yul: Emit immutable references for pure yul code when requested. - - - -Bugfixes: - * Antlr Grammar: Allow builtin names in ``yulPath`` to support ``.address`` in function pointers. - * Code Generator: Fix internal error when accessing the members of external functions occupying more than two stack slots. - * Code Generator: Fix internal error when doing an explicit conversion from ``string calldata`` to ``bytes``. - * Control Flow Graph: Perform proper virtual lookup for modifiers for uninitialized variable and unreachable code analysis. - * General: ``string.concat`` now properly takes strings as arguments and returns ``string memory``. It was accidentally introduced as a copy of ``bytes.concat`` before. - * Immutables: Fix wrong error when the constructor of a base contract uses ``return`` and the derived contract contains immutable variables. - * Inheritance: Consider functions in all ancestors during override analysis. - * IR Generator: Add missing cleanup during the conversion of fixed bytes types to smaller fixed bytes types. - * IR Generator: Add missing cleanup for indexed event arguments of value type. - * IR Generator: Fix internal error when copying reference types in calldata and storage to struct or array members in memory. - * IR Generator: Fix IR syntax error when copying storage arrays of structs containing functions. - * Natspec: Fix internal error when overriding a struct getter with a Natspec-documented return value and the name in the struct is different. - * Type Checker: Fix internal error when a constant variable declaration forward references a struct. - * Yul EVM Code Transform: Improved stack shuffling in corner cases. - - -Solc-Js: - * The wrapper now requires at least nodejs v10. - * The code has been ported to TypeScript. - - -Build System: - * Emscripten builds store the embedded WebAssembly binary in LZ4 compressed format and transparently decompress on loading. - - -### 0.8.11 (2021-12-20) - -Language Features: - * General: New builtin function ``abi.encodeCall(functionPointer, (arg1, arg2, ...))`` that type-checks the arguments and returns the ABI-encoded function call data. - - -Compiler Features: - * Commandline Interface: Add ``--lsp`` option to get ``solc`` to act as a Language Server (LSP) communicating over stdio. - - -Bugfixes: - * Code Generator: Fix a crash when using ``@use-src`` and compiling from Yul to ewasm. - * SMTChecker: Fix internal error when an unsafe target is solved more than once and the counterexample messages are different. - * SMTChecker: Fix soundness of assigned storage/memory local pointers that were not erasing enough knowledge. - * Fix internal error when a function has a calldata struct argument with an internal type inside. - * IR Generator: Fix IR syntax error when copying storage arrays of functions. - - -### 0.8.10 (2021-11-09) - -Language Features: - * Inline Assembly: Support ``.address`` and ``.selector`` on external function pointers to access their address and function selector. - - -Compiler Features: - * Code Generator: Skip existence check for external contract if return data is expected. In this case, the ABI decoder will revert if the contract does not exist. - * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``. - * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. - * Commandline Interface: Support ``--asm``, ``--bin``, ``--ir-optimized``, ``--ewasm`` and ``--ewasm-ir`` output selection options in assembler mode. - * Commandline Interface: Use different colors when printing errors, warnings and infos. - * JSON AST: Set absolute paths of imports earlier, in the ``parsing`` stage. - * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions. - * SMTChecker: Report contract invariants and reentrancy properties. This can be enabled via the CLI option ``--model-checker-invariants`` or the Standard JSON option ``settings.modelChecker.invariants``. - * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``. - * Standard JSON: Add ``settings.debug.debugInfo`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. - * Yul EVM Code Transform: Switch to new optimized code transform when compiling via Yul with enabled optimizer. - * Yul Optimizer: Take control-flow side-effects of user-defined functions into account in various optimizer steps. - - -Bugfixes: - * Code Generator: Fix constructor source mappings for immutables. - * Commandline Interface: Disallow ``--error-recovery`` option outside of the compiler mode. - * Commandline Interface: Don't return zero exit code when writing linked files to disk fails. - * Commandline Interface: Fix extra newline character being appended to sources passed through standard input, affecting their hashes. - * Commandline Interface: Report output selection options unsupported by the selected input mode instead of ignoring them. - * Commandline Interface: When linking only accept exact matches for library names passed to the ``--libraries`` option. Library names not prefixed with a file name used to match any library with that name. - * SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``). - * SMTChecker: Fix internal error in the CHC engine when passing gas in the function options. - * TypeChecker: Fix internal error when using arrays and structs with user defined value types before declaration. - * TypeChecker: Fix internal error when using user defined value types in public library functions. - * TypeChecker: Improved error message for constant variables with (nested) mapping types. - * Yul Assembler: Fix internal error when function names are not unique. - * Yul IR Generator: Do not output empty switches/if-bodies for empty contracts. - - -Important Bugfixes in Experimental Features: - * Yul IR Generator: Changes to function return variables referenced in modifier invocation arguments were not properly forwarded if there was more than one return variable. - - -Build System: - * Pass linker-only emscripten options only when linking. - * Remove obsolete compatibility workaround for emscripten builds. - * Update emscripten to version 2.0.33. - - -### 0.8.9 (2021-09-29) - -Important Bugfixes: - * Immutables: Properly perform sign extension on signed immutables. - * User Defined Value Type: Fix storage layout of user defined value types for underlying types shorter than 32 bytes. - - -Bugfixes: - * AST: Export ``canonicalName`` for ``UserDefinedValueTypeDefinition`` and ``ContractDefinition``. - - - -### 0.8.8 (2021-09-27) - -Language Features: - * Inheritance: A function that overrides only a single interface function does not require the ``override`` specifier. - * Type System: Support ``type(E).min`` and ``type(E).max`` for enums. - * User Defined Value Type: allows creating a zero cost abstraction over a value type with stricter type requirements. - - -Compiler Features: - * Commandline Interface: Add ``--include-path`` option for specifying extra directories that may contain importable code (e.g. packaged third-party libraries). - * Commandline Interface: Do not implicitly run evm bytecode generation unless needed for the requested output. - * Commandline Interface: Normalize paths specified on the command line and make them relative for files located inside base path and/or include paths. - * Immutable variables can be read at construction time once they are initialized. - * SMTChecker: Add constraints to better correlate ``address(this).balance`` and ``msg.value``. - * SMTChecker: Support constants via modules. - * SMTChecker: Support low level ``call`` as external calls to unknown code. - * SMTChecker: Support the ``value`` option for external function calls. - * SMTChecker: Support user defined value types. - - -Bugfixes: - * Code Generator: Fix ICE on assigning to calldata structs and statically-sized calldata arrays in inline assembly. - * Code Generator: Use stable source order for ABI functions. - * Commandline Interface: Disallow the ``--experimental-via-ir`` option in Standard JSON, Assembler and Linker modes. - * Commandline Interface: Fix resolution of paths whitelisted with ``--allowed-paths`` or implicitly due to base path, remappings and files being compiled. Correctly handle paths that do not match imports exactly due to being relative, non-normalized or empty. - * Commandline Interface: Report optimizer options as invalid in Standard JSON and linker modes instead of ignoring them. - * Name Resolver: Fix that when importing an aliased symbol using ``import {AliasedName} from "a.sol"`` it would use the original name of the symbol and not the aliased one. - * Opcode Optimizer: Prevent the optimizer from running multiple times to avoid potential bytecode differences for referenced code. - * Parser: Properly check for multiple SPDX license identifiers next to each other and validate them. - * SMTChecker: Fix BMC's constraints regarding internal functions. - * SMTChecker: Fix false negative caused by ``push`` on storage array references returned by internal functions. - * SMTChecker: Fix false positive in external calls from constructors. - * SMTChecker: Fix internal error on some multi-source uses of ``abi.*``, cryptographic functions and constants. - * Standard JSON: Fix non-fatal errors in Yul mode being discarded if followed by a fatal error. - * Type Checker: Correct wrong error message in inline assembly complaining about ``.slot`` or ``.offset`` not valid when actually ``.length`` was used. - * Type Checker: Disallow modifier declarations and definitions in interfaces. - * Yul Optimizer: Fix a crash in LoadResolver, when ``keccak256`` has particular non-identifier arguments. - - - -### 0.8.7 (2021-08-11) - -Language Features: - * Introduce global ``block.basefee`` for retrieving the base fee of the current block. - * Yul: Introduce builtin ``basefee()`` for retrieving the base fee of the current block. - - -Compiler Features: - * AssemblyStack: Also run opcode-based optimizer when compiling Yul code. - * Commandline Interface: option ``--pretty-json`` works also with ``--standard--json``. - * EVM: Set the default EVM version to "London". - * SMTChecker: Do not check underflow and overflow by default. - * SMTChecker: Unproved targets are hidden by default, and the SMTChecker only states how many unproved targets there are. They can be listed using the command line option ``--model-checker-show-unproved`` or the JSON option ``settings.modelChecker.showUnproved``. - * SMTChecker: new setting to enable/disable encoding of division and modulo with slack variables. The command line option is ``--model-checker-div-mod-slacks`` and the JSON option is ``settings.modelChecker.divModWithSlacks``. - * Yul EVM Code Transform: Also pop unused argument slots for functions without return variables (under the same restrictions as for functions with return variables). - * Yul EVM Code Transform: Do not reuse stack slots that immediately become unreachable. - * Yul Optimizer: Move function arguments and return variables to memory with the experimental Stack Limit Evader (which is not enabled by default). - - -Bugfixes: - * Code Generator: Fix crash when passing an empty string literal to ``bytes.concat()``. - * Code Generator: Fix internal compiler error when calling functions bound to calldata structs and arrays. - * Code Generator: Fix internal compiler error when passing a 32-byte hex literal or a zero literal to ``bytes.concat()`` by disallowing such literals. - * Commandline Interface: Apply ``--optimizer-runs`` option in assembly / yul mode. - * Commandline Interface: Fix crash when a directory path is passed to ``--standard-json``. - * Commandline Interface: Read JSON from standard input when ``--standard-json`` gets ``-`` as a file name. - * Standard JSON: Include source location for errors in files with empty name. - * Type Checker: Fix internal error and prevent static calls to unimplemented modifiers. - * Yul Code Generator: Fix internal compiler error when using a long literal with bitwise negation. - * Yul Code Generator: Fix source location references for calls to builtin functions. - * Yul Parser: Fix source location references for ``if`` statements. - - -### 0.8.6 (2021-06-22) - -Language Features: - * Yul: Special meaning of ``".metadata"`` data object in Yul object. - - -Bugfixes: - * Control Flow Graph: Fix incorrectly reported unreachable code. - * Solc-Js: When running ``solcjs`` without the ``--optimize`` flag, use ``settings.optimizer.enabled=false`` in Standard JSON instead of omitting the key. - * Standard JSON: Omitting ``settings.optimizer.enabled`` was not equivalent to setting it to ``false``. It meant disabling also the peephole optimizer and jumpdest remover which by default still run with ``enabled=false``. - - -### 0.8.5 (2021-06-10) - -Language Features: - * Allowing conversion from ``bytes`` and ``bytes`` slices to ``bytes1``/.../``bytes32``. - * Yul: Add ``verbatim`` builtin function to inject arbitrary bytecode. - - -Compiler Features: - * Code Generator: Insert helper functions for panic codes instead of inlining unconditionally. This can reduce costs if many panics (checks) are inserted, but can increase costs where few panics are used. - * EVM: Set the default EVM version to "Berlin". - * SMTChecker: Function definitions can be annotated with the custom Natspec tag ``custom:smtchecker abstract-function-nondet`` to be abstracted by a nondeterministic value when called. - * Standard JSON / combined JSON: New artifact "functionDebugData" that contains bytecode offsets of entry points of functions and potentially more information in the future. - * Yul Optimizer: Evaluate ``keccak256(a, c)``, when the value at memory location ``a`` is known at compile time and ``c`` is a constant ``<= 32``. - - -Bugfixes: - * AST: Do not output value of Yul literal if it is not a valid UTF-8 string. - * Code Generator: Fix internal error when function arrays are assigned to storage variables and the function types can be implicitly converted but are not identical. - * Code Generator: Fix internal error when super would have to skip an unimplemented function in the virtual resolution order. - * Control Flow Graph: Assume unimplemented modifiers use a placeholder. - * Control Flow Graph: Take internal calls to functions that always revert into account for reporting unused or unassigned variables. - * Function Call Graph: Fix internal error connected with circular constant references. - * Name Resolver: Do not issue shadowing warning if the shadowing name is not directly accessible. - * Natspec: Allow multiple ``@return`` tags on public state variable documentation. - * SMTChecker: Fix internal error on conversion from ``bytes`` to ``fixed bytes``. - * SMTChecker: Fix internal error on external calls from the constructor. - * SMTChecker: Fix internal error on struct constructor with fixed bytes member initialized with string literal. - * Source Locations: Properly set source location of scoped blocks. - * Standard JSON: Properly allow the ``inliner`` setting under ``settings.optimizer.details``. - * Type Checker: Fix internal compiler error related to having mapping types in constructor parameter for abstract contracts. - * Type Checker: Fix internal compiler error when attempting to use an invalid external function type on pre-byzantium EVMs. - * Type Checker: Fix internal compiler error when overriding receive ether function with one having different parameters during inheritance. - * Type Checker: Make errors about (nested) mapping type in event or error parameter into fatal type errors. - * Type Checker: Fix internal compiler error when overriding an implemented modifier with an unimplemented one. - - -AST Changes: - * Add member `hexValue` for Yul string and hex literals. - - - -### 0.8.4 (2021-04-21) - -Important Bugfixes: - * ABI Decoder V2: For two-dimensional arrays and specially crafted data in memory, the result of ``abi.decode`` can depend on data elsewhere in memory. Calldata decoding is not affected. - - -Language Features: - * Assembly / Yul: Allow hex string literals. - * Possibility to use ``bytes.concat`` with variable number of ``bytes`` and ``bytesNN`` arguments which behaves as a restricted version of `abi.encodePacked` with a more descriptive name. - * Support custom errors via the ``error`` keyword and introduce the ``revert`` statement. - - -Compiler Features: - * Analysis: Properly detect circular references to the bytecode of other contracts across all function calls. - * Commandline Interface: Model checker option ``--model-checker-targets`` also accepts ``outOfBounds``. - * Commandline Interface: New model checker option ``--model-checker-contracts`` allows users to select which contracts should be analyzed as the most derived. - * Low-Level Inliner: Inline ordinary jumps to small blocks and jumps to small blocks that terminate. - * NatSpec: Allow ``@notice`` tag on non-public state variables and local variable declarations. The documentation will only be part of the AST, under the field ``documentation``. - * SMTChecker: Deprecate ``pragma experimental SMTChecker;`` and set default model checker engine to ``none``. - * SMTChecker: Report local variables in CHC counterexamples. - * SMTChecker: Report out of bounds index access for arrays and fixed bytes. - * SMTChecker: Support file level functions and constants. - * Standard JSON: Model checker option ``settings.modelChecker.targets`` also accepts ``outOfBounds``. - * Standard JSON: Model checker option ``settings.modelChecker.targets`` takes an array of string targets instead of string of comma separated targets. - * Standard JSON: New model checker option ``settings.modelChecker.contracts`` allows users to select which contracts should be analyzed as the most derived. - * Yul EVM Code Transform: Stack Optimization: Reuse slots of unused function arguments and defer allocating stack slots for return variables until after expression statements and assignments that do not reference them. - * Yul Optimizer: Added a new step FunctionSpecializer, that specializes a function with its literal arguments. - - -Bugfixes: - * Antlr Grammar: Fix parsing of import paths involving properly distinguishing between empty and non-empty string literals in general. - * AST Output: Fix ``kind`` field of ``ModifierInvocation`` for base constructor calls. - * Commandline interface: Fix internal error when printing AST and using ``--base-path`` or ``file://`` prefix in imports. - * Commandline interface: Fix standard input bypassing allowed path checks. - * Natspec: Fix internal error related to the `@returns` documentation for a public state variable overriding a function. - * SMTChecker: Fix false positive and false negative on ``push`` as LHS of a compound assignment. - * SMTChecker: Fix false positive in contracts that cannot be deployed. - * SMTChecker: Fix internal error on public getter returning dynamic data on older EVM versions where these are not available. - * SMTChecker: Fix internal error on try-catch with function call in catch block. - * Type Checker: Fix missing error when events are used without an emit statement. - - -AST Changes: - * New property for ``ContractDefinition`` nodes: ``usedErrors`` lists AST IDs of all errors used by the contract (even if defined outside). - - - -### 0.8.3 (2021-03-23) - -Important Bugfixes: - * Optimizer: Fix bug on incorrect caching of Keccak-256 hashes. - -Compiler Features: - * Command Line Interface: Drop experimental support for ``--machine evm15``. - * Optimizer: Try to move ``and`` with constant inside ``or`` to improve storage writes of small types. - * Optimizer: Replace multiplications and divisions with powers of two by shifts. - -Bugfixes: - * AST Import: For constructors, a public visibility is ignored during importing. - * Error Reporter: Fix handling of carriage return. - * SMTChecker: Fix internal error in BMC on resolving virtual functions inside branches. - * SMTChecker: Fix internal error on ``array.pop`` nested inside 1-tuple. - * SMTChecker: Fix internal error on ``FixedBytes`` constant initialized with string literal. - * SMTChecker: Fix internal error on array slices. - * SMTChecker: Fix internal error on calling public getter on a state variable of type array (possibly nested) of structs. - * SMTChecker: Fix internal error on pushing to ``string`` casted to ``bytes``. - * SMTChecker: Fix bug in virtual functions called by constructors. - -AST Changes: - * ModifierInvocation: Add ``kind`` field which can be ``modifierInvocation`` or ``baseConstructorSpecifier``. - - -### 0.8.2 (2021-03-02) - -Compiler Features: - * AST: Export NatSpec comments above each statement as their documentation. - * Inline Assembly: Do not warn anymore about variables or functions being shadowed by EVM opcodes. - * NatSpec: Provide source locations for parsing errors. - * Optimizer: Simple inlining when jumping to small blocks that jump again after a few side-effect free opcodes. - * NatSpec: Allow and export all tags that start with ``@custom:``. - - -Bugfixes: - * AST: Added ``referencedDeclaration`` for enum members. - * Code Generator: Fix internal error when functions are passed as parameters of other callables, when the function types can be implicitly converted, but not identical. - * Parser: Properly parse ``.address`` in some situations. - * SMTChecker: Fix missing type constraints on block and transaction variables in the deployment phase. - * Type Checker: Fix internal error when override specifier is not a contract. - * Type Checker: Make function-hash collision errors into fatal type errors. - - -AST Changes: - * Adds ``nameLocation`` to declarations to represent the exact location of the symbolic name. - * Removed the redundant function type "bytearraypush" - replaced by "arraypush". - * Support field ``documentation`` to hold NatSpec comments above each statement. - - -### 0.8.1 (2021-01-27) - -Language Features: - * Possibility to use ``catch Panic(uint code)`` to catch a panic failure from an external call. - -Compiler Features: - * Code Generator: Reduce the cost of ``
.code.length`` by using ``extcodesize`` directly. - * Command Line Interface: Allow ``=`` as separator between library name and address in ``--libraries`` commandline option. - * Command Line Interface: New option ``--model-checker-targets`` allows specifying which targets should be checked. The valid options are ``all``, ``constantCondition``, ``underflow``, ``overflow``, ``divByZero``, ``balance``, ``assert``, ``popEmptyArray``, where the default is ``all``. Multiple targets can be chosen at the same time, separated by a comma without spaces: ``underflow,overflow,assert``. - * Command Line Interface: Only accept library addresses with a prefix of ``0x`` in ``--libraries`` commandline option. - * Optimizer: Add rule to replace ``iszero(sub(x,y))`` by ``eq(x,y)``. - * Parser: Report meaningful error if parsing a version pragma failed. - * SMTChecker: Output internal and trusted external function calls in a counterexample's transaction trace. - * SMTChecker: Show ``msg.value`` in counterexample transaction traces when greater than 0. - * SMTChecker: Show contract name in counterexample function call. - * SMTChecker: Support ABI functions as uninterpreted functions. - * SMTChecker: Support try/catch statements. - * SMTChecker: Synthesize untrusted functions called externally. - * SMTChecker: Use checked arithmetic by default and support ``unchecked`` blocks. - * Standard JSON: New option ``modelCheckerSettings.targets`` allows specifying which targets should be checked. The valid options are ``all``, ``constantCondition``, ``underflow``, ``overflow``, ``divByZero``, ``balance``, ``assert``, ``popEmptyArray``, where the default is ``all``. Multiple targets can be chosen at the same time, separated by a comma without spaces: ``underflow,overflow,assert``. - -Bugfixes: - * Code Generator: Fix length check when decoding malformed error data in catch clause. - * Control Flow Graph: Fix missing error caused by read from/write to uninitialized variables. - * SMTChecker: Fix false negatives in overriding modifiers and functions. - * SMTChecker: Fix false negatives in the presence of inline assembly. - * SMTChecker: Fix false negatives when analyzing external function calls. - * SMTChecker: Fix internal error on ``block.chainid``. - * SMTChecker: Fix internal error on pushing string literal to ``bytes`` array. - * SMTChecker: Fix missing type constraints for block variables. - * Type Checker: Fix infinite loop when accessing circular constants from inline assembly. - * Type Checker: Fix internal error caused by constant structs containing mappings. - * Type System: Disallow implicit conversion from ``uintN`` to ``intM`` when ``M > N``, and by extension, explicit conversion between the same types is also disallowed. - -Build System: - * Update the soljson.js build to emscripten 2.0.12 and boost 1.75.0. - - -### 0.8.0 (2020-12-16) - -Breaking Changes: - * Code Generator: All arithmetic is checked by default. These checks can be disabled using ``unchecked { ... }``. - * Code Generator: Cause a panic if a byte array in storage is accessed whose length is encoded incorrectly. - * Code Generator: Use ``revert`` with error signature ``Panic(uint256)`` and error codes instead of invalid opcode on failing assertions. - * Command Line Interface: JSON fields `abi`, `devdoc`, `userdoc` and `storage-layout` are now sub-objects rather than strings. - * Command Line Interface: Remove the ``--old-reporter`` option. - * Command Line Interface: Remove the legacy ``--ast-json`` option. Only the ``--ast-compact-json`` option is supported now. - * General: Enable ABI coder v2 by default. - * General: Remove global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4``. - * Parser: Exponentiation is right associative. ``a**b**c`` is parsed as ``a**(b**c)``. - * Scanner: Remove support for the ``\b``, ``\f``, and ``\v`` escape sequences. - * Standard JSON: Remove the ``legacyAST`` option. - * Type Checker: Function call options can only be given once. - * Type System: Declarations with the name ``this``, ``super`` and ``_`` are disallowed, with the exception of public functions and events. - * Type System: Disallow ``msg.data`` in ``receive()`` function. - * Type System: Disallow ``type(super)``. - * Type System: Disallow enums with more than 256 members. - * Type System: Disallow explicit conversions from negative literals and literals larger than ``type(uint160).max`` to ``address`` type. - * Type System: Disallow the ``byte`` type. It was an alias to ``bytes1``. - * Type System: Explicit conversion to ``address`` type always returns a non-payable ``address`` type. In particular, ``address(u)``, ``address(b)``, ``address(c)`` and ``address(this)`` have the type ``address`` instead of ``address payable`` (Here ``u``, ``b``, and ``c`` are arbitrary variables of type ``uint160``, ``bytes20`` and contract type respectively.) - * Type System: Explicit conversions between two types are disallowed if it changes more than one of sign, width or kind at the same time. - * Type System: Explicit conversions from literals to enums are only allowed if the value fits in the enum. - * Type System: Explicit conversions from literals to integer type is as strict as implicit conversions. - * Type System: Introduce ``address(...).code`` to retrieve the code as ``bytes memory``. The size can be obtained via ``address(...).code.length``, but it will currently always include copying the code. - * Type System: Introduce ``block.chainid`` for retrieving the current chain id. - * Type System: Support ``address(...).codehash`` to retrieve the codehash of an account. - * Type System: The global variables ``tx.origin`` and ``msg.sender`` have type ``address`` instead of ``address payable``. - * Type System: Unary negation can only be used on signed integers, not on unsigned integers. - * View Pure Checker: Mark ``chainid`` as view. - * Yul: Disallow the use of reserved identifiers, such as EVM instructions, even if they are not available in the given dialect / EVM version. - * Yul: The ``assignimmutable`` builtin in the "EVM with objects" dialect takes the base offset of the code to modify as an additional argument. - -Language Features: - * Super constructors can now be called using the member notation e.g. ``M.C(123)``. - -Bugfixes: - * Type Checker: Perform proper truncating integer arithmetic when using constants in array length expressions. - -AST Changes: - * New AST Node ``IdentifierPath`` replacing in many places the ``UserDefinedTypeName``. - * New AST Node ``UncheckedBlock`` used for ``unchecked { ... }``. - -### 0.7.6 (2020-12-16) - -Language Features: - * Code generator: Support conversion from calldata slices to memory and storage arrays. - * Code generator: Support copying dynamically encoded structs from calldata to memory. - * Code generator: Support copying of nested arrays from calldata to memory. - * Scanner: Generate a parser error when comments or unicode strings contain an unbalanced or underflowing set of unicode direction override markers (LRO, RLO, LRE, RLE, PDF). - * The fallback function can now also have a single ``calldata`` argument (equaling ``msg.data``) and return ``bytes memory`` (which will not be ABI-encoded but returned as-is). - * Wasm backend: Add ``i32.select`` and ``i64.select`` instructions. - -Compiler Features: - * Build System: Optionally support dynamic loading of Z3 and use that mechanism for Linux release builds. - * Code Generator: Avoid memory allocation for default value if it is not used. - * SMTChecker: Apply constant evaluation on binary arithmetic expressions. - * SMTChecker: Create underflow and overflow verification targets for increment/decrement in the CHC engine. - * SMTChecker: Report struct values in counterexamples from CHC engine. - * SMTChecker: Support early returns in the CHC engine. - * SMTChecker: Support getters. - * SMTChecker: Support named arguments in function calls. - * SMTChecker: Support struct constructor. - * Standard-Json: Move the recently introduced ``modelCheckerSettings`` key to ``settings.modelChecker``. - * Standard-Json: Properly filter the requested output artifacts. - -Bugfixes: - * Code generator: Do not pad empty string literals with a single 32-byte zero field in the ABI coder v1. - * NatSpec: Fix segfault when inheriting return parameter documentation for modifiers with no parameters. - * SMTChecker: Fix cast string literals to byte arrays. - * SMTChecker: Fix internal compiler error when doing bitwise compound assignment with string literals. - * SMTChecker: Fix internal error when trying to generate counterexamples with old z3. - * SMTChecker: Fix segmentation fault that could occur on certain SMT-enabled sources when no SMT solver was available. - * SMTChecker: Fix internal error when ``bytes.push()`` is used as the LHS of an assignment. - * Type Checker: ``super`` is not available in libraries. - * Type Checker: Disallow leading zeroes in sized-types (e.g. ``bytes000032``), but allow them to be treated as identifiers. - * Yul Optimizer: Fix a bug in NameSimplifier where a new name created by NameSimplifier could also be created by NameDispenser. - * Yul Optimizer: Removed NameSimplifier from optimization steps available to users. - -### 0.7.5 (2020-11-18) - -Language Features: - * Ability to select the abi coder using ``pragma abicoder v1`` and ``pragma abicoder v2``. - * Inline Assembly: Use ``.offset`` and ``.length`` for calldata variables of dynamic array type to access their calldata offset and length (number of elements). Both of them can also be assigned to. - * Immutable variables with literal number values are considered pure. - -Compiler Features: - * Assembler: Perform linking in assembly mode when library addresses are provided. - * Command Line Interface: New option ``--experimental-via-ir`` allows switching compilation process to go through the Yul intermediate representation. This is highly experimental and is used for development purposes. - * Command Line Interface: New option ``--model-checker-timeout`` sets a timeout in milliseconds for each individual query performed by the SMTChecker. - * Command Line Interface: Report error if file could not be read in ``--standard-json`` mode. - * Command Line interface: Report proper error for each output file which could not be written. Previously an exception was thrown, and execution aborted, on the first error. - * SMTChecker: Add division by zero checks in the CHC engine. - * SMTChecker: More precise analysis of external calls using ``this``. - * SMTChecker: Support ``selector`` for expressions with value known at compile-time. - * Standard JSON: New option ``modelCheckerSettings.timeout`` sets a timeout in milliseconds for each individual query performed by the SMTChecker. - * Standard JSON: New option ``settings.viaIR`` allows the same switch as ``--experimental-via-ir`` on the commandline. - - -Bugfixes: - * Code generator: Fix missing creation dependency tracking for abstract contracts. - * Command Line Interface: Fix write error when the directory passed to ``--output-dir`` ends with a slash. - * Command Line Interface: Reject duplicate libraries in ``--libraries`` option instead of arbitrarily choosing one. - * NatSpec: Fix internal error when inheriting return parameter documentation but the parameter names differ between base and inherited. - * SMTChecker: Fix CHC false positives when branches are used inside modifiers. - * SMTChecker: Fix false negative in modifier applied multiple times. - * SMTChecker: Fix incorrect counterexamples reported by the CHC engine. - * SMTChecker: Fix internal error in the BMC engine when inherited contract from a different source unit has private state variables. - * SMTChecker: Fix internal error on conversion from string literal to byte. - * SMTChecker: Fix internal error when ``array.push()`` is used as the LHS of an assignment. - * SMTChecker: Fix internal error when assigning state variable via contract's name. - * SMTChecker: Fix internal error when using tuples of rational literals inside the conditional operator. - * SMTChecker: Fix lack of reporting potential violations when using only the CHC engine. - * Standard JSON: Fix library addresses specified in ``libraries`` being used for linking even if the file names do not match. - -AST Changes: - * New member ``suffix`` for inline assembly identifiers. Currently supported values are ``"slot"``, ``"offset"`` and ``"length"`` to access the components of a Solidity variable. - - -### 0.7.4 (2020-10-19) - -Important Bugfixes: - * Code Generator: Fix data corruption bug when copying empty byte arrays from memory or calldata to storage. - - -Language Features: - * Constants can be defined at file level. - - -Compiler Features: - * Command Line Interface: New option ``--model-checker-engine`` allows to choose a specific SMTChecker engine. Options are ``all`` (default), ``bmc``, ``chc`` and ``none``. - * Control Flow Graph: Print warning for non-empty functions with unnamed return parameters that are not assigned a value in all code paths. - * SMTChecker: Support ``keccak256``, ``sha256``, ``ripemd160`` and ``ecrecover`` in the CHC engine. - * SMTChecker: Support inline arrays. - * SMTChecker: Support variables ``block``, ``msg`` and ``tx`` in the CHC engine. - * Standard JSON: New option ``modelCheckerSettings.engine`` allows to choose a specific SMTChecker engine. Options are ``all`` (default), ``bmc``, ``chc`` and ``none``. - - -Bugfixes: - * Code generator: Fix ``ABIEncoderV2`` pragma from the current module affecting inherited functions and applied modifiers. - * Code generator: Fix internal compiler error when referencing members via module name but not using the reference. - * Code generator: Fix internal error on returning structs containing mappings from library function. - * Code generator: Use revert instead of invalid opcode for out-of-bounds array index access in getter. - * Contract Level Checker: Add missing check against inheriting functions with ABIEncoderV2 return types in ABIEncoderV1 contracts. - * Name Resolver: Fix shadowing/same-name warnings for later declarations. - * Type Checker: Allow arrays of contract types as type expressions and as arguments for ``abi.decode``. - * Type Checker: Disallow invalid use of library names as type name. - * Type Checker: Fix internal compiler error caused by storage parameters with nested mappings in libraries. - - -### 0.7.3 (2020-10-07) - -Important Bugfixes: - * Code Generator: Properly cleanup after copying dynamic-array to storage for packed types. - -Compiler Features: - * Code generator: Implemented events with function type as one of its indexed parameters. - * General: Option to stop compilation after parsing stage. Can be used with ``solc --stop-after parsing`` - * Optimizer: Optimize ``exp`` when base is ``-1``. - * SMTChecker: Support ``addmod`` and ``mulmod``. - * SMTChecker: Support array slices. - * SMTChecker: Support type conversions. - - -Bugfixes: - * Fixed internal compiler errors for certain contracts involving the ``new`` expression. - * JSON AST: Fix internal error when using ``--ast-json`` on a function with memory arguments in ABIEncoderV2 contracts. - * Type Checker: Add missing checks for calls using types incompatible with ABIEncoderV1 in modules where ABIEncoderV2 is not enabled. - * Type Checker: Fix internal compiler error when calling `.push()` for a storage array with a nested mapping. - - -### 0.7.2 (2020-09-28) - -Important Bugfixes: - * Type Checker: Disallow two or more free functions with identical name (potentially imported and aliased) and parameter types. - -Compiler Features: - * Export compiler-generated utility sources via standard-json or combined-json. - * Optimizer: Optimize ``exp`` when base is 0, 1 or 2. - * SMTChecker: Keep knowledge about string literals, even through assignment, and thus support the ``.length`` property properly. - * SMTChecker: Support ``address`` type conversion with literals, e.g. ``address(0)``. - * SMTChecker: Support ``revert()``. - * SMTChecker: Support ``type(T).min``, ``type(T).max``, and ``type(I).interfaceId``. - * SMTChecker: Support compound and, or, and xor operators. - * SMTChecker: Support events and low-level logs. - * SMTChecker: Support fixed bytes index access. - * SMTChecker: Support memory allocation, e.g. ``new bytes(123)``. - * SMTChecker: Support shifts. - * SMTChecker: Support structs. - * Type Checker: Explain why oversized hex string literals can not be explicitly converted to a shorter ``bytesNN`` type. - * Type Checker: More detailed error messages why implicit conversions fail. - * Type Checker: Report position of first invalid UTF-8 sequence in ``unicode""`` literals. - * Yul IR Generator: Report source locations related to unimplemented features. - * Yul Optimizer: Inline into functions further down in the call graph first. - * Yul Optimizer: Prune unused parameters in functions. - * Yul Optimizer: Try to simplify function names. - - -Bugfixes: - * Code generator: Fix internal error on stripping dynamic types from return parameters on EVM versions without ``RETURNDATACOPY``. - * Type Checker: Add missing check against nested dynamic arrays in ABI encoding functions when ABIEncoderV2 is disabled. - * Type Checker: Correct the error message for invalid named parameter in a call to refer to the right argument. - * Type Checker: Disallow ``virtual`` for modifiers in libraries. - * Name Resolver: Correct the warning for homonymous, but not shadowing declarations. - * Type system: Fix internal error on implicit conversion of contract instance to the type of its ``super``. - * Type system: Fix internal error on implicit conversion of string literal to a calldata string. - * Type system: Fix named parameters in overloaded function and event calls being matched incorrectly if the order differs from the declaration. - * ViewPureChecker: Prevent visibility check on constructors. - - -### 0.7.1 (2020-09-02) - -Language Features: - * Allow function definitions outside of contracts, behaving much like internal library functions. - * Code generator: Implementing copying structs from calldata to storage. - -Compiler Features: - * SMTChecker: Add underflow and overflow as verification conditions in the CHC engine. - * SMTChecker: Support bitwise or, xor and not operators. - * SMTChecker: Support conditional operator. - * Standard JSON Interface: Do not run EVM bytecode code generation, if only Yul IR or EWasm output is requested. - * Yul Optimizer: LoopInvariantCodeMotion can move reading operations outside for-loops as long as the affected area is not modified inside the loop. - * Yul: Report error when using non-string literals for ``datasize()``, ``dataoffset()``, ``linkersymbol()``, ``loadimmutable()``, ``setimmutable()``. - -Bugfixes: - * AST: Remove ``null`` member values also when the compiler is used in standard-json-mode. - * General: Allow `type(Contract).name` for abstract contracts and interfaces. - * Immutables: Disallow assigning immutables more than once during their declaration. - * Immutables: Properly treat complex assignment and increment/decrement as both reading and writing and thus disallow it everywhere for immutable variables. - * Optimizer: Keep side-effects of ``x`` in ``byte(a, shr(b, x))`` even if the constants ``a`` and ``b`` would make the expression zero unconditionally. This optimizer rule is very hard if not impossible to trigger in a way that it can result in invalid code, though. - * References Resolver: Fix internal bug when using constructor for library. - * Scanner: Fix bug where whitespace would be allowed within the ``->`` token (e.g. ``function f() - > x {}`` becomes invalid in inline assembly and Yul). - * SMTChecker: Fix internal error in BMC function inlining. - * SMTChecker: Fix internal error on array implicit conversion. - * SMTChecker: Fix internal error on fixed bytes index access. - * SMTChecker: Fix internal error on lvalue unary operators with tuples. - * SMTChecker: Fix internal error on tuple assignment. - * SMTChecker: Fix internal error on tuples of one element that have tuple type. - * SMTChecker: Fix internal error when using imported code. - * SMTChecker: Fix soundness of array ``pop``. - * Type Checker: Disallow ``using for`` directive inside interfaces. - * Type Checker: Disallow signed literals as exponent in exponentiation operator. - * Type Checker: Disallow structs containing nested mapping in memory as parameters for library functions. - * Yul Optimizer: Ensure that Yul keywords are not mistakenly used by the NameDispenser and VarNameCleaners. The bug would manifest as uncompilable code. - * Yul Optimizer: Make function inlining order more resilient to whether or not unrelated source files are present. - - -### 0.7.0 (2020-07-28) - -Breaking changes: - * Inline Assembly: Disallow ``.`` in user-defined function and variable names. - * Inline Assembly: Slot and offset of storage pointer variable ``x`` are accessed via ``x.slot`` and ``x.offset`` instead of ``x_slot`` and ``x_offset``. - * JSON AST: Mark hex string literals with ``kind: "hexString"``. - * JSON AST: Remove members with ``null`` value from JSON output. - * Parser: Disallow ``gwei`` as identifier. - * Parser: Disallow dot syntax for ``value`` and ``gas``. - * Parser: Disallow non-printable characters in string literals. - * Parser: Introduce Unicode string literals: ``unicode"😃"``. - * Parser: NatSpec comments on variables are only allowed for public state variables. - * Parser: Remove the ``finney`` and ``szabo`` denominations. - * Parser: Remove the identifier ``now`` (replaced by ``block.timestamp``). - * Reference Resolver: ``using A for B`` only affects the contract it is mentioned in and not all derived contracts - * Type Checker: Disallow ``virtual`` for library functions. - * Type Checker: Disallow assignments to state variables that contain nested mappings. - * Type checker: Disallow events with same name and parameter types in inheritance hierarchy. - * Type Checker: Disallow shifts by signed types. - * Type Checker: Disallow structs and arrays in memory or calldata if they contain nested mappings. - * Type Checker: Exponentiation and shifts of literals by non-literals will always use ``uint256`` or ``int256`` as a type. - * Yul: Disallow consecutive and trailing dots in identifiers. Leading dots were already disallowed. - * Yul: Disallow EVM instruction `pc()`. - - -Language Features: - * Inheritance: Allow overrides to have stricter state mutability: ``view`` can override ``nonpayable`` and ``pure`` can override ``view``. - * Parser: Deprecate visibility for constructors. - * State mutability: Do not issue recommendation for stricter mutability for virtual functions but do issue it for functions that override. - - -Compiler Features: - * SMTChecker: Report multi-transaction counterexamples including the function calls that initiate the transactions. This does not include concrete values for reference types and reentrant calls. - * Variable declarations using the ``var`` keyword are not recognized anymore. - - -Bugfixes: - * Immutables: Fix internal compiler error when immutables are not assigned. - * Inheritance: Disallow public state variables overwriting ``pure`` functions. - * NatSpec: Constructors and functions have consistent userdoc output. - * SMTChecker: Fix internal error when assigning to a 1-tuple. - * SMTChecker: Fix internal error when tuples have extra effectless parenthesis. - * State Mutability: Constant public state variables are considered ``pure`` functions. - * Type Checker: Fixing deduction issues on function types when function call has named arguments. - - -### 0.6.12 (2020-07-22) - -Language Features: - * NatSpec: Implement tag ``@inheritdoc`` to copy documentation from a specific base contract. - * Wasm backend: Add ``i32.ctz``, ``i64.ctz``, ``i32.popcnt``, and ``i64.popcnt``. - - -Compiler Features: - * Code Generator: Avoid double cleanup when copying to memory. - * Code Generator: Evaluate ``keccak256`` of string literals at compile-time. - * Optimizer: Add rule to remove shifts inside the byte opcode. - * Peephole Optimizer: Add rule to remove swap after dup. - * Peephole Optimizer: Remove unnecessary masking of tags. - * Yul EVM Code Transform: Free stack slots directly after visiting the right-hand-side of variable declarations instead of at the end of the statement only. - - -Bugfixes: - * SMTChecker: Fix error in events with indices of type static array. - * SMTChecker: Fix internal error in sequential storage array pushes (``push().push()``). - * SMTChecker: Fix internal error when using bitwise operators on fixed bytes type. - * SMTChecker: Fix internal error when using compound bitwise operator assignments on array indices inside branches. - * Type Checker: Fix internal compiler error related to oversized types. - * Type Checker: Fix overload resolution in combination with ``{value: ...}``. - - -Build System: - * Update internal dependency of jsoncpp to 1.9.3. - - -### 0.6.11 (2020-07-07) - - -Language Features: - * General: Add unit denomination ``gwei`` - * Yul: Support ``linkersymbol`` builtin in standalone assembly mode to refer to library addresses. - * Yul: Support using string literals exceeding 32 bytes as literal arguments for builtins. - - -Compiler Features: - * NatSpec: Add fields ``kind`` and ``version`` to the JSON output. - * NatSpec: Inherit tags from unique base functions if derived function does not provide any. - * Commandline Interface: Prevent some incompatible commandline options from being used together. - * NatSpec: Support NatSpec comments on events. - * Yul Optimizer: Store knowledge about storage / memory after ``a := sload(x)`` / ``a := mload(x)``. - * SMTChecker: Support external calls to unknown code. - * Source Maps: Also tag jumps into and out of Yul functions as jumps into and out of functions. - - -Bugfixes: - * NatSpec: Do not consider ``////`` and ``/***`` as NatSpec comments. - * Type Checker: Disallow constructor parameters with ``calldata`` data location. - * Type Checker: Do not disallow assigning to calldata variables. - * Type Checker: Fix internal error related to ``using for`` applied to non-libraries. - * Wasm backend: Fix code generation for for-loops with pre statements. - * Wasm backend: Properly support both ``i32.drop`` and ``i64.drop``, and remove ``drop``. - * Yul: Disallow the same variable to occur multiple times on the left-hand side of an assignment. - * Yul: Fix source location of variable multi-assignment. - - -### 0.6.10 (2020-06-11) - -Important Bugfixes: - * Fixed a bug related to internal library functions with ``calldata`` parameters called via ``using for``. - - -Compiler Features: - * Commandline Interface: Re-group help screen. - * Output compilation error codes in standard-json and when using ``--error-codes``. - * Yul: Raise warning for switch statements that only have a default and no other cases. - - -Bugfixes: - * SMTChecker: Fix internal error when encoding tuples of tuples. - * SMTChecker: Fix aliasing soundness after pushing to an array pointer. - * Type system: Fix internal compiler error on calling externally a function that returns variables with calldata location. - * Type system: Fix bug where a bound function was not found if ``using for`` is applied to explicit reference types. - - -### 0.6.9 (2020-06-04) - -Language Features: - * Permit calldata location for all variables. - * NatSpec: Support NatSpec comments on state variables. - * Yul: EVM instruction `pc()` is marked deprecated and will be removed in the next breaking release. - - -Compiler Features: - * Build system: Update the soljson.js build to emscripten 1.39.15 and boost 1.73.0 and include Z3 for integrated SMTChecker support without the callback mechanism. - * Build system: Switch the emscripten build from the fastcomp backend to the upstream backend. - * Code Generator: Do not introduce new internal source references for small compiler routines. - * Commandline Interface: Adds new option ``--base-path PATH`` to use the given path as the root of the source tree (defaults to the root of the filesystem). - * SMTChecker: Support array ``length``. - * SMTChecker: Support array ``push`` and ``pop``. - * SMTChecker: General support to BitVectors and the bitwise ``and`` operator. - - -Bugfixes: - * Code Generator: Trigger proper unimplemented errors on certain array copy operations. - * Commandline Interface: Fix internal error when using ``--assemble`` or ``--yul`` options with ``--machine ewasm`` but without specifying ``--yul-dialect``. - * NatSpec: DocString block is terminated when encountering an empty line. - * Optimizer: Fixed a bug in BlockDeDuplicator. - * Scanner: Fix bug when two empty NatSpec comments lead to scanning past EOL. - * SMTChecker: Fix internal error on try/catch clauses with parameters. - * SMTChecker: Fix internal error when applying arithmetic operators to fixed point variables. - * SMTChecker: Fix internal error when assigning to index access inside branches. - * SMTChecker: Fix internal error when short circuiting Boolean expressions with function calls in state variable initialization. - * Type Checker: Disallow assignments to storage variables of type ``mapping``. - * Type Checker: Disallow inline arrays of non-nameable types. - * Type Checker: Disallow usage of override with non-public state variables. - * Type Checker: Fix internal compiler error when accessing members of array slices. - * Type Checker: Fix internal compiler error when forward referencing non-literal constants from inline assembly. - * Type Checker: Fix internal compiler error when trying to decode too large static arrays. - * Type Checker: Fix wrong compiler error when referencing an overridden function without calling it. - - -### 0.6.8 (2020-05-14) - -Important Bugfixes: - * Add missing callvalue check to the creation code of a contract that does not define a constructor but has a base that does define a constructor. - * Disallow array slices of arrays with dynamically encoded base types. - * String literals containing backslash characters can no longer cause incorrect code to be generated when passed directly to function calls or encoding functions when ABIEncoderV2 is active. - - -Language Features: - * Implemented ``type(T).min`` and ``type(T).max`` for every integer type ``T`` that returns the smallest and largest value representable by the type. - - -Compiler Features: - * Commandline Interface: Don't ignore `--yul-optimizations` in assembly mode. - * Allow using abi encoding functions for calldata array slices without explicit casts. - * Wasm binary output: Implement ``br`` and ``br_if``. - - -Bugfixes: - * ABI: Skip ``private`` or ``internal`` constructors. - * Fixed an "Assembly Exception in Bytecode" error where requested functions were generated twice. - * Natspec: Fixed a bug that ignored ``@return`` tag when no other developer-documentation tags were present. - * Type Checker: Checks if a literal exponent in the ``**`` operation is too large or fractional. - * Type Checker: Disallow accessing ``runtimeCode`` for contract types that contain immutable state variables. - * Yul Assembler: Fix source location of variable declarations without value. - - -### 0.6.7 (2020-05-04) - -Language Features: - * Add support for EIP 165 interface identifiers with `type(I).interfaceId`. - * Allow virtual modifiers inside abstract contracts to have empty body. - - -Compiler Features: - * Optimizer: Simplify repeated AND and OR operations. - * Standard Json Input: Support the prefix ``file://`` in the field ``urls``. - * Add option to specify optimization steps to be performed by Yul optimizer with `--yul-optimizations` in the commandline interface or `optimizer.details.yulDetails.optimizerSteps` in standard-json. - -Bugfixes: - * SMTChecker: Fix internal error when fixed points are used. - * SMTChecker: Fix internal error when using array slices. - * Type Checker: Disallow ``virtual`` and ``override`` for constructors. - * Type Checker: Fix several internal errors by performing size and recursiveness checks of types before the full type checking. - * Type Checker: Fix internal error when assigning to empty tuples. - * Type Checker: Fix internal error when applying unary operators to tuples with empty components. - * Type Checker: Perform recursiveness check on structs declared at the file level. - -Build System: - * soltest.sh: ``SOLIDITY_BUILD_DIR`` is no longer relative to ``REPO_ROOT`` to allow for build directories outside of the source tree. - - - -### 0.6.6 (2020-04-09) - -Important Bugfixes: - * Fix tuple assignments with components occupying multiple stack slots and different stack size on left- and right-hand-side. - - -Bugfixes: - * AST export: Export `immutable` property in the field `mutability`. - * SMTChecker: Fix internal error in the CHC engine when calling inherited functions internally. - * Type Checker: Error when trying to encode functions with call options gas and value set. - - - -### 0.6.5 (2020-04-06) - -Important Bugfixes: - * Code Generator: Restrict the length of dynamic memory arrays to 64 bits during creation at runtime fixing a possible overflow. - - -Language Features: - * Allow local storage variables to be declared without initialization, as long as they are assigned before they are accessed. - * State variables can be marked ``immutable`` which causes them to be read-only, but assignable in the constructor. The value will be stored directly in the code. - - -Compiler Features: - * Commandline Interface: Enable output of storage layout with `--storage-layout`. - * Metadata: Added support for IPFS hashes of large files that need to be split in multiple chunks. - - -Bugfixes: - * Inheritance: Allow public state variables to override functions with dynamic memory types in their return values. - * Inline Assembly: Fix internal error when accessing invalid constant variables. - * Inline Assembly: Fix internal error when accessing functions. - * JSON AST: Always add pointer suffix for memory reference types. - * Reference Resolver: Fix internal error when accessing invalid struct members. - * Type Checker: Fix internal errors when assigning nested tuples. - - -### 0.6.4 (2020-03-10) - -Language Features: - * General: Deprecated `value(...)` and `gas(...)` in favor of `{value: ...}` and `{gas: ...}` - * Inline Assembly: Allow assigning to `_slot` of local storage variable pointers. - * Inline Assembly: Perform control flow analysis on inline assembly. Allows storage returns to be set in assembly only. - - -Compiler Features: - * AssemblyStack: Support for source locations (source mappings) and thus debugging Yul sources. - * Commandline Interface: Enable output of experimental optimized IR via ``--ir-optimized``. - - -Bugfixes: - * Inheritance: Fix incorrect error on calling unimplemented base functions. - * Reference Resolver: Fix scoping issue following try/catch statements. - * Standard-JSON-Interface: Fix a bug related to empty filenames and imports. - * SMTChecker: Fix internal errors when analysing tuples. - * Yul AST Import: correctly import blocks as statements, switch statements and string literals. - -### 0.6.3 (2020-02-18) - -Language Features: - * Allow contract types and enums as keys for mappings. - * Allow function selectors to be used as compile-time constants. - * Report source locations for structured documentation errors. - - -Compiler Features: - * AST: Add a new node for doxygen-style, structured documentation that can be received by contract, function, event and modifier definitions. - * Code Generator: Use ``calldatacopy`` instead of ``codecopy`` to zero out memory past input. - * Debug: Provide reason strings for compiler-generated internal reverts when using the ``--revert-strings`` option or the ``settings.debug.revertStrings`` setting on ``debug`` mode. - * Yul Optimizer: Prune functions that call each other but are otherwise unreferenced. - * SMTChecker: CHC support to internal function calls. - - -Bugfixes: - * Assembly: Added missing `source` field to legacy assembly json output to complete the source reference. - * Parser: Fix an internal error for ``abstract`` without ``contract``. - * Type Checker: Make invalid calls to uncallable types fatal errors instead of regular. - - -### 0.6.2 (2020-01-27) - -Language Features: - * Allow accessing external functions via contract and interface names to obtain their selector. - * Allow interfaces to inherit from other interfaces - * Allow gas and value to be set in external function calls using ``c.f{gas: 10000, value: 4 ether}()``. - * Allow specifying the ``salt`` for contract creations and thus the ``create2`` opcode using ``new C{salt: 0x1234, value: 1 ether}(arg1, arg2)``. - * Inline Assembly: Support literals ``true`` and ``false``. - - -Compiler Features: - * LLL: The LLL compiler has been removed. - * General: Raise warning if runtime bytecode exceeds 24576 bytes (a limit introduced in Spurious Dragon). - * General: Support compiling starting from an imported AST. Among others, this can be used for mutation testing. - * Yul Optimizer: Apply penalty when trying to rematerialize into loops. - - -Bugfixes: - * Commandline interface: Only activate yul optimizer if ``--optimize`` is given. - * Fixes internal compiler error on explicitly calling unimplemented base functions. - - -Build System: - * Switch to building soljson.js with an embedded base64-encoded wasm binary. - - -### 0.6.1 (2020-01-02) - -Bugfixes: - * Yul Optimizer: Fix bug in redundant assignment remover in combination with break and continue statements. - - -### 0.6.0 (2019-12-17) - -Breaking changes: - * ABI: Remove the deprecated ``constant`` and ``payable`` fields. - * ABI: The ``type`` field is now required and no longer specified to default to ``function``. - * AST: Inline assembly is exported as structured JSON instead of plain string. - * C API (``libsolc``): Introduce context parameter to both ``solidity_compile`` and the callback. - * C API (``libsolc``): The provided callback now takes two parameters, kind and data. The callback can then be used for multiple purposes, such has file imports and SMT queries. - * C API (``libsolc``): ``solidity_free`` was renamed to ``solidity_reset``. Functions ``solidity_alloc`` and ``solidity_free`` were added. - * C API (``libsolc``): ``solidity_compile`` now returns a string that must be explicitly freed via ``solidity_free()`` - * Commandline Interface: Remove the text-based AST printer (``--ast``). - * Commandline Interface: Switch to the new error reporter by default. ``--old-reporter`` falls back to the deprecated old error reporter. - * Commandline Interface: Add option to disable or choose hash method between IPFS and Swarm for the bytecode metadata. - * General: Disallow explicit conversions from external function types to ``address`` and add a member called ``address`` to them as replacement. - * General: Enable Yul optimizer as part of standard optimization. - * General: New reserved keywords: ``override``, ``receive``, and ``virtual``. - * General: ``private`` cannot be used together with ``virtual``. - * General: Split unnamed fallback functions into two cases defined using ``fallback()`` and ``receive()``. - * Inheritance: State variable shadowing is now disallowed. - * Inline Assembly: Only strict inline assembly is allowed. - * Inline Assembly: Variable declarations cannot shadow declarations outside the assembly block. - * JSON AST: Replace ``superFunction`` attribute by ``baseFunctions``. - * Natspec JSON Interface: Properly support multiple ``@return`` statements in ``@dev`` documentation and enforce named return parameters to be mentioned documentation. - * Source mappings: Add "modifier depth" as a fifth field in the source mappings. - * Standard JSON Interface: Add option to disable or choose hash method between IPFS and Swarm for the bytecode metadata. - * Syntax: ``push(element)`` for dynamic storage arrays do not return the new length anymore. - * Syntax: Abstract contracts need to be marked explicitly as abstract by using the ``abstract`` keyword. - * Syntax: ``length`` member of arrays is now always read-only, even for storage arrays. - * Type Checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base. - -Language Features: - * Allow explicit conversions from ``address`` to ``address payable`` via ``payable(...)``. - * Allow global enums and structs. - * Allow public variables to override external functions. - * Allow underscores as delimiters in hex strings. - * Allow to react on failing external calls using ``try`` and ``catch``. - * Introduce syntax for array slices and implement them for dynamic calldata arrays. - * Introduce ``push()`` for dynamic storage arrays. It returns a reference to the newly allocated element, if applicable. - * Introduce ``virtual`` and ``override`` keywords. - * Modify ``push(element)`` for dynamic storage arrays such that it does not return the new length anymore. - * Yul: Introduce ``leave`` statement that exits the current function. - * JSON AST: Add the function selector of each externally-visible FunctonDefinition to the AST JSON export. - -Compiler Features: - * Allow revert strings to be stripped from the binary using the ``--revert-strings`` option or the ``settings.debug.revertStrings`` setting. - * ABIEncoderV2: Do not warn about enabled ABIEncoderV2 anymore (the pragma is still needed, though). - - -### 0.5.17 (2020-03-17) - -Bugfixes: - * Type Checker: Disallow overriding of private functions. - - -### 0.5.16 (2020-01-02) - -Backported Bugfixes: - * Yul Optimizer: Fix bug in redundant assignment remover in combination with break and continue statements. - - -### 0.5.15 (2019-12-17) - -Bugfixes: - * Yul Optimizer: Fix incorrect redundant load optimization crossing user-defined functions that contain for-loops with memory / storage writes. - -### 0.5.14 (2019-12-09) - -Language Features: - * Allow to obtain the selector of public or external library functions via a member ``.selector``. - * Inline Assembly: Support constants that reference other constants. - * Parser: Allow splitting hexadecimal and regular string literals into multiple parts. - - -Compiler Features: - * Commandline Interface: Allow translation from yul / strict assembly to EWasm using ``solc --yul --yul-dialect evm --machine ewasm`` - * Set the default EVM version to "Istanbul". - * SMTChecker: Add support to constructors including constructor inheritance. - * Yul: When compiling via Yul, string literals from the Solidity code are kept as string literals if every character is safely printable. - * Yul Optimizer: Perform loop-invariant code motion. - - -Bugfixes: - * SMTChecker: Fix internal error when using ``abi.decode``. - * SMTChecker: Fix internal error when using arrays or mappings of functions. - * SMTChecker: Fix internal error in array of structs type. - * Version Checker: ``^0`` should match ``0.5.0``, but no prerelease. - * Yul: Consider infinite loops and recursion to be not removable. - - -Build System: - * Update to emscripten version 1.39.3. - - -### 0.5.13 (2019-11-14) - -Language Features: - * Allow to obtain the address of a linked library with ``address(LibraryName)``. - - -Compiler Features: - * Code Generator: Use SELFBALANCE opcode for ``address(this).balance`` if using Istanbul EVM. - * EWasm: Experimental EWasm binary output via ``--ewasm`` and as documented in standard-json. - * SMTChecker: Add break/continue support to the CHC engine. - * SMTChecker: Support assignments to multi-dimensional arrays and mappings. - * SMTChecker: Support inheritance and function overriding. - * Standard JSON Interface: Output the storage layout of a contract when artifact ``storageLayout`` is requested. - * TypeChecker: List possible candidates when overload resolution fails. - * TypeChecker: Disallow variables of library types. - -Bugfixes: - * Code Generator: Fixed a faulty assert that would wrongly trigger for array sizes exceeding unsigned integer. - * SMTChecker: Fix internal error when accessing indices of fixed bytes. - * SMTChecker: Fix internal error when using function pointers as arguments. - * SMTChecker: Fix internal error when implicitly converting string literals to fixed bytes. - * Type Checker: Disallow constructor of the same class to be used as modifier. - * Type Checker: Treat magic variables as unknown identifiers in inline assembly. - * Code Generator: Fix internal error when trying to convert ``super`` to a different type - - -### 0.5.12 (2019-10-01) - -Language Features: - * Type Checker: Allow assignment to external function arguments except for reference types. - - -Compiler Features: - * ABI Output: Change sorting order of functions from selector to kind, name. - * Optimizer: Add rule that replaces the BYTE opcode by 0 if the first argument is larger than 31. - * SMTChecker: Add loop support to the CHC engine. - * Yul Optimizer: Take side-effect-freeness of user-defined functions into account. - * Yul Optimizer: Remove redundant mload/sload operations. - * Yul Optimizer: Use the fact that branch conditions have certain value inside the branch. - - -Bugfixes: - * Code Generator: Fix internal error when popping a dynamic storage array of mappings. - * Name Resolver: Fix wrong source location when warning on shadowed aliases in import declarations. - * Scanner: Fix multi-line natspec comment parsing with triple slashes when file is encoded with CRLF instead of LF. - * Type System: Fix arrays of recursive structs. - * Yul Optimizer: Fix reordering bug in connection with shifted one and mul/div-instructions in for loop conditions. - - -### 0.5.11 (2019-08-12) - - -Language Features: - * Inline Assembly: Support direct constants of value type in inline assembly. - -Compiler Features: - * ABI: Additional internal type info in the field ``internalType``. - * eWasm: Highly experimental eWasm output using ``--ewasm`` in the commandline interface or output selection of ``ewasm.wast`` in standard-json. - * Metadata: Update the swarm hash to the current specification, changes ``bzzr0`` to ``bzzr1`` and urls to use ``bzz-raw://``. - * Standard JSON Interface: Compile only selected sources and contracts. - * Standard JSON Interface: Provide secondary error locations (e.g. the source position of other conflicting declarations). - * SMTChecker: Do not erase knowledge about storage pointers if another storage pointer is assigned. - * SMTChecker: Support string literal type. - * SMTChecker: New Horn-based algorithm that proves assertions via multi-transaction contract invariants. - * Standard JSON Interface: Provide AST even on errors if ``--error-recovery`` commandline switch or StandardCompiler `settings.parserErrorRecovery` is true. - * Yul Optimizer: Do not inline function if it would result in expressions being duplicated that are not cheap. - - -Bugfixes: - * ABI decoder: Ensure that decoded arrays always point to distinct memory locations. - * Code Generator: Treat dynamically encoded but statically sized arrays and structs in calldata properly. - * SMTChecker: Fix internal error when inlining functions that contain tuple expressions. - * SMTChecker: Fix pointer knowledge erasing in loops. - * SMTChecker: Fix internal error when using compound bitwise assignment operators inside branches. - * SMTChecker: Fix internal error when inlining a function that returns a tuple containing an unsupported type inside a branch. - * SMTChecker: Fix internal error when inlining functions that use state variables and belong to a different source. - * SMTChecker: Fix internal error when reporting counterexamples concerning state variables from different source files. - * SMTChecker: Fix SMT sort mismatch when using string literals. - * View/Pure Checker: Properly detect state variable access through base class. - * Yul Analyzer: Check availability of data objects already in analysis phase. - * Yul Optimizer: Fix an issue where memory-accessing code was removed even though ``msize`` was used in the program. - - -### 0.5.10 (2019-06-25) - -Important Bugfixes: - * ABIEncoderV2: Fix incorrect abi encoding of storage array of data type that occupy multiple storage slots - * Code Generator: Properly zero out higher order bits in elements of an array of negative numbers when assigning to storage and converting the type at the same time. - - -Compiler Features: - * Commandline Interface: Experimental parser error recovery via the ``--error-recovery`` commandline switch or StandardCompiler `settings.parserErrorRecovery` boolean. - * Optimizer: Add rule to simplify ``SUB(~0, X)`` to ``NOT(X)``. - * Yul Optimizer: Make the optimizer work for all dialects of Yul including eWasm. - - -Bugfixes: - * Type Checker: Set state mutability of the function type members ``gas`` and ``value`` to pure (while their return type inherits state mutability from the function type). - * Yul / Inline Assembly Parser: Disallow trailing commas in function call arguments. - - -Build System: - * Attempt to use stock Z3 cmake files to find Z3 and only fall back to manual discovery. - * CMake: use imported targets for boost. - * Emscripten build: upgrade to boost 1.70. - * Generate a cmake error for gcc versions older than 5.0. - - - -### 0.5.9 (2019-05-28) - -Language Features: - * Inline Assembly: Revert change introduced in 0.5.7: The ``callvalue()`` instruction does not require ``payable`` anymore. - * Static Analyzer: Disallow libraries calling themselves externally. - - -Compiler Features: - * Assembler: Encode the compiler version in the deployed bytecode. - * Code Generator: Fix handling of structs of dynamic size as constructor parameters. - * Inline Assembly: Disallow the combination of ``msize()`` and the Yul optimizer. - * Metadata: Add IPFS hashes of source files. - * Optimizer: Add rule to simplify SHL/SHR combinations. - * Optimizer: Add rules for multiplication and division by left-shifted one. - * SMTChecker: Support inherited state variables. - * SMTChecker: Support tuples and function calls with multiple return values. - * SMTChecker: Support ``delete``. - * SMTChecker: Inline external function calls to ``this``. - * Yul Optimizer: Simplify single-run ``for`` loops to ``if`` statements. - * Yul Optimizer: Optimize representation of numbers. - * Yul Optimizer: Do not inline recursive functions. - * Yul Optimizer: Do not remove instructions that affect ``msize()`` if ``msize()`` is used. - -Bugfixes: - * Code Generator: Explicitly turn uninitialized internal function pointers into invalid functions when loaded from storage. - * Code Generator: Fix assertion failure when assigning structs containing array of mapping. - * Compiler Internals: Reset the Yul string repository before each compilation, freeing up memory. - * SMTChecker: Fix bad cast in base constructor modifier. - * SMTChecker: Fix internal error when visiting state variable inherited from base class. - * SMTChecker: Fix internal error in fixed point operations. - * SMTChecker: Fix internal error in assignment to unsupported type. - * SMTChecker: Fix internal error in branching when inlining function calls that modify local variables. - - -### 0.5.8 (2019-04-30) - -Important Bugfixes: - * Code Generator: Fix initialization routine of uninitialized internal function pointers in constructor context. - * Yul Optimizer: Fix SSA transform for multi-assignments. - - -Language Features: - * ABIEncoderV2: Implement encoding of calldata arrays and structs. - * Code Generation: Implement copying recursive structs from storage to memory. - * Yul: Disallow function definitions inside for-loop init blocks. - - -Compiler Features: - * ABI Decoder: Raise a runtime error on dirty inputs when using the experimental decoder. - * Optimizer: Add rule for shifts by constants larger than 255 for Constantinople. - * Optimizer: Add rule to simplify certain ANDs and SHL combinations - * SMTChecker: Support arithmetic compound assignment operators. - * SMTChecker: Support unary increment and decrement for array and mapping access. - * SMTChecker: Show unsupported warning for inline assembly blocks. - * SMTChecker: Support mod. - * SMTChecker: Support ``contract`` type. - * SMTChecker: Support ``this`` as address. - * SMTChecker: Support address members. - * Standard JSON Interface: Metadata settings now re-produce the original ``"useLiteralContent"`` setting from the compilation input. - * Yul: Adds break and continue keywords to for-loop syntax. - * Yul: Support ``.`` as part of identifiers. - * Yul Optimizer: Adds steps for detecting and removing of dead code. - * Yul Code Generator: Directly jump over a series of function definitions (instead of jumping over each one) - - -Bugfixes: - * SMTChecker: Implement Boolean short-circuiting. - * SMTChecker: SSA control-flow did not take into account state variables that were modified inside inlined functions that were called inside branches. - * Type System: Use correct type name for contracts in event parameters when used in libraries. This affected code generation. - * Type System: Allow direct call to base class functions that have overloads. - * Type System: Warn about shadowing builtin variables if user variables are named ``this`` or ``super``. - * Yul: Properly register functions and disallow shadowing between function variables and variables in the outside scope. - - -Build System: - * Soltest: Add commandline option `--test` / `-t` to isoltest which takes a string that allows filtering unit tests. - * soltest.sh: allow environment variable ``SOLIDITY_BUILD_DIR`` to specify build folder and add ``--help`` usage. - - -### 0.5.7 (2019-03-26) - -Important Bugfixes: - * ABIEncoderV2: Fix bugs related to loading short value types from storage when encoding an array or struct from storage. - * ABIEncoderV2: Fix buffer overflow problem when encoding packed array from storage. - * Optimizer: Fix wrong ordering of arguments in byte optimization rule for constants. - - -Language Features: - * Function calls with named arguments now work with overloaded functions. - - -Compiler Features: - * Inline Assembly: Issue error when using ``callvalue()`` inside nonpayable function (in the same way that ``msg.value`` already does). - * Standard JSON Interface: Support "Yul" as input language. - * SMTChecker: Show callstack together with model if applicable. - * SMTChecker: Support modifiers. - * Yul Optimizer: Enable stack allocation optimization by default if Yul optimizer is active (disable in ``yulDetails``). - - -Bugfixes: - * Code Generator: Defensively pad memory for ``type(Contract).name`` to multiples of 32. - * Type System: Detect and disallow internal function pointers as parameters for public/external library functions, even when they are nested/wrapped in structs, arrays or other types. - * Yul Optimizer: Properly determine whether a variable can be eliminated during stack compression pass. - * Yul / Inline Assembly Parser: Disallow more than one case statement with the same label inside a switch based on the label's integer value. - - -Build System: - * Install scripts: Fix boost repository URL for CentOS 6. - * Soltest: Fix hex string update in soltest. - - -### 0.5.6 (2019-03-13) - -Important Bugfixes: - * Yul Optimizer: Fix visitation order bug for the structural simplifier. - * Optimizer: Fix overflow in optimization rule that simplifies double shift by constant. - -Language Features: - * Allow calldata arrays with dynamically encoded base types with ABIEncoderV2. - * Allow dynamically encoded calldata structs with ABIEncoderV2. - - -Compiler Features: - * Optimizer: Add rules for ``lt``-comparisons with constants. - * Peephole Optimizer: Remove double ``iszero`` before ``jumpi``. - * SMTChecker: Support enums without typecast. - * SMTChecker: Support one-dimensional arrays. - * Type Checker: Provide better error messages for some literal conversions. - * Yul Optimizer: Add rule to remove empty default switch cases. - * Yul Optimizer: Add rule to remove empty cases if no default exists. - * Yul Optimizer: Add rule to replace a switch with no cases with ``pop(expression)``. - - -Bugfixes: - * JSON ABI: Json description of library ABIs no longer contains functions with internal types like storage structs. - * SMTChecker: Fix internal compiler error when contract contains too large rational number. - * Type system: Detect if a contract's base uses types that require the experimental abi encoder while the contract still uses the old encoder. - - -Build System: - * Soltest: Add support for arrays in function signatures. - * Soltest: Add support for struct arrays in function signatures. - * Soltest: Add support for left-aligned, unpadded hex string literals. - -### 0.5.5 (2019-03-05) - -Language Features: - * Add support for getters of mappings with ``string`` or ``bytes`` key types. - * Meta programming: Provide access to the name of contracts via ``type(C).name``. - - -Compiler Features: - * Support ``petersburg`` as ``evmVersion`` and set as default. - * Commandline Interface: Option to activate the experimental yul optimizer using ``-optimize-yul``. - * Inline Assembly: Consider ``extcodehash`` as part of Constantinople. - * Inline Assembly: Instructions unavailable to the currently configured EVM are errors now. - * SMTChecker: Do not report underflow/overflow if they always revert. This removes false positives when using ``SafeMath``. - * Standard JSON Interface: Allow retrieving metadata without triggering bytecode generation. - * Standard JSON Interface: Provide fine-grained control over the optimizer via the settings. - * Static Analyzer: Warn about expressions with custom types when they have no effect. - * Optimizer: Add new rules with constants including ``LT``, ``GT``, ``AND`` and ``BYTE``. - * Optimizer: Add rule for shifts with constants for Constantinople. - * Optimizer: Combine multiple shifts with constant shift-by values into one. - * Optimizer: Do not mask with 160-bits after ``CREATE`` and ``CREATE2`` as they are guaranteed to return an address or 0. - * Optimizer: Support shifts in the constant optimiser for Constantinople. - * Yul Optimizer: Add rule to replace switch statements with literals by matching case body. - - -Bugfixes: - * ABIEncoderV2: Fix internal error related to bare delegatecall. - * ABIEncoderV2: Fix internal error related to ecrecover. - * ABIEncoderV2: Fix internal error related to mappings as library parameters. - * ABIEncoderV2: Fix invalid signature for events containing structs emitted in libraries. - * Inline Assembly: Proper error message for missing variables. - * Optimizer: Fix internal error related to unused tag removal across assemblies. This never generated any invalid code. - * SMTChecker: Fix crash related to statically-sized arrays. - * TypeChecker: Fix internal error and disallow index access on contracts and libraries. - * Yul: Properly detect name clashes with functions before their declaration. - * Yul: Take built-in functions into account in the compilability checker. - * Yul Optimizer: Properly take reassignments to variables in sub-expressions into account when replacing in the ExpressionSimplifier. - - -Build System: - * Soltest: Add support for left-aligned, padded hex literals. - * Soltest: Add support for right-aligned, padded boolean literals. - -### 0.5.4 (2019-02-12) - -Language Features: - * Allow calldata structs without dynamically encoded members with ABIEncoderV2. - - -Compiler Features: - * ABIEncoderV2: Implement packed encoding. - * C API (``libsolc`` / raw ``soljson.js``): Introduce ``solidity_free`` method which releases all internal buffers to save memory. - * Commandline Interface: Adds new option ``--new-reporter`` for improved diagnostics formatting - along with ``--color`` and ``--no-color`` for colorized output to be forced (or explicitly disabled). - - -Bugfixes: - * Code Generator: Defensively pad allocation of creationCode and runtimeCode to multiples of 32 bytes. - * Commandline Interface: Allow yul optimizer only for strict assembly. - * Parser: Disallow empty import statements. - * Type Checker: Disallow mappings with data locations other than ``storage``. - * Type Checker: Fix internal error when a struct array index does not fit into a uint256. - * Type System: Properly report packed encoded size for arrays and structs (mostly unused until now). - - -Build System: - * Add support for continuous fuzzing via Google oss-fuzz - * SMT: If using Z3, require version 4.6.0 or newer. - * Soltest: Add parser that is used in the file-based unit test environment. - * Ubuntu PPA Packages: Use CVC4 as SMT solver instead of Z3 - - -### 0.5.3 (2019-01-22) - -Language Features: - * Provide access to creation and runtime code of contracts via ``type(C).creationCode`` / ``type(C).runtimeCode``. - - -Compiler Features: - * Control Flow Graph: Warn about unreachable code. - * SMTChecker: Support basic typecasts without truncation. - * SMTChecker: Support external function calls and erase all knowledge regarding storage variables and references. - - -Bugfixes: - * Emscripten: Split simplification rule initialization up further to work around issues with soljson.js in some browsers. - * Type Checker: Disallow calldata structs until implemented. - * Type Checker: Return type error if fixed point encoding is attempted instead of throwing ``UnimplementedFeatureError``. - * Yul: Check that arguments to ``dataoffset`` and ``datasize`` are literals at parse time and properly take this into account in the optimizer. - * Yul: Parse number literals for detecting duplicate switch cases. - * Yul: Require switch cases to have the same type. - - -Build System: - * Emscripten: Upgrade to emscripten 1.38.8 on travis and circleci. - - -### 0.5.2 (2018-12-19) - -Language Features: - * Control Flow Graph: Detect every access to uninitialized storage pointers. - - -Compiler Features: - * Inline Assembly: Improve error messages around invalid function argument count. - * Code Generator: Only check callvalue once if all functions are non-payable. - * Code Generator: Use codecopy for string constants more aggressively. - * Code Generator: Use binary search for dispatch function if more efficient. The size/speed tradeoff can be tuned using ``--optimize-runs``. - * SMTChecker: Support mathematical and cryptographic functions in an uninterpreted way. - * SMTChecker: Support one-dimensional mappings. - * Standard JSON Interface: Disallow unknown keys in standard JSON input. - * Standard JSON Interface: Only run code generation if it has been requested. This could lead to unsupported feature errors only being reported at the point where you request bytecode. - * Static Analyzer: Do not warn about unused variables or state mutability for functions with an empty body. - * Type Checker: Add an additional reason to be displayed when type conversion fails. - * Yul: Support object access via ``datasize``, ``dataoffset`` and ``datacopy`` in standalone assembly mode. - - -Bugfixes: - * Standard JSON Interface: Report specific error message for json input errors instead of internal compiler error. - - -Build System: - * Replace the trusty PPA build by a static build on cosmic that is used for the trusty package instead. - * Remove support for Visual Studio 2015. - - -### 0.5.1 (2018-12-03) - -Language Features: - * Allow mapping type for parameters and return variables of public and external library functions. - * Allow public functions to override external functions. - -Compiler Features: - * Code generator: Do not perform redundant double cleanup on unsigned integers when loading from calldata. - * Commandline interface: Experimental ``--optimize`` option for assembly mode (``--strict-assembly`` and ``--yul``). - * SMTChecker: SMTLib2 queries and responses passed via standard JSON compiler interface. - * SMTChecker: Support ``msg``, ``tx`` and ``block`` member variables. - * SMTChecker: Support ``gasleft()`` and ``blockhash()`` functions. - * SMTChecker: Support internal bound function calls. - * Yul: Support Yul objects in ``--assemble``, ``--strict-assembly`` and ``--yul`` commandline options. - -Bugfixes: - * Assembly output: Do not mix in/out jump annotations with arguments. - * Commandline interface: Fix crash when using ``--ast`` on empty runtime code. - * Code Generator: Annotate jump from calldata decoder to function as "jump in". - * Code Generator: Fix internal error related to state variables of function type access via base contract name. - * Optimizer: Fix nondeterminism bug related to the boost version and constants representation. The bug only resulted in less optimal but still correct code because the generated routine is always verified to be correct. - * Type Checker: Properly detect different return types when overriding an external interface function with a public contract function. - * Type Checker: Disallow struct return types for getters of public state variables unless the new ABI encoder is active. - * Type Checker: Fix internal compiler error when a field of a struct used as a parameter in a function type has a non-existent type. - * Type Checker: Disallow functions ``sha3`` and ``suicide`` also without a function call. - * Type Checker: Fix internal compiler error with ``super`` when base contract function is not implemented. - * Type Checker: Fixed internal error when trying to create abstract contract in some cases. - * Type Checker: Fixed internal error related to double declaration of events. - * Type Checker: Disallow inline arrays of mapping type. - * Type Checker: Consider abstract function to be implemented by public state variable. - -Build System: - * CMake: LLL is not built anymore by default. Must configure it with CMake as `-DLLL=ON`. - * Docker: Includes both Scratch and Alpine images. - * Emscripten: Upgrade to Emscripten SDK 1.37.21 and boost 1.67. - -Solc-Js: - * Fix handling of standard-json in the commandline executable. - * Remove support of nodejs 4. - - -### 0.5.0 (2018-11-13) - -How to update your code: - * Change every ``.call()`` to a ``.call("")`` and every ``.call(signature, a, b, c)`` to use ``.call(abi.encodeWithSignature(signature, a, b, c))`` (the last one only works for value types). - * Change every ``keccak256(a, b, c)`` to ``keccak256(abi.encodePacked(a, b, c))``. - * Add ``public`` to every function and ``external`` to every fallback or interface function that does not specify its visibility already. - * Make your fallback functions ``external``. - * Explicitly state the data location for all variables of struct, array or mapping types (including function parameters), e.g. change ``uint[] x = m_x`` to ``uint[] storage x = m_x``. Note that ``external`` functions require parameters with a data location of ``calldata``. - * Explicitly convert values of contract type to addresses before using an ``address`` member. Example: if ``c`` is a contract, change ``c.transfer(...)`` to ``address(c).transfer(...)``. - * Declare variables and especially function arguments as ``address payable``, if you want to call ``transfer`` on them. - -Breaking Changes: - * ABI Encoder: Properly pad data from calldata (``msg.data`` and external function parameters). Use ``abi.encodePacked`` for unpadded encoding. - * C API (``libsolc`` / raw ``soljson.js``): Removed the ``version``, ``license``, ``compileSingle``, ``compileJSON``, ``compileJSONCallback`` methods - and replaced them with the ``solidity_license``, ``solidity_version`` and ``solidity_compile`` methods. - * Code Generator: Signed right shift uses proper arithmetic shift, i.e. rounding towards negative infinity. Warning: this may silently change the semantics of existing code! - * Code Generator: Revert at runtime if calldata is too short or points out of bounds. This is done inside the ``ABI decoder`` and therefore also applies to ``abi.decode()``. - * Code Generator: Use ``STATICCALL`` for ``pure`` and ``view`` functions. This was already the case in the experimental 0.5.0 mode. - * Commandline interface: Remove obsolete ``--formal`` option. - * Commandline interface: Rename the ``--julia`` option to ``--yul``. - * Commandline interface: Require ``-`` if standard input is used as source. - * Commandline interface: Use hash of library name for link placeholder instead of name itself. - * Compiler interface: Disallow remappings with empty prefix. - * Control Flow Analyzer: Consider mappings as well when checking for uninitialized return values. - * Control Flow Analyzer: Turn warning about returning uninitialized storage pointers into an error. - * General: ``continue`` in a ``do...while`` loop jumps to the condition (it used to jump to the loop body). Warning: this may silently change the semantics of existing code. - * General: Disallow declaring empty structs. - * General: Disallow raw ``callcode`` (was already deprecated in 0.4.12). It is still possible to use it via inline assembly. - * General: Disallow ``var`` keyword. - * General: Disallow ``sha3`` and ``suicide`` aliases. - * General: Disallow the ``throw`` statement. This was already the case in the experimental 0.5.0 mode. - * General: Disallow the ``years`` unit denomination (was already deprecated in 0.4.24) - * General: Introduce ``emit`` as a keyword instead of parsing it as identifier. - * General: New keywords: ``calldata`` and ``constructor`` - * General: New reserved keywords: ``alias``, ``apply``, ``auto``, ``copyof``, ``define``, ``immutable``, - ``implements``, ``macro``, ``mutable``, ``override``, ``partial``, ``promise``, ``reference``, ``sealed``, - ``sizeof``, ``supports``, ``typedef`` and ``unchecked``. - * General: Remove assembly instruction aliases ``sha3`` and ``suicide`` - * General: C99-style scoping rules are enforced now. This was already the case in the experimental 0.5.0 mode. - * General: Disallow combining hex numbers with unit denominations (e.g. ``0x1e wei``). This was already the case in the experimental 0.5.0 mode. - * JSON AST: Remove ``constant`` and ``payable`` fields (the information is encoded in the ``stateMutability`` field). - * JSON AST: Replace the ``isConstructor`` field by a new ``kind`` field, which can be ``constructor``, ``fallback`` or ``function``. - * Interface: Remove "clone contract" feature. The ``--clone-bin`` and ``--combined-json clone-bin`` commandline options are not available anymore. - * Name Resolver: Do not exclude public state variables when looking for conflicting declarations. - * Optimizer: Remove the no-op ``PUSH1 0 NOT AND`` sequence. - * Parser: Disallow trailing dots that are not followed by a number. - * Parser: Remove ``constant`` as function state mutability modifier. - * Parser: Disallow uppercase X in hex number literals - * Type Checker: Disallow assignments between tuples with different numbers of components. This was already the case in the experimental 0.5.0 mode. - * Type Checker: Disallow values for constants that are not compile-time constants. This was already the case in the experimental 0.5.0 mode. - * Type Checker: Disallow arithmetic operations for boolean variables. - * Type Checker: Disallow tight packing of literals. This was already the case in the experimental 0.5.0 mode. - * Type Checker: Disallow calling base constructors without parentheses. This was already the case in the experimental 0.5.0 mode. - * Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size. - * Type Checker: Disallow conversions between unrelated contract types. Explicit conversion via ``address`` can still achieve it. - * Type Checker: Disallow empty return statements for functions with one or more return values. - * Type Checker: Disallow empty tuple components. This was partly already the case in the experimental 0.5.0 mode. - * Type Checker: Disallow multi-variable declarations with mismatching number of values. This was already the case in the experimental 0.5.0 mode. - * Type Checker: Disallow specifying base constructor arguments multiple times in the same inheritance hierarchy. This was already the case in the experimental 0.5.0 mode. - * Type Checker: Disallow calling constructor with wrong argument count. This was already the case in the experimental 0.5.0 mode. - * Type Checker: Disallow uninitialized storage variables. This was already the case in the experimental 0.5.0 mode. - * Type Checker: Detecting cyclic dependencies in variables and structs is limited in recursion to 256. - * Type Checker: Require explicit data location for all variables, including function parameters. This was partly already the case in the experimental 0.5.0 mode. - * Type Checker: Only accept a single ``bytes`` type for ``.call()`` (and family), ``keccak256()``, ``sha256()`` and ``ripemd160()``. - * Type Checker: Fallback function must be external. This was already the case in the experimental 0.5.0 mode. - * Type Checker: Interface functions must be declared external. This was already the case in the experimental 0.5.0 mode. - * Type Checker: Address members are not included in contract types anymore. An explicit conversion is now required before invoking an ``address`` member from a contract. - * Type Checker: Disallow "loose assembly" syntax entirely. This means that jump labels, jumps and non-functional instructions cannot be used anymore. - * Type System: Disallow explicit and implicit conversions from decimal literals to ``bytesXX`` types. - * Type System: Disallow explicit and implicit conversions from hex literals to ``bytesXX`` types of different size. - * Type System: Distinguish between payable and non-payable address types. - * View Pure Checker: Disallow ``msg.value`` in (or introducing it via a modifier to) a non-payable function. - * Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/solidity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible. - * References Resolver: Turn missing storage locations into an error. This was already the case in the experimental 0.5.0 mode. - * Syntax Checker: Disallow functions without implementation to use modifiers. This was already the case in the experimental 0.5.0 mode. - * Syntax Checker: Named return values in function types are an error. - * Syntax Checker: Strictly require visibility specifier for functions. This was already the case in the experimental 0.5.0 mode. - * Syntax Checker: Disallow unary ``+``. This was already the case in the experimental 0.5.0 mode. - * Syntax Checker: Disallow single statement variable declaration inside if/while/for bodies that are not blocks. - * View Pure Checker: Strictly enforce state mutability. This was already the case in the experimental 0.5.0 mode. - -Language Features: - * General: Add ``staticcall`` to ``address``. - * General: Allow appending ``calldata`` keyword to types, to explicitly specify data location for arguments of external functions. - * General: Support ``pop()`` for storage arrays. - * General: Scoping rules now follow the C99-style. - * General: Allow ``enum``s in interfaces. - * General: Allow ``mapping`` storage pointers as arguments and return values in all internal functions. - * General: Allow ``struct``s in interfaces. - * General: Provide access to the ABI decoder through ``abi.decode(bytes memory data, (...))``. - * General: Disallow zero length for fixed-size arrays. - * Parser: Accept the ``address payable`` type during parsing. - -Compiler Features: - * Build System: Support for Mojave version of macOS added. - * Code Generator: ``CREATE2`` instruction has been updated to match EIP1014 (aka "Skinny CREATE2"). It also is accepted as part of Constantinople. - * Code Generator: ``EXTCODEHASH`` instruction has been added based on EIP1052. - * Type Checker: Nicer error message when trying to reference overloaded identifiers in inline assembly. - * Type Checker: Show named argument in case of error. - * Type System: IntegerType is split into IntegerType and AddressType internally. - * Tests: Determine transaction status during IPC calls. - * Code Generator: Allocate and free local variables according to their scope. - * Removed ``pragma experimental "v0.5.0";``. - * Syntax Checker: Improved error message for lookup in function types. - * Name Resolver: Updated name suggestion look up function to take into account length of the identifier: 1: no search, 2-3: at most one change, 4-: at most two changes - * SMTChecker: Support calls to internal functions that return none or a single value. - -Bugfixes: - * Build System: Support versions of CVC4 linked against CLN instead of GMP. In case of compilation issues due to the experimental SMT solver support, the solvers can be disabled when configuring the project with CMake using ``-DUSE_CVC4=OFF`` or ``-DUSE_Z3=OFF``. - * Tests: Fix chain parameters to make ipc tests work with newer versions of cpp-ethereum. - * Code Generator: Fix allocation of byte arrays (zeroed out too much memory). - * Code Generator: Properly handle negative number literals in ABIEncoderV2. - * Code Generator: Do not crash on using a length of zero for multidimensional fixed-size arrays. - * Commandline Interface: Correctly handle paths with backslashes on windows. - * Control Flow Analyzer: Ignore unimplemented functions when detecting uninitialized storage pointer returns. - * Fix NatSpec json output for `@notice` and `@dev` tags on contract definitions. - * Optimizer: Correctly estimate gas costs of constants for special cases. - * Optimizer: Fix simplification rule initialization bug that appeared on some emscripten platforms. - * References Resolver: Do not crash on using ``_slot`` and ``_offset`` suffixes on their own. - * References Resolver: Enforce ``storage`` as data location for mappings. - * References Resolver: Properly handle invalid references used together with ``_slot`` and ``_offset``. - * References Resolver: Report error instead of assertion fail when FunctionType has an undeclared type as parameter. - * References Resolver: Fix high CPU usage when using large variable names issue. Only suggest similar name if identifiers shorter than 80 characters. - * Type Checker: Default data location for type conversions (e.g. from literals) is memory and not storage. - * Type Checker: Disallow assignments to mappings within tuple assignments as well. - * Type Checker: Disallow packed encoding of arrays of structs. - * Type Checker: Allow assignments to local variables of mapping types. - * Type Checker: Consider fixed size arrays when checking for recursive structs. - * Type Checker: Fix crashes in erroneous tuple assignments in which the type of the right hand side cannot be determined. - * Type Checker: Fix freeze for negative fixed-point literals very close to ``0``, such as ``-1e-100``. - * Type Checker: Dynamic types as key for public mappings return error instead of assertion fail. - * Type Checker: Fix internal error when array index value is too large. - * Type Checker: Fix internal error when fixed-size array is too large to be encoded. - * Type Checker: Fix internal error for array type conversions. - * Type Checker: Fix internal error when array index is not an unsigned. - * Type System: Allow arbitrary exponents for literals with a mantissa of zero. - * Parser: Fix incorrect source location for nameless parameters. - * Command Line Interface: Fix internal error when compiling stdin with no content and --ast option. - - -### 0.4.26 (2019-04-29) - -Important Bugfixes: - * Code Generator: Fix initialization routine of uninitialized internal function pointers in constructor context. - * Type System: Use correct type name for contracts in event parameters when used in libraries. This affected code generation. - -Bugfixes: - * ABIEncoderV2: Refuse to generate code that is known to be potentially buggy. - * General: Split rule list such that JavaScript environments with small stacks can use the compiler. - -Note: The above changes are not included in 0.5.0, because they were backported. - - -### 0.4.25 (2018-09-12) - -Important Bugfixes: - * Code Generator: Properly perform cleanup for exponentiation and non-256 bit types. - * Type Checker: Report error when using indexed structs in events with experimental ABIEncoderV2. This used to log wrong values. - * Type Checker: Report error when using structs in events without experimental ABIEncoderV2. This used to crash or log the wrong values. - * Parser: Consider all unicode line terminators (LF, VF, FF, CR, NEL, LS, PS) for single-line comments - and string literals. They are invalid in strings and will end comments. - * Parser: Disallow unterminated multi-line comments at the end of input. - * Parser: Treat ``/** /`` as unterminated multi-line comment. - -### 0.4.24 (2018-05-16) - -Language Features: - * Code Generator: Use native shift instructions on target Constantinople. - * General: Allow multiple variables to be declared as part of a tuple assignment, e.g. ``(uint a, uint b) = ...``. - * General: Remove deprecated ``constant`` as function state modifier from documentation and tests (but still leave it as a valid feature). - * Type Checker: Deprecate the ``years`` unit denomination and raise a warning for it (or an error as experimental 0.5.0 feature). - * Type Checker: Make literals (without explicit type casting) an error for tight packing as experimental 0.5.0 feature. - * Type Checker: Warn about wildcard tuple assignments (this will turn into an error with version 0.5.0). - * Type Checker: Warn when ``keccak256``, ``sha256`` and ``ripemd160`` are not used with a single bytes argument (suggest to use ``abi.encodePacked(...)``). This will turn into an error with version 0.5.0. - -Compiler Features: - * Build System: Update internal dependency of jsoncpp to 1.8.4, which introduces more strictness and reduces memory usage. - * Control Flow Graph: Add Control Flow Graph as analysis structure. - * Control Flow Graph: Warn about returning uninitialized storage pointers. - * Gas Estimator: Only explore paths with higher gas costs. This reduces accuracy but greatly improves the speed of gas estimation. - * Optimizer: Remove unnecessary masking of the result of known short instructions (``ADDRESS``, ``CALLER``, ``ORIGIN`` and ``COINBASE``). - * Parser: Display nicer error messages by showing the actual tokens and not internal names. - * Parser: Use the entire location of the token instead of only its starting position as source location for parser errors. - * SMT Checker: Support state variables of integer and bool type. - -Bugfixes: - * Code Generator: Fix ``revert`` with reason coming from a state or local string variable. - * Type Checker: Show proper error when trying to ``emit`` a non-event. - * Type Checker: Warn about empty tuple components (this will turn into an error with version 0.5.0). - * Type Checker: The ABI encoding functions are pure and thus can be used for constants. - -### 0.4.23 (2018-04-19) - -Features: - * Build system: Support Ubuntu Bionic. - * SMTChecker: Integration with CVC4 SMT solver - * Syntax Checker: Warn about functions named "constructor". - -Bugfixes: - * Type Checker: Improve error message for failed function overload resolution. - * Type Checker: Do not complain about new-style constructor and fallback function to have the same name. - * Type Checker: Detect multiple constructor declarations in the new syntax and old syntax. - * Type Checker: Explicit conversion of ``bytesXX`` to ``contract`` is properly disallowed. - -### 0.4.22 (2018-04-16) - -Features: - * Code Generator: Initialize arrays without using ``msize()``. - * Code Generator: More specialized and thus optimized implementation for ``x.push(...)`` - * Commandline interface: Error when missing or inaccessible file detected. Suppress it with the ``--ignore-missing`` flag. - * Constant Evaluator: Fix evaluation of single element tuples. - * General: Add encoding routines ``abi.encodePacked``, ``abi.encode``, ``abi.encodeWithSelector`` and ``abi.encodeWithSignature``. - * General: Add global function ``gasleft()`` and deprecate ``msg.gas``. - * General: Add global function ``blockhash(uint)`` and deprecate ``block.hash(uint)``. - * General: Allow providing reason string for ``revert()`` and ``require()``. - * General: Introduce new constructor syntax using the ``constructor`` keyword as experimental 0.5.0 feature. - * General: Limit the number of errors output in a single run to 256. - * General: Support accessing dynamic return data in post-byzantium EVMs. - * General: Allow underscores in numeric and hex literals to separate thousands and quads. - * Inheritance: Error when using empty parentheses for base class constructors that require arguments as experimental 0.5.0 feature. - * Inheritance: Error when using no parentheses in modifier-style constructor calls as experimental 0.5.0 feature. - * Interfaces: Allow overriding external functions in interfaces with public in an implementing contract. - * Optimizer: Optimize ``SHL`` and ``SHR`` only involving constants (Constantinople only). - * Optimizer: Remove useless ``SWAP1`` instruction preceding a commutative instruction (such as ``ADD``, ``MUL``, etc). - * Optimizer: Replace comparison operators (``LT``, ``GT``, etc) with opposites if preceded by ``SWAP1``, e.g. ``SWAP1 LT`` is replaced with ``GT``. - * Optimizer: Optimize across ``mload`` if ``msize()`` is not used. - * Static Analyzer: Error on duplicated super constructor calls as experimental 0.5.0 feature. - * Syntax Checker: Issue warning for empty structs (or error as experimental 0.5.0 feature). - * Syntax Checker: Warn about modifiers on functions without implementation (this will turn into an error with version 0.5.0). - * Syntax Tests: Add source locations to syntax test expectations. - * Type Checker: Improve documentation and warnings for accessing contract members inherited from ``address``. - -Bugfixes: - * Code Generator: Allow ``block.blockhash`` without being called. - * Code Generator: Do not include internal functions in the runtime bytecode which are only referenced in the constructor. - * Code Generator: Properly skip unneeded storage array cleanup when not reducing length. - * Code Generator: Bugfix in modifier lookup in libraries. - * Code Generator: Implement packed encoding of external function types. - * Code Generator: Treat empty base constructor argument list as not provided. - * Code Generator: Properly force-clean bytesXX types for shortening conversions. - * Commandline interface: Fix error messages for imported files that do not exist. - * Commandline interface: Support ``--evm-version constantinople`` properly. - * DocString Parser: Fix error message for empty descriptions. - * Gas Estimator: Correctly ignore costs of fallback function for other functions. - * JSON AST: Remove storage qualifier for type name strings. - * Parser: Fix internal compiler error when parsing ``var`` declaration without identifier. - * Parser: Fix parsing of getters for function type variables. - * Standard JSON: Support ``constantinople`` as ``evmVersion`` properly. - * Static Analyzer: Fix non-deterministic order of unused variable warnings. - * Static Analyzer: Invalid arithmetic with constant expressions causes errors. - * Type Checker: Fix detection of recursive structs. - * Type Checker: Fix asymmetry bug when comparing with literal numbers. - * Type System: Improve error message when attempting to shift by a fractional amount. - * Type System: Make external library functions accessible. - * Type System: Prevent encoding of weird types. - * Type System: Restrict rational numbers to 4096 bits. - -### 0.4.21 (2018-03-07) - -Features: - * Code Generator: Assert that ``k != 0`` for ``mulmod(a, b, k)`` and ``addmod(a, b, k)`` as experimental 0.5.0 feature. - * Code Generator: Do not retain any gas in calls (except if EVM version is set to homestead). - * Code Generator: Use ``STATICCALL`` opcode for calling ``view`` and ``pure`` functions as experimental 0.5.0 feature. - * General: C99/C++-style scoping rules (instead of JavaScript function scoping) take effect as experimental v0.5.0 feature. - * General: Improved messaging when error spans multiple lines of a sourcefile - * General: Support and recommend using ``emit EventName();`` to call events explicitly. - * Inline Assembly: Enforce strict mode as experimental 0.5.0 feature. - * Interface: Provide ability to select target EVM version (homestead or byzantium, with byzantium being the default). - * Standard JSON: Reject badly formatted invalid JSON inputs. - * Type Checker: Disallow uninitialized storage pointers as experimental 0.5.0 feature. - * Syntax Analyser: Do not warn about experimental features if they do not concern code generation. - * Syntax Analyser: Do not warn about ``pragma experimental "v0.5.0"`` and do not set the experimental flag in the bytecode for this. - * Syntax Checker: Mark ``throw`` as an error as experimental 0.5.0 feature. - * Syntax Checker: Issue error if no visibility is specified on contract functions as experimental 0.5.0 feature. - * Syntax Checker: Issue warning when using overloads of ``address`` on contract instances. - * Type Checker: disallow combining hex numbers and unit denominations as experimental 0.5.0 feature. - -Bugfixes: - * Assembly: Raise error on oversized number literals in assembly. - * JSON-AST: Add "documentation" property to function, event and modifier definition. - * Resolver: Properly determine shadowing for imports with aliases. - * Standalone Assembly: Do not ignore input after closing brace of top level block. - * Standard JSON: Catch errors properly when invalid "sources" are passed. - * Standard JSON: Ensure that library addresses supplied are of correct length and hex prefixed. - * Type Checker: Properly detect which array and struct types are unsupported by the old ABI encoder. - * Type Checker: Properly warn when using ``_offset`` and ``_slot`` for constants in inline assembly. - * Commandline interface: throw error if option is unknown - -### 0.4.20 (2018-02-14) - -Features: - * Code Generator: Prevent non-view functions in libraries from being called - directly (as opposed to via delegatecall). - * Commandline interface: Support strict mode of assembly (disallowing jumps, - instructional opcodes, etc) with the ``--strict-assembly`` switch. - * Inline Assembly: Issue warning for using jump labels (already existed for jump instructions). - * Inline Assembly: Support some restricted tokens (return, byte, address) as identifiers in Iulia mode. - * Optimiser: Replace ``x % 2**i`` by ``x & (2**i-1)``. - * Resolver: Continue resolving references after the first error. - * Resolver: Suggest alternative identifiers if a given identifier is not found. - * SMT Checker: Take if-else branch conditions into account in the SMT encoding of the program - variables. - * Syntax Checker: Deprecate the ``var`` keyword (and mark it an error as experimental 0.5.0 feature). - * Type Checker: Allow `this.f.selector` to be a pure expression. - * Type Checker: Issue warning for using ``public`` visibility for interface functions. - * Type Checker: Limit the number of warnings raised for creating abstract contracts. - -Bugfixes: - * Error Output: Truncate huge number literals in the middle to avoid output blow-up. - * Parser: Disallow event declarations with no parameter list. - * Standard JSON: Populate the ``sourceLocation`` field in the error list. - * Standard JSON: Properly support contract and library file names containing a colon (such as URLs). - * Type Checker: Suggest the experimental ABI encoder if using ``struct``s as function parameters - (instead of an internal compiler error). - * Type Checker: Improve error message for wrong struct initialization. - -### 0.4.19 (2017-11-30) - -Features: - * Code Generator: New ABI decoder which supports structs and arbitrarily nested - arrays and checks input size (activate using ``pragma experimental ABIEncoderV2;``). - * General: Allow constant variables to be used as array length. - * Inline Assembly: ``if`` statement. - * Standard JSON: Support the ``outputSelection`` field for selective compilation of target artifacts. - * Syntax Checker: Turn the usage of ``callcode`` into an error as experimental 0.5.0 feature. - * Type Checker: Improve address checksum warning. - * Type Checker: More detailed errors for invalid array lengths (such as division by zero). - -Bugfixes: - -### 0.4.18 (2017-10-18) - -Features: - * Code Generator: Always use all available gas for calls as experimental 0.5.0 feature - (previously, some amount was retained in order to work in pre-Tangerine-Whistle - EVM versions) - * Parser: Better error message for unexpected trailing comma in parameter lists. - * Standard JSON: Support the ``outputSelection`` field for selective compilation of supplied sources. - * Syntax Checker: Unary ``+`` is now a syntax error as experimental 0.5.0 feature. - * Type Checker: Disallow non-pure constant state variables as experimental 0.5.0 feature. - * Type Checker: Do not add members of ``address`` to contracts as experimental 0.5.0 feature. - * Type Checker: Force interface functions to be external as experimental 0.5.0 feature. - * Type Checker: Require ``storage`` or ``memory`` keyword for local variables as experimental 0.5.0 feature. - * Compiler Interface: Better formatted error message for long source snippets - -Bugfixes: - * Code Generator: Allocate one byte per memory byte array element instead of 32. - * Code Generator: Do not accept data with less than four bytes (truncated function - signature) for regular function calls - fallback function is invoked instead. - * Optimizer: Remove unused stack computation results. - * Parser: Fix source location of VariableDeclarationStatement. - * Type Checker: Allow ``gas`` in view functions. - * Type Checker: Do not mark event parameters as shadowing state variables. - * Type Checker: Prevent duplicate event declarations. - * Type Checker: Properly check array length and don't rely on an assertion in code generation. - * Type Checker: Properly support overwriting members inherited from ``address`` in a contract - (such as ``balance``, ``transfer``, etc.) - * Type Checker: Validate each number literal in tuple expressions even if they are not assigned from. - -### 0.4.17 (2017-09-21) - -Features: - * Assembly Parser: Support multiple assignment (``x, y := f()``). - * Code Generator: Keep a single copy of encoding functions when using the experimental "ABIEncoderV2". - * Code Generator: Partial support for passing ``structs`` as arguments and return parameters (requires ``pragma experimental ABIEncoderV2;`` for now). - * General: Support ``pragma experimental "v0.5.0";`` to activate upcoming breaking changes. - * General: Added ``.selector`` member on external function types to retrieve their signature. - * Optimizer: Add new optimization step to remove unused ``JUMPDEST``s. - * Static Analyzer: Warn when using deprecated builtins ``sha3`` and ``suicide`` - (replaced by ``keccak256`` and ``selfdestruct``, introduced in 0.4.2 and 0.2.0, respectively). - * Syntax Checker: Warn if no visibility is specified on contract functions. - * Type Checker: Display helpful warning for unused function arguments/return parameters. - * Type Checker: Do not show the same error multiple times for events. - * Type Checker: Greatly reduce the number of duplicate errors shown for duplicate constructors and functions. - * Type Checker: Warn on using literals as tight packing parameters in ``keccak256``, ``sha3``, ``sha256`` and ``ripemd160``. - * Type Checker: Enforce ``view`` and ``pure``. - * Type Checker: Enforce ``view`` / ``constant`` with error as experimental 0.5.0 feature. - * Type Checker: Enforce fallback functions to be ``external`` as experimental 0.5.0 feature. - -Bugfixes: - * ABI JSON: Include all overloaded events. - * Parser: Crash fix related to parseTypeName. - * Type Checker: Allow constant byte arrays. - -### 0.4.16 (2017-08-24) - -Features: - * ABI JSON: Include new field ``stateMutability`` with values ``pure``, ``view``, - ``nonpayable`` and ``payable``. - * Analyzer: Experimental partial support for Z3 SMT checker ("SMTChecker"). - * Build System: Shared libraries (``libsolutil``, ``libevmasm``, ``libsolidity`` - and ``liblll``) are no longer produced during the build process. - * Code generator: Experimental new implementation of ABI encoder that can - encode arbitrarily nested arrays ("ABIEncoderV2") - * Metadata: Store experimental flag in metadata CBOR. - * Parser: Display previous visibility specifier in error if multiple are found. - * Parser: Introduce ``pure`` and ``view`` keyword for functions, - ``constant`` remains an alias for ``view`` and pureness is not enforced yet, - so use with care. - * Static Analyzer: Warn about large storage structures. - * Syntax Checker: Support ``pragma experimental ;`` to turn on - experimental features. - * Type Checker: More detailed error message for invalid overrides. - * Type Checker: Warn about shifting a literal. - -Bugfixes: - * Assembly Parser: Be more strict about number literals. - * Assembly Parser: Limit maximum recursion depth. - * Parser: Enforce commas between array and tuple elements. - * Parser: Limit maximum recursion depth. - * Type Checker: Crash fix related to ``using``. - * Type Checker: Disallow constructors in libraries. - * Type Checker: Reject the creation of interface contracts using the ``new`` statement. - -### 0.4.15 (2017-08-08) - -Features: - * Type Checker: Show unimplemented function if trying to instantiate an abstract class. - -Bugfixes: - * Code Generator: ``.delegatecall()`` should always return execution outcome. - * Code Generator: Provide "new account gas" for low-level ``callcode`` and ``delegatecall``. - * Type Checker: Constructors must be implemented if declared. - * Type Checker: Disallow the ``.gas()`` modifier on ``ecrecover``, ``sha256`` and ``ripemd160``. - * Type Checker: Do not mark overloaded functions as shadowing other functions. - * Type Checker: Internal library functions must be implemented if declared. - -### 0.4.14 (2017-07-31) - -Features: - * C API (``jsonCompiler``): Export the ``license`` method. - * Code Generator: Optimise the fallback function, by removing a useless jump. - * Inline Assembly: Show useful error message if trying to access calldata variables. - * Inline Assembly: Support variable declaration without initial value (defaults to 0). - * Metadata: Only include files which were used to compile the given contract. - * Type Checker: Disallow value transfers to contracts without a payable fallback function. - * Type Checker: Include types in explicit conversion error message. - * Type Checker: Raise proper error for arrays too large for ABI encoding. - * Type checker: Warn if using ``this`` in a constructor. - * Type checker: Warn when existing symbols, including builtins, are overwritten. - -Bugfixes: - * Code Generator: Properly clear return memory area for ecrecover. - * Type Checker: Fix crash for some assignment to non-lvalue. - * Type Checker: Fix invalid "specify storage keyword" warning for reference members of structs. - * Type Checker: Mark modifiers as internal. - * Type Checker: Re-allow multiple mentions of the same modifier per function. - - -### 0.4.13 (2017-07-06) - -Features: - * Syntax Checker: Deprecated "throw" in favour of require(), assert() and revert(). - * Type Checker: Warn if a local storage reference variable does not explicitly use the keyword ``storage``. - -Bugfixes: - * Code Generator: Correctly unregister modifier variables. - * Compiler Interface: Only output AST if analysis was successful. - * Error Output: Do not omit the error type. - -### 0.4.12 (2017-07-03) - -Features: - * Assembly: Add ``CREATE2`` (EIP86), ``STATICCALL`` (EIP214), ``RETURNDATASIZE`` and ``RETURNDATACOPY`` (EIP211) instructions. - * Assembly: Display auxiliary data in the assembly output. - * Assembly: Renamed ``SHA3`` to ``KECCAK256``. - * AST: export all attributes to JSON format. - * C API (``jsonCompiler``): Use the Standard JSON I/O internally. - * Code Generator: Added the Whiskers template system. - * Inline Assembly: ``for`` and ``switch`` statements. - * Inline Assembly: Function definitions and function calls. - * Inline Assembly: Introduce ``keccak256`` as an opcode. ``sha3`` is still a valid alias. - * Inline Assembly: Present proper error message when not supplying enough arguments to a functional - instruction. - * Inline Assembly: Warn when instructions shadow Solidity variables. - * Inline Assembly: Warn when using ``jump``s. - * Remove obsolete Why3 output. - * Type Checker: Enforce strict UTF-8 validation. - * Type Checker: Warn about copies in storage that might overwrite unexpectedly. - * Type Checker: Warn about type inference from literal numbers. - * Static Analyzer: Warn about deprecation of ``callcode``. - -Bugfixes: - * Assembly: mark ``MLOAD`` to have side effects in the optimiser. - * Code Generator: Fix ABI encoding of empty literal string. - * Code Generator: Fix negative stack size checks. - * Code generator: Use ``REVERT`` instead of ``INVALID`` for generated input validation routines. - * Inline Assembly: Enforce function arguments when parsing functional instructions. - * Optimizer: Disallow optimizations involving ``MLOAD`` because it changes ``MSIZE``. - * Static Analyzer: Unused variable warnings no longer issued for variables used inside inline assembly. - * Type Checker: Fix address literals not being treated as compile-time constants. - * Type Checker: Fixed crash concerning non-callable types. - * Type Checker: Fixed segfault with constant function parameters - * Type Checker: Disallow comparisons between mapping and non-internal function types. - * Type Checker: Disallow invoking the same modifier multiple times. - * Type Checker: Do not treat strings that look like addresses as addresses. - * Type Checker: Support valid, but incorrectly rejected UTF-8 sequences. - -### 0.4.11 (2017-05-03) - -Features: - * Implement the Standard JSON Input / Output API - * Support ``interface`` contracts. - * C API (``jsonCompiler``): Add the ``compileStandard()`` method to process a Standard JSON I/O. - * Commandline interface: Add the ``--standard-json`` parameter to process a Standard JSON I/O. - * Commandline interface: Support ``--allow-paths`` to define trusted import paths. Note: the - path(s) of the supplied source file(s) is always trusted. - * Inline Assembly: Storage variable access using ``_slot`` and ``_offset`` suffixes. - * Inline Assembly: Disallow blocks with unbalanced stack. - * Static analyzer: Warn about statements without effects. - * Static analyzer: Warn about unused local variables, parameters, and return parameters. - * Syntax checker: issue deprecation warning for unary '+' - -Bugfixes: - * Assembly output: Implement missing AssemblyItem types. - * Compiler interface: Fix a bug where source indexes could be inconsistent between Solidity compiled - with different compilers (clang vs. gcc) or compiler settings. The bug was visible in AST - and source mappings. - * Gas Estimator: Reflect the most recent fee schedule. - * Type system: Contract inheriting from base with unimplemented constructor should be abstract. - * Optimizer: Number representation bug in the constant optimizer fixed. - -### 0.4.10 (2017-03-15) - -Features: - * Add ``assert(condition)``, which throws if condition is false (meant for internal errors). - * Add ``require(condition)``, which throws if condition is false (meant for invalid input). - * Commandline interface: Do not overwrite files unless forced. - * Introduce ``.transfer(value)`` for sending Ether. - * Code generator: Support ``revert()`` to abort with rolling back, but not consuming all gas. - * Inline assembly: Support ``revert`` (EIP140) as an opcode. - * Parser: Support scientific notation in numbers (e.g. ``2e8`` and ``200e-2``). - * Type system: Support explicit conversion of external function to address. - * Type system: Warn if base of exponentiation is literal (result type might be unexpected). - * Type system: Warn if constant state variables are not compile-time constants. - -Bugfixes: - * Commandline interface: Always escape filenames (replace ``/``, ``:`` and ``.`` with ``_``). - * Commandline interface: Do not try creating paths ``.`` and ``..``. - * Commandline interface: Allow long library names. - * Parser: Disallow octal literals. - * Type system: Fix a crash caused by continuing on fatal errors in the code. - * Type system: Disallow compound assignment for tuples. - * Type system: Detect cyclic dependencies between constants. - * Type system: Disallow arrays with negative length. - * Type system: Fix a crash related to invalid binary operators. - * Type system: Disallow ``var`` declaration with empty tuple type. - * Type system: Correctly convert function argument types to pointers for member functions. - * Type system: Move privateness of constructor into AST itself. - * Inline assembly: Charge one stack slot for non-value types during analysis. - * Assembly output: Print source location before the operation it refers to instead of after. - * Optimizer: Stop trying to optimize tricky constants after a while. - -### 0.4.9 (2017-01-31) - -Features: - * Compiler interface: Contracts and libraries can be referenced with a ``file:`` prefix to make them unique. - * Compiler interface: Report source location for "stack too deep" errors. - * AST: Use deterministic node identifiers. - * Inline assembly: introduce ``invalid`` (EIP141) as an opcode. - * Type system: Introduce type identifier strings. - * Type checker: Warn about invalid checksum for addresses and deduce type from valid ones. - * Metadata: Do not include platform in the version number. - * Metadata: Add option to store sources as literal content. - * Code generator: Extract array utils into low-level functions. - * Code generator: Internal errors (array out of bounds, etc.) now cause a reversion by using an invalid - instruction (0xfe - EIP141) instead of an invalid jump. Invalid jump is still kept for explicit throws. - -Bugfixes: - * Code generator: Allow recursive structs. - * Inline assembly: Disallow variables named like opcodes. - * Type checker: Allow multiple events of the same name (but with different arities or argument types) - * Natspec parser: Fix error with ``@param`` parsing and whitespace. - -### 0.4.8 (2017-01-13) - -Features: - * Optimiser: Performance improvements. - * Output: Print assembly in new standardized Solidity assembly format. - -Bugfixes: - * Remappings: Prefer longer context over longer prefix. - * Type checker, code generator: enable access to events of base contracts' names. - * Imports: ``import ".dir/a"`` is not a relative path. Relative paths begin with directory ``.`` or ``..``. - * Type checker, disallow inheritances of different kinds (e.g. a function and a modifier) of members of the same name - -### 0.4.7 (2016-12-15) - -Features: - * Bitshift operators. - * Type checker: Warn when ``msg.value`` is used in non-payable function. - * Code generator: Inject the Swarm hash of a metadata file into the bytecode. - * Code generator: Replace expensive memcpy precompile by simple assembly loop. - * Optimizer: Some dead code elimination. - -Bugfixes: - * Code generator: throw if calling the identity precompile failed during memory (array) copying. - * Type checker: string literals that are not valid UTF-8 cannot be converted to string type - * Code generator: any non-zero value given as a boolean argument is now converted into 1. - * AST Json Converter: replace ``VariableDefinitionStatement`` nodes with ``VariableDeclarationStatement`` - * AST Json Converter: fix the camel case in ``ElementaryTypeNameExpression`` - * AST Json Converter: replace ``public`` field with ``visibility`` in the function definition nodes - -### 0.4.6 (2016-11-22) - -Bugfixes: - * Optimizer: Knowledge about state was not correctly cleared for JUMPDESTs (introduced in 0.4.5) - -### 0.4.5 (2016-11-21) - -Features: - * Function types - * Do-while loops: support for a ``do while ();`` control structure - * Inline assembly: support ``invalidJumpLabel`` as a jump label. - * Type checker: now more eagerly searches for a common type of an inline array with mixed types - * Code generator: generates a runtime error when an out-of-range value is converted into an enum type. - -Bugfixes: - - * Inline assembly: calculate stack height warning correctly even when local variables are used. - * Code generator: check for value transfer in non-payable constructors. - * Parser: disallow empty enum definitions. - * Type checker: disallow conversion between different enum types. - * Interface JSON: do not include trailing new line. - -### 0.4.4 (2016-10-31) - -Bugfixes: - * Type checker: forbid signed exponential that led to an incorrect use of EXP opcode. - * Code generator: properly clean higher order bytes before storing in storage. - -### 0.4.3 (2016-10-25) - -Features: - - * Inline assembly: support both ``suicide`` and ``selfdestruct`` opcodes - (note: ``suicide`` is deprecated). - * Inline assembly: issue warning if stack is not balanced after block. - * Include ``keccak256()`` as an alias to ``sha3()``. - * Support shifting constant numbers. - -Bugfixes: - * Commandline interface: Disallow unknown options in ``solc``. - * Name resolver: Allow inheritance of ``enum`` definitions. - * Type checker: Proper type checking for bound functions. - * Type checker: fixed crash related to invalid fixed point constants - * Type checker: fixed crash related to invalid literal numbers. - * Type checker: ``super.x`` does not look up ``x`` in the current contract. - * Code generator: expect zero stack increase after ``super`` as an expression. - * Code generator: fix an internal compiler error for ``L.Foo`` for ``enum Foo`` defined in library ``L``. - * Code generator: allow inheritance of ``enum`` definitions. - * Inline assembly: support the ``address`` opcode. - * Inline assembly: fix parsing of assignment after a label. - * Inline assembly: external variables of unsupported type (such as ``this``, ``super``, etc.) - are properly detected as unusable. - * Inline assembly: support variables within modifiers. - * Optimizer: fix related to stale knowledge about SHA3 operations - -### 0.4.2 (2016-09-17) - -Bugfixes: - - * Code Generator: Fix library functions being called from payable functions. - * Type Checker: Fixed a crash about invalid array types. - * Code Generator: Fixed a call gas bug that became visible after - version 0.4.0 for calls where the output is larger than the input. - -### 0.4.1 (2016-09-09) - - * Build System: Fixes to allow library compilation. - -### 0.4.0 (2016-09-08) - -This release deliberately breaks backwards compatibility mostly to -enforce some safety features. The most important change is that you have -to explicitly specify if functions can receive ether via the ``payable`` -modifier. Furthermore, more situations cause exceptions to be thrown. - -Minimal changes to be made for upgrade: - - Add ``payable`` to all functions that want to receive Ether - (including the constructor and the fallback function). - - Change ``_`` to ``_;`` in modifiers. - - Add version pragma to each file: ``pragma solidity ^0.4.0;`` - -Breaking Changes: - - * Source files have to specify the compiler version they are - compatible with using e.g. ``pragma solidity ^0.4.0;`` or - ``pragma solidity >=0.4.0 <0.4.8;`` - * Functions that want to receive Ether have to specify the - new ``payable`` modifier (otherwise they throw). - * Contracts that want to receive Ether with a plain "send" - have to implement a fallback function with the ``payable`` - modifier. Contracts now throw if no payable fallback - function is defined and no function matches the signature. - * Failing contract creation through "new" throws. - * Division / modulus by zero throws. - * Function call throws if target contract does not have code - * Modifiers are required to contain ``_`` (use ``if (false) _`` as a workaround if needed). - * Modifiers: return does not skip part in modifier after ``_``. - * Placeholder statement `_` in modifier now requires explicit `;`. - * ``ecrecover`` now returns zero if the input is malformed (it previously returned garbage). - * The ``constant`` keyword cannot be used for constructors or the fallback function. - * Removed ``--interface`` (Solidity interface) output option - * JSON AST: General cleanup, renamed many nodes to match their C++ names. - * JSON output: ``srcmap-runtime`` renamed to ``srcmapRuntime``. - * Moved (and reworked) standard library contracts from inside the compiler to github.com/ethereum/solidity/std - (``import "std";`` or ``import owned;`` do not work anymore). - * Confusing and undocumented keyword ``after`` was removed. - * New reserved words: ``abstract``, ``hex``, ``interface``, ``payable``, ``pure``, ``static``, ``view``. - -Features: - - * Hexadecimal string literals: ``hex"ab1248fe"`` - * Internal: Inline assembly usable by the code generator. - * Commandline interface: Using ``-`` as filename allows reading from stdin. - * Interface JSON: Fallback function is now part of the ABI. - * Interface: Version string now *SemVer* compatible. - * Code generator: Do not provide "new account gas" if we know the called account exists. - -Bugfixes: - - * JSON AST: Nodes were added at wrong parent - * Why3 translator: Crash fix for exponentiation - * Commandline Interface: linking libraries with underscores in their name. - * Type Checker: Fallback function cannot return data anymore. - * Code Generator: Fix crash when ``sha3()`` was used on unsupported types. - * Code Generator: Manually set gas stipend for ``.send(0)``. - -Lots of changes to the documentation mainly by voluntary external contributors. - -### 0.3.6 (2016-08-10) - -Features: - - * Formal verification: Take external effects on a contract into account. - * Type Checker: Warning about unused return value of low-level calls and send. - * Output: Source location and node id as part of AST output - * Output: Source location mappings for bytecode - * Output: Formal verification as part of json compiler output. - -Bugfixes: - - * Commandline Interface: Do not crash if input is taken from stdin. - * Scanner: Correctly support unicode escape codes in strings. - * JSON output: Fix error about relative / absolute source file names. - * JSON output: Fix error about invalid utf8 strings. - * Code Generator: Dynamic allocation of empty array caused infinite loop. - * Code Generator: Correctly calculate gas requirements for memcpy precompile. - * Optimizer: Clear known state if two code paths are joined. - -### 0.3.5 (2016-06-10) - -Features: - - * Context-dependent path remappings (different modules can use the same library in different versions) - -Bugfixes: - - * Type Checking: Dynamic return types were removed when fetching data from external calls, now they are replaced by an "unusable" type. - * Type Checking: Overrides by constructors were considered making a function non-abstract. - -### 0.3.4 (2016-05-31) - -No change outside documentation. - -### 0.3.3 (2016-05-27) - - * Allow internal library functions to be called (by "inlining") - * Fractional/rational constants (only usable with fixed point types, which are still in progress) - * Inline assembly has access to internal functions (as jump labels) - * Running `solc` without arguments on a terminal will print help. - * Bugfix: Remove some non-determinism in code generation. - * Bugfix: Corrected usage of not / bnot / iszero in inline assembly - * Bugfix: Correctly clean bytesNN types before comparison - -### 0.3.2 (2016-04-18) - - * Bugfix: Inline assembly parser: `byte` opcode was unusable - * Bugfix: Error reporting: tokens for variably-sized types were not converted to string properly - * Bugfix: Dynamic arrays of structs were not deleted correctly. - * Bugfix: Static arrays in constructor parameter list were not decoded correctly. - -### 0.3.1 (2016-03-31) - - * Inline assembly - * Bugfix: Code generation: array access with narrow types did not clean higher order bits - * Bugfix: Error reporting: error reporting with unknown source location caused a crash - -### 0.3.0 (2016-03-11) - -BREAKING CHANGES: - - * Added new keywords `assembly`, `foreign`, `fixed`, `ufixed`, `fixedNxM`, `ufixedNxM` (for various values of M and N), `timestamp` - * Number constant division does not round to integer, but to a fixed point type (e.g. `1 / 2 != 1`, but `1 / 2 == 0.5`). - * Library calls now default to use DELEGATECALL (e.g. called library functions see the same value as the calling function for `msg.value` and `msg.sender`). - * `
.delegatecall` as a low-level calling interface - -Bugfixes: - * Fixed a bug in the optimizer that resulted in comparisons being wrong. - - -### 0.2.2 (2016-02-17) - - * Index access for types `bytes1`, ..., `bytes32` (only read access for now). - * Bugfix: Type checker crash for wrong number of base constructor parameters. - -### 0.2.1 (2016-01-30) - - * Inline arrays, i.e. `var y = [1,x,f()];` if there is a common type for `1`, `x` and `f()`. Note that the result is always a fixed-length memory array and conversion to dynamic-length memory arrays is not yet possible. - * Import similar to ECMAScript6 import (`import "abc.sol" as d` and `import {x, y} from "abc.sol"`). - * Commandline compiler solc automatically resolves missing imports and allows for "include directories". - * Conditional: `x ? y : z` - * Bugfix: Fixed several bugs where the optimizer generated invalid code. - * Bugfix: Enums and structs were not accessible to other contracts. - * Bugfix: Fixed segfault connected to function parameter types, appeared during gas estimation. - * Bugfix: Type checker crash for wrong number of base constructor parameters. - * Bugfix: Allow function overloads with different array types. - * Bugfix: Allow assignments of type `(x) = 7`. - * Bugfix: Type `uint176` was not available. - * Bugfix: Fixed crash during type checking concerning constructor calls. - * Bugfix: Fixed crash during code generation concerning invalid accessors for struct types. - * Bugfix: Fixed crash during code generating concerning computing a hash of a struct type. - -### 0.2.0 (2015-12-02) - - * **Breaking Change**: `new ContractName.value(10)()` has to be written as `(new ContractName).value(10)()` - * Added `selfdestruct` as an alias for `suicide`. - * Allocation of memory arrays using `new`. - * Binding library functions to types via `using x for y` - * `addmod` and `mulmod` (modular addition and modular multiplication with arbitrary intermediate precision) - * Bugfix: Constructor arguments of fixed array type were not read correctly. - * Bugfix: Memory allocation of structs containing arrays or strings. - * Bugfix: Data location for explicit memory parameters in libraries was set to storage. - -### 0.1.7 (2015-11-17) - - * Improved error messages for unexpected tokens. - * Proof-of-concept transcompilation to why3 for formal verification of contracts. - * Bugfix: Arrays (also strings) as indexed parameters of events. - * Bugfix: Writing to elements of `bytes` or `string` overwrite others. - * Bugfix: "Successor block not found" on Windows. - * Bugfix: Using string literals in tuples. - * Bugfix: Cope with invalid commit hash in version for libraries. - * Bugfix: Some test framework fixes on windows. - -### 0.1.6 (2015-10-16) - - * `.push()` for dynamic storage arrays. - * Tuple expressions (`(1,2,3)` or `return (1,2,3);`) - * Declaration and assignment of multiple variables (`var (x,y,) = (1,2,3,4,5);` or `var (x,y) = f();`) - * Destructuring assignment (`(x,y,) = (1,2,3)`) - * Bugfix: Internal error about usage of library function with invalid types. - * Bugfix: Correctly parse `Library.structType a` at statement level. - * Bugfix: Correctly report source locations of parenthesized expressions (as part of "tuple" story). - -### 0.1.5 (2015-10-07) - - * Breaking change in storage encoding: Encode short byte arrays and strings together with their length in storage. - * Report warnings - * Allow storage reference types for public library functions. - * Access to types declared in other contracts and libraries via `.`. - * Version stamp at beginning of runtime bytecode of libraries. - * Bugfix: Problem with initialized string state variables and dynamic data in constructor. - * Bugfix: Resolve dependencies concerning `new` automatically. - * Bugfix: Allow four indexed arguments for anonymous events. - * Bugfix: Detect too large integer constants in functions that accept arbitrary parameters. - -### 0.1.4 (2015-09-30) - - * Bugfix: Returning fixed-size arrays. - * Bugfix: combined-json output of solc. - * Bugfix: Accessing fixed-size array return values. - * Bugfix: Disallow assignment from literal strings to storage pointers. - * Refactoring: Move type checking into its own module. - -### 0.1.3 (2015-09-25) - - * `throw` statement. - * Libraries that contain functions which are called via CALLCODE. - * Linker stage for compiler to insert other contract's addresses (used for libraries). - * Compiler option to output runtime part of contracts. - * Compile-time out of bounds check for access to fixed-size arrays by integer constants. - * Version string includes libevmasm/libethereum's version (contains the optimizer). - * Bugfix: Accessors for constant public state variables. - * Bugfix: Propagate exceptions in clone contracts. - * Bugfix: Empty single-line comments are now treated properly. - * Bugfix: Properly check the number of indexed arguments for events. - * Bugfix: Strings in struct constructors. - -### 0.1.2 (2015-08-20) - - * Improved commandline interface. - * Explicit conversion between `bytes` and `string`. - * Bugfix: Value transfer used in clone contracts. - * Bugfix: Problem with strings as mapping keys. - * Bugfix: Prevent usage of some operators. - -### 0.1.1 (2015-08-04) - - * Strings can be used as mapping keys. - * Clone contracts. - * Mapping members are skipped for structs in memory. - * Use only a single stack slot for storage references. - * Improved error message for wrong argument count. (#2456) - * Bugfix: Fix comparison between `bytesXX` types. (#2087) - * Bugfix: Do not allow floats for integer literals. (#2078) - * Bugfix: Some problem with many local variables. (#2478) - * Bugfix: Correctly initialise `string` and `bytes` state variables. - * Bugfix: Correctly compute gas requirements for callcode. - -### 0.1.0 (2015-07-10) diff --git a/README.md b/README.md index 6242a69f0b54..0b5fda4375cc 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,50 @@ -# The Solidity Contract-Oriented Programming Language +# é¢å‘åˆçº¦çš„Solidity编程语言 [![Matrix Chat](https://img.shields.io/badge/Matrix%20-chat-brightgreen?style=plastic&logo=matrix)](https://matrix.to/#/#ethereum_solidity:gitter.im) [![Gitter Chat](https://img.shields.io/badge/Gitter%20-chat-brightgreen?style=plastic&logo=gitter)](https://gitter.im/ethereum/solidity) -[![Solidity Forum](https://img.shields.io/badge/Solidity_Forum%20-discuss-brightgreen?style=plastic&logo=discourse)](https://forum.soliditylang.org/) +[![Solidity Forum](https://img.shields.io/badge/Solidity_Forum%20-discuss-brightgreen?style=plastic&logo=discourse)](https://forum.soliditylang.org/) [![Twitter Follow](https://img.shields.io/twitter/follow/solidity_lang?style=plastic&logo=twitter)](https://twitter.com/solidity_lang) [![Mastodon Follow](https://img.shields.io/mastodon/follow/000335908?domain=https%3A%2F%2Ffosstodon.org%2F&logo=mastodon&style=plastic)](https://fosstodon.org/@solidity) -You can talk to us on Gitter and Matrix, tweet at us on Twitter or create a new topic in the Solidity forum. Questions, feedback, and suggestions are welcome! +您å¯ä»¥åœ¨Gitterå’ŒMatrix上与我们交谈,在Twitter上å‘我们å‘推特,或者在Solidity论å›ä¸Šåˆ›å»ºä¸€ä¸ªæ–°çš„主题。 +我们欢迎一切问题,å馈和建议。 -Solidity is a statically typed, contract-oriented, high-level language for implementing smart contracts on the Ethereum platform. +Solidity是一ç§é™æ€ç±»åž‹çš„,é¢å‘åˆçº¦çš„高级语言,用于在Ethereumå¹³å°ä¸Šå®žçŽ°æ™ºèƒ½åˆçº¦ã€‚ -For a good overview and starting point, please check out the official [Solidity Language Portal](https://soliditylang.org). -## Table of Contents +为了获得一个好的概述和起点,请查看官方的 [Solidity语言门户](https://soliditylang.org)。 -- [Background](#background) -- [Build and Install](#build-and-install) -- [Example](#example) -- [Documentation](#documentation) -- [Development](#development) -- [Maintainers](#maintainers) -- [License](#license) -- [Security](#security) +## 目录 -## Background +- [背景介ç»](#背景介ç») +- [构建和安装](#构建和安装) +- [示例](#示例) +- [文档](#文档) +- [å‘展](#å‘展) +- [维护者](#维护者) +- [许å¯](#许å¯) +- [安全](#安全) -Solidity is a statically-typed curly-braces programming language designed for developing smart contracts -that run on the Ethereum Virtual Machine. Smart contracts are programs that are executed inside a peer-to-peer -network where nobody has special authority over the execution, and thus they allow anyone to implement tokens of value, -ownership, voting, and other kinds of logic. +## èƒŒæ™¯ä»‹ç» -When deploying contracts, you should use the latest released version of -Solidity. This is because breaking changes, as well as new features and bug fixes, are -introduced regularly. We currently use a 0.x version -number [to indicate this fast pace of change](https://semver.org/#spec-item-4). +Solidity是一ç§é™æ€ç±»åž‹çš„大括å·ç¼–程语言,用于开å‘在以太åŠè™šæ‹Ÿæœºä¸Šè¿è¡Œçš„智能åˆçº¦ã€‚ +智能åˆçº¦æ˜¯åœ¨ç‚¹å¯¹ç‚¹ç½‘络内执行的程åºï¼Œæ²¡æœ‰äººå¯¹æ‰§è¡Œæœ‰ç‰¹åˆ«çš„æƒé™ï¼Œ +因此它们å…许实现价值代å¸ï¼Œæ‰€æœ‰æƒï¼ŒæŠ•ç¥¨å’Œå…¶ä»–ç§ç±»çš„逻辑。 -## Build and Install +当部署åˆçº¦æ—¶ï¼Œæ‚¨åº”该使用最新å‘布的 Solidity 版本。 +这是因为é‡å¤§çš„å˜åŒ–,以åŠæ–°çš„功能和错误修å¤éƒ½æ˜¯å®šæœŸå¼•å…¥çš„。 +我们目å‰ä½¿ç”¨ 0.x ç‰ˆæœ¬å· [以表示这ç§å¿«é€Ÿå˜åŒ–的节å¥](https://semver.org/#spec-item-4)。 -Instructions about how to build and install the Solidity compiler can be -found in the [Solidity documentation](https://docs.soliditylang.org/en/latest/installing-solidity.html#building-from-source). +## 构建和安装 +关于如何构建和安装 Solidity 编译器的说明å¯ä»¥åœ¨ +[Solidity 文档](https://docs.soliditylang.org/en/latest/installing-solidity.html#building-from-source) +中找到。 -## Example -A "Hello World" program in Solidity is of even less use than in other languages, but still: +## 示例 + +在 Solidity 中的 “Hello World†程åºæ¯”其他语言更没有用处,但此处ä»ç„¶ä»¥æ­¤æ¥å±•ç¤ºï¼š ```solidity // SPDX-License-Identifier: MIT @@ -56,37 +57,36 @@ contract HelloWorld { } ``` -To get started with Solidity, you can use [Remix](https://remix.ethereum.org/), which is a -browser-based IDE. Here are some example contracts: +è¦å¼€å§‹ä½¿ç”¨ Solidity,您å¯ä»¥ä½¿ç”¨ [Remix](https://remix.ethereum.org/), +它是一个基于æµè§ˆå™¨çš„IDE。这里有一些åˆçº¦çš„例å­ï¼š + +1. [投票åˆçº¦](https://docs.soliditylang.org/en/latest/solidity-by-example.html#voting) +2. [盲æ‹åˆçº¦](https://docs.soliditylang.org/en/latest/solidity-by-example.html#blind-auction) +3. [安全的远程购买åˆçº¦](https://docs.soliditylang.org/en/latest/solidity-by-example.html#safe-remote-purchase) +4. [微支付通é“åˆçº¦](https://docs.soliditylang.org/en/latest/solidity-by-example.html#micropayment-channel) -1. [Voting](https://docs.soliditylang.org/en/latest/solidity-by-example.html#voting) -2. [Blind Auction](https://docs.soliditylang.org/en/latest/solidity-by-example.html#blind-auction) -3. [Safe remote purchase](https://docs.soliditylang.org/en/latest/solidity-by-example.html#safe-remote-purchase) -4. [Micropayment Channel](https://docs.soliditylang.org/en/latest/solidity-by-example.html#micropayment-channel) +## 文档 -## Documentation +Solidity 文档托管在 [阅读文档](https://docs.soliditylang.org) 。 -The Solidity documentation is hosted using [Read the Docs](https://docs.soliditylang.org). +## å‘展 -## Development +Solidity ä»åœ¨å¼€å‘中。我们éšæ—¶æ¬¢è¿Žæ‚¨çš„贡献! +如果您想æ供帮助,请éµå¾ª [å¼€å‘者指å—](https://docs.soliditylang.org/en/latest/contributing.html)。 -Solidity is still under development. Contributions are always welcome! -Please follow the -[Developers Guide](https://docs.soliditylang.org/en/latest/contributing.html) -if you want to help. +您å¯ä»¥åœ¨ [项目管ç†](https://github.com/ethereum/solidity/projects) +中找到我们目å‰å¯¹å³å°†å‘布的版本的功能和错误的优先级。 -You can find our current feature and bug priorities for forthcoming -releases in the [projects section](https://github.com/ethereum/solidity/projects). -## Maintainers -The Solidity programming language and compiler are open-source community projects governed by a core team. -The core team is sponsored by the [Ethereum Foundation](https://ethereum.foundation/). +## 维护者 +* [@axic](https://github.com/axic) +* [@chriseth](https://github.com/chriseth) -## License -Solidity is licensed under [GNU General Public License v3.0](LICENSE.txt). +## è®¸å¯ +Solidity 有 [GNU 通用公共许å¯è¯ v3.0](LICENSE.txt) 的许å¯ã€‚ -Some third-party code has its [own licensing terms](cmake/templates/license.h.in). +一些第三方代ç æœ‰å…¶ [自己的许å¯æ¡æ¬¾](cmake/templates/license.h.in)。 -## Security +## 安全 -The security policy may be [found here](SECURITY.md). +安全政策å¯ä»¥ [在这里找到](SECURITY.md)。 diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md deleted file mode 100644 index db07fb888555..000000000000 --- a/ReleaseChecklist.md +++ /dev/null @@ -1,117 +0,0 @@ -## Checklist for making a release: - -### Requirements - - [ ] GitHub account with access to [solidity](https://github.com/ethereum/solidity), [solc-js](https://github.com/ethereum/solc-js), - [solc-bin](https://github.com/ethereum/solc-bin), [homebrew-ethereum](https://github.com/ethereum/homebrew-ethereum), - [solidity-website](https://github.com/ethereum/solidity-website). - - [ ] DockerHub account with push rights to the [``solc`` image](https://hub.docker.com/r/ethereum/solc). - - [ ] Launchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and - a gnupg key for your email in the ``ethereum.org`` domain (has to be version 1, gpg2 won't work). - - [ ] Ubuntu/Debian dependencies of the PPA scripts: ``devscripts``, ``debhelper``, ``dput``, ``git``, ``wget``, ``ca-certificates``. - - [ ] [npm Registry](https://www.npmjs.com) account added as a collaborator for the [``solc`` package](https://www.npmjs.com/package/solc). - - [ ] Access to the [solidity_lang Twitter account](https://twitter.com/solidity_lang). - - [ ] [Reddit](https://www.reddit.com) account that is at least 10 days old with a minimum of 20 comment karma (``/r/ethereum`` requirements). - -### Pre-flight checks -At least a day before the release: - - [ ] Run ``make linkcheck`` from within ``docs/`` and fix any broken links it finds. - Ignore false positives caused by ``href`` anchors and dummy links not meant to work. - - [ ] Double-check that [the most recent docs builds at readthedocs](https://readthedocs.org/projects/solidity/builds/) succeeded. - - [ ] Make sure that all merged PRs that should have changelog entries do have them. - - [ ] Rerun CI on the top commits of main branches in all repositories that do not have daily activity by creating a test branch or PR: - - [ ] ``solc-js`` - - [ ] ``solc-bin`` (make sure the bytecode comparison check did run) - - [ ] ``homebrew-ethereum`` - - [ ] (Optional) Create a prerelease in our Ubuntu PPA by following the steps in the PPA section below on ``develop`` rather than on a tag. - This is recommended especially when dealing with PPA for the first time, when we add a new Ubuntu version or when the PPA scripts were modified in this release cycle. - - [ ] Verify that the release tarball of ``solc-js`` works. - Bump version locally, add ``soljson.js`` from CI, build it, compare the file structure with the previous version, install it locally and try to use it. - -### Drafts -At least a day before the release: - - [ ] Create a draft PR to sort the changelog. - - [ ] Create draft PRs to bump version in ``solidity`` and ``solc-js``. - - [ ] Create a draft of the release on github. - - [ ] Create a draft PR to update soliditylang.org. - - [ ] Create drafts of blog posts. - - [ ] Prepare drafts of Twitter, Reddit and Solidity Forum announcements. - -### Blog Post - - [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Releases`` category and explain some of the new features or concepts. - - [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Security Alerts`` category in case of important bug(s). - -### Changelog - - [ ] Sort the changelog entries alphabetically and correct any errors you notice. Commit it. - - [ ] Update the changelog to include a release date. - - [ ] Run ``scripts/update_bugs_by_version.py`` to regenerate ``bugs_by_version.json`` from the changelog and ``bugs.json``. - Make sure that the resulting ``bugs_by_version.json`` has a new, empty entry for the new version. - - [ ] Commit changes, create a pull request and wait for the tests. Then merge it. - - [ ] Copy the changelog into the release blog post. - -### Create the Release - - [ ] Create a [release on GitHub](https://github.com/ethereum/solidity/releases/new). - Set the target to the ``develop`` branch and the tag to the new version, e.g. ``v0.8.5``. - Include the following warning: ``**The release is still in progress and the binaries may not yet be available from all sources.**``. - Do not publish it yet - click the ``Save draft`` button instead. - - [ ] Thank voluntary contributors in the GitHub release notes. - Use ``scripts/list_contributors.sh v`` to get initial list of names. - Remove different variants of the same name manually before using the output. - - [ ] Check that all tests on the latest commit in ``develop`` are green. - - [ ] Click the ``Publish release`` button on the release page, creating the tag. - - [ ] Wait for the CI runs on the tag itself. - -### Upload Release Artifacts and Publish Binaries - - [ ] Switch to the tag that archives have to be created for. - - [ ] Create the ``prerelease.txt`` file: (``echo -n > prerelease.txt``). - - [ ] Run ``scripts/create_source_tarball.sh`` while being on the tag to create the source tarball. This will create the tarball in a directory called ``upload``. - - [ ] Take the tarball from the upload directory (its name should be ``solidity_x.x.x.tar.gz``, otherwise ``prerelease.txt`` was missing in the step before) and upload the source tarball to the release page. - - [ ] Take the ``github-binaries.tar`` tarball from ``c_release_binaries`` run of the tagged commit in circle-ci and add all binaries from it to the release page. - Make sure it contains four binaries: ``solc-windows.exe``, ``solc-macos``, ``solc-static-linux`` and ``soljson.js``. - - [ ] Take the ``solc-bin-binaries.tar`` tarball from ``c_release_binaries`` run of the tagged commit in circle-ci and add all binaries from it to solc-bin. - - [ ] Run ``npm run update -- --reuse-hashes`` in ``solc-bin`` and verify that the script has updated ``list.js``, ``list.txt`` and ``list.json`` files correctly and that symlinks to the new release have been added in ``solc-bin/wasm/`` and ``solc-bin/emscripten-wasm32/``. - - [ ] Create a pull request in solc-bin and merge. - -### Homebrew and MacOS - - [ ] Update the version and the hash (``sha256sum solidity_$VERSION.tar.gz``) in the [``solidity`` formula in Homebrew core repository](https://github.com/Homebrew/homebrew-core/blob/master/Formula/solidity.rb). - - [ ] Update the version and the hash (``sha256sum solidity_$VERSION.tar.gz``) in [our custom ``solidity`` Homebrew formula](https://github.com/ethereum/homebrew-ethereum/blob/master/solidity.rb). - -### Docker - - [ ] Run ``./scripts/docker_deploy_manual.sh v$VERSION``. - -### PPA - - [ ] Create ``.release_ppa_auth`` at the root of your local Solidity checkout and set ``LAUNCHPAD_EMAIL`` and ``LAUNCHPAD_KEYID`` to your key's email and key id. - - [ ] Double-check that the ``DISTRIBUTIONS`` list in ``scripts/release_ppa.sh`` and ``scripts/deps-ppa/static_z3.sh`` contains the most recent versions of Ubuntu. - - [ ] Make sure the [``~ethereum/cpp-build-deps`` PPA repository](https://launchpad.net/~ethereum/+archive/ubuntu/cpp-build-deps) contains ``libz3-static-dev builds`` for all current versions of Ubuntu. - Note that it may be included in the ``z3-static`` multipackage (follow the ``View package details`` link to check). - If not present, run ``scripts/deps-ppa/static_z3.sh`` and wait for the builds to succeed before continuing. - - [ ] Run ``scripts/release_ppa.sh v$VERSION`` to create the PPA release. - This will create a single package containing static binary for older Ubuntu versions in the [``~ethereum/ethereum-static`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-static) - and separate packages with dynamically-linked binaries for recent versions (those listed in ``DISTRIBUTIONS``) in the [``~ethereum/ethereum`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum). - - [ ] Wait for the build to be finished and published for *all architectures* (currently we only build for ``amd64``, but we may add ``arm`` in the future). - **SERIOUSLY: DO NOT PROCEED EARLIER!!!** - - [ ] *After* the package with the static build is *published*, use it to create packages for older Ubuntu versions. - Copy the static package to the [``~ethereum/ethereum`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum) - for the destination series ``Trusty``, ``Xenial`` and ``Bionic`` while selecting ``Copy existing binaries``. - -### Release solc-js - - [ ] Wait until solc-bin was properly deployed. You can test this via remix - a test run through remix is advisable anyway. - - [ ] Increment the version number, create a pull request for that, merge it after tests succeeded. - - [ ] Run ``npm run build:tarball`` in the updated ``solc-js`` repository to create ``solc-.tgz``. Inspect the tarball to ensure that it contains an up to date compiler binary. - - [ ] Run ``npm run publish:tarball`` to publish the newly created tarball. - - [ ] Create a tag using ``git tag --annotate v$VERSION`` and push it with ``git push --tags``. - -### Post-release - - [ ] Make sure the documentation for the new release has been published successfully. - Go to the [documentation status page at ReadTheDocs](https://readthedocs.org/projects/solidity/) and verify that the new version is listed, works and is marked as default. - - [ ] Remove "still in progress" warning from the [release notes](https://github.com/ethereum/solidity/releases). - - [ ] Merge the [blog posts](https://github.com/ethereum/solidity-website/pulls) related to the release. - - [ ] Create a commit to increase the version number on ``develop`` in ``CMakeLists.txt`` and add a new skeleton changelog entry. - - [ ] Update the release information section [in the source of soliditylang.org](https://github.com/ethereum/solidity-website/blob/main/src/pages/index.tsx). - - [ ] Announce on [Twitter](https://twitter.com/solidity_lang), including links to the release and the blog post. - - [ ] Announce on [Fosstodon](https://fosstodon.org/@solidity/), including links to the release and the blog post. - - [ ] Share the announcement on Reddit in [``/r/ethdev``](https://reddit.com/r/ethdev/), cross-posted to [``/r/ethereum``](https://reddit.com/r/ethereum/). - - [ ] Share the announcement on the [Solidity forum](https://forum.soliditylang.org) in the ``Announcements`` category. - - [ ] Share the announcement on [Project Updates](https://discord.com/channels/420394352083337236/798974456704925696) - - [ ] Share the announcement on [`#solidity` channel on Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im) - - [ ] Share the announcement on [`#solc-tooling`](https://matrix.to/#/#solc-tooling:matrix.org) - - [ ] Lean back, wait for bug reports and repeat from step 1 :). diff --git a/ReviewChecklist.md b/ReviewChecklist.md deleted file mode 100644 index 3f0af6f981d2..000000000000 --- a/ReviewChecklist.md +++ /dev/null @@ -1,200 +0,0 @@ -# PR Review Checklist -The Solidity compiler is a critical piece of infrastructure in the Ethereum ecosystem. -For this reason, our review process is quite strict and all PRs have to fulfill certain quality -expectations and guidelines. -The list below is meant to reduce the workload on the core team by helping contributors self-identify -and solve common issues before they are pointed out in the review. -It is also meant to serve as a final checklist for reviewers to go through before approving a PR. - -## Before You Submit a PR -- [ ] **Do you have any other open PRs?** - Work on a PR is not done until it is merged or closed. - Our reviewing capacity is limited, so we require that external contributors work on **no more than one PR at a time**. - - If your PR is not getting reviewed, feel free to bring it to our attention on the [#solidity-dev](https://gitter.im/ethereum/solidity-dev) channel. - - Unless they were requested, we are going to close any excess PRs, leaving only the earliest one open. - You may reopen them, one at a time, when your current PR is done. -- [ ] **Is the issue ready to be worked on?** - - If the issue does not have a desirability label (`nice to have`, `should have`, - `must have eventually`, `must have`, `roadmap`) we have not yet decided whether to implement it. - - If the issue has the `needs design` label, we have not yet decided how it should be implemented. - - `good first issue candidate` means that the issue will potentially be a `good first issue` - eventually but at the moment it is not yet ready to be worked on. -- [ ] **Is this a breaking change?** Breaking changes should be based on the `breaking` branch rather than on the `develop` branch. -- [ ] **Does the PR actually address the issue?** - - [ ] Mention the issue number in the PR description. - If the PR solves it completely, use the `Fixes #` form so that Github will close the issue automatically. - - [ ] Do not include the issue number in the PR title, branch name or commit description. -- [ ] When submitting a PR from a fork **create a branch and give it a descriptive name.** - E.g. `fix-array-abi-encoding-bug`. - Do not submit PRs directly from the `develop` branch of your fork since it makes rebasing and fetching new changes harder. -- [ ] **Does the PR depend on other PRs?** - - [ ] If the PR has dependencies, mention them in bold in the description. - - [ ] Avoid basing PRs from forks on branches other than `develop` or `breaking` because - GitHub closes them when the base branch gets merged. - Do this only for PRs created directly in the main repo. -- [ ] **Does the PR update test expectations to match the modified code?** If not, your PR will not pass some of the `_soltest_`, jobs in CI. - In many cases the expectations can be updated automatically: - - `cmdlineTests.sh --update` for command-line tests. - - `isoltest --enforce-gas-cost --accept-updates` for soltest-based tests. - - If your PR affects gas costs, an extra run of `isoltest --enforce-gas-cost --optimize --accept-updates` is needed to update gas expectations with optimizer enabled. - - Review updated files before committing them. - **Are expectations correct and do updated tests still serve their purpose?** - -## Abandoned PRs -- [ ] **Is the submitter still responsive?** - - If the PR had no activity from the submitter in the last 2 weeks (despite receiving reviews and our prompts) we consider it abandoned. -- [ ] **Is the abandoned PR easy to finish or relevant?** - - Apply the `takeover` label if the PR can be finished without significant effort or is something that actually needs to be done right now. - Otherwise close it. - It can still be taken over later or reopened by the submitter but until then we should not be getting sidetracked by it. - -## Light Review -Before an in-depth review, it is recommended to give new PRs a quick, superficial review, which -is not meant to provide complete and detailed feedback, but instead give the submitter a rough idea -if the PR is even on the right track and let them solve the obvious problems on their own. - -Light review should focus on the following three areas: -- [ ] **Are there any obvious mistakes?** Style issues, bad practices, easy to identify bugs, etc. -- [ ] **Is there anything missing?** Tests (of the right kind), documentation, etc. Does it address the whole issue? -- [ ] **Is it the right solution?** Are there better ways to do this? Is the change even necessary? - -If the answers above are "Yes, Yes, No", thank the contributor for their effort and **close the PR**. - -## Coding Style and Good Practices -- [ ] Does the PR follow our [coding style](CODING_STYLE.md)? - -### Reliability -- [ ] **Use assertions liberally.** If you are certain your assumption will not be broken, prove it with `solAssert()`. -- [ ] **Validate inputs and handle errors**. Note that assertions are **not** validation. - -### Readability -- [ ] **Choose good names.** - - [ ] Is the name straightforward to understand? - Do you feel the need to jump back to the definition and remind yourself what it was whenever you see it? - - [ ] Is the name unambiguous in the context where it is used? - - [ ] Avoid abbreviations. -- [ ] **Source files, classes and public functions should have docstrings.** -- [ ] **Avoid code duplication.** But not fanatically. Minimal amounts of duplication are acceptable if it aids readability. -- [ ] **Do not leave dead or commented-out code behind.** You can still see old code in history. - If you really have a good reason to do it, always leave a comment explaining what it is and why it is there. -- [ ] **Mark hacks as such.** If you have to leave behind a temporary workaround, make - sure to include a comment that explains why and in what circumstances it can be removed. - Preferably link to an issue you reported upstream. -- [ ] **Avoid obvious comments.** -- [ ] **Do include comments when the reader may need extra context to understand the code.** - -### Commits and PRs -- [ ] **Avoid hiding functional changes inside refactors.** - E.g. when fixing a small bug, or changing user-visible behavior, put the change in a separate commit. - Do not mix it with another change that renames things or reformats the code around, making the fix itself hard to identify. -- [ ] **Whenever possible, split off refactors or unrelated changes into separate PRs.** - Smaller PRs are easier and quicker to review. - Splitting off refactors helps focus on the main point of the PR. - -### Common Pitfalls -The following points are all covered by the coding style but come up so often that it is worth singling them out here: -- [ ] **Always initialize value types in the definition,** even if you are sure you will assign them later. -- [ ] **Use "east const" style.** I.e. `T const*`, not `const T *`. -- [ ] **Keep indentation consistent.** See our [`.editorconfig`](.editorconfig). - - [ ] Tabs for C++. But use them for indentation only. Any whitespace later on the line must consist of spaces. - - [ ] 4 spaces for most other file types. -- [ ] **Use `auto` sparingly.** Only use it when the actual type is very long and complicated or when it is - already used elsewhere in the same expression. -- [ ] **Indent braces and parentheses in a way that makes nesting clear.** -- [ ] **Use `using namespace` only in `.cpp` files.** Use it for `std` and our own modules. - Avoid unnecessary `std::` prefix in `.cpp` files (except for `std::move` and `std::forward`). -- [ ] **Use range-based loops and destructuring.** -- [ ] **Include any headers you use directly,** even if they are implicitly included through other headers. - -## Documentation -- [ ] **Does the PR update relevant documentation?** - -### Documentation Style and Good Practices -- [ ] **Use double backticks in RST (``` ``x`` ```). Prefer single backticks in Markdown (`` `x` ``),** - but note that double backticks are valid too and we use them in some cases for legacy reasons. -- [ ] **Always start a new sentence on a new line.** - This way you do not have to rewrap the surrounding text when you rewrite the sentence. - This also makes changes actually easier to spot in the diff. - -## Testing - -### What to Test -- [ ] **Is newly added code adequately covered by tests?** Have you considered all the important corner cases? -- If it is a bugfix: - - [ ] **The PR must include tests that reproduce the bug.** - - [ ] **Are there gaps in test coverage of the buggy feature?** Fill them by adding more tests. - - [ ] **Try to break it.** Can you of any similar features that could also be buggy? - Play with the repro and include prominent variants as separate test cases, even if they don't trigger a bug. -- [ ] **Positive cases (code that compiles) should have a semantic test.** -- [ ] **Negative cases (code with compilation errors) should have a syntax test.** -- [ ] **Avoid mixing positive and negative cases in the same syntax test.** - If the test produces an error, we stop at the analysis stage and we will not detect - problems that only occur in code generation, optimizer or assembler. - - [ ] If you have to do it, at least mark positive cases inside the file with a short comment. - - This way, when the test is updated, it is easier to verify that these cases still do not trigger an error. -- [ ] New syntax: **does it have an [`ASTJSON`](test/libsolidity/ASTJSON/) test?** -- [ ] New CLI or StandardJSON option: - - [ ] **Does it have a [command-line test](test/cmdlineTests/)?** - - [ ] **Is the option listed for every input mode in [`CommandLineParser` tests](test/solc/CommandLineParser.cpp)?** -- [ ] **Did you consider interactions with other language features?** - - [ ] Are all types covered? Structs? Enums? Contracts/libraries/interfaces? User-defined value types? - Value types: integers, fixed bytes, `address`, `address payable`, `bool`? Function pointers? - Static and dynamic arrays? `string` and `bytes`? Mappings? - Values of types that cannot be named: literals, tuples, array slices, storage references? - - [ ] If it accepts a function, does it also accept an event or an error? These have function types but are not functions. - - [ ] If it affects free functions, what about internal library functions? - - [ ] Attached library functions? Functions attached with `using for`? - - [ ] Possible combinations of `storage`, `memory`, `calldata`, `immutable`, `constant`? - Remember that internal functions can take `storage` arguments. - - [ ] Does it work at construction time as well? What if you store it at construction time and read after deployment? - - [ ] What about importing it from a different module or inheriting it? - - [ ] Have you tested it with the ternary operator? - -### Test Style and Good Practices -- [ ] **Make test case file names long and specific enough** so that it is easy to guess what is inside. - When checking if we have the case already covered the name is usually the only clue we see. - - [ ] Place them in the right subdirectory. - - [ ] **Avoid simply appending numbers to the name to distinguish similar cases.** - Coming up with good names is hard but figuring out if any of hundreds of tests with names that - match your search actually fits your case is even harder. -- [ ] **Do not include version pragma and the SPDX comment in semantic and syntax test cases**. - In other test types include them if necessary to suppress warnings. -- [ ] **If you have to use a version pragma, avoid hard-coding version.** Use `pragma solidity *`. -- [ ] **When writing StandardJSON command-line tests, use `urls` instead of `content`** and put - the Solidity or Yul code in a separate file. - -## Compiler-specific -- [ ] **Are error messages sensible and understandable to users?** -- [ ] **Are error codes consistent?** - - [ ] Avoid randomly changing or reassigning error codes. - - [ ] Avoid defining separate codes for trivial variants of the same issue. - Make it easy for tools to consistently refer to the same error with the same code. -- [ ] **Error messages should end with a full stop.** -- [ ] **Prefer Ranges v3 to Boost where possible.** - -## Take a Step Back -- [ ] **Do you fully understand what the PR does and why?** -- [ ] **Are you confident that the code works and does not break unrelated functionality?** -- [ ] **Is this a reasonable way to achieve the goal stated in the issue?** -- [ ] **Is the code simple?** Does the PR achieve its objective at the cost of significant - complexity that may be a source of future bugs? -- [ ] **Is the code efficient?** Does the PR introduce any major performance bottlenecks? -- [ ] **Does the PR introduce any breaking changes beyond what was agreed in the issue?** - -## Final Checks Before Merging -- [ ] **Is the PR rebased on top of the `develop` branch** (or `breaking` if it is a breaking change)? -- [ ] **Did all CI checks pass?** - - Note that we have a few jobs that tend to randomly fail due to outside factors, especially external tests (with `_ext_` in the name). - If these fail, rebase on latest `develop` (or `breaking`) and try rerunning them. - Note also that not all of these checks are required for the PR to be merged. -- [ ] If the change is visible to users, **does the PR have a [changelog](Changelog.md) entry?** - - [ ] Is the changelog entry in the right section? - Make sure to move it up if there was a release recently. -- [ ] **Is commit history simple and understandable?** - - [ ] Each commit should be a self-contained, logical step leading the goal of the PR, without going back and forth. - In particular, review fixups should be squashed into the commits they fix. - - [ ] Do not include any merge commits in your branch. Please use rebase to keep up to date with the base branch. -- [ ] **Is the PR properly labeled?** - - Use `external contribution` label to mark PRs not coming from the core team. - - If the PR depends on other PRs, use `has dependencies` and set the base branch accordingly. - - Labels like `documentation` or `optimizer` are helpful for filtering PRs. diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index d319b332f26f..000000000000 --- a/SECURITY.md +++ /dev/null @@ -1,52 +0,0 @@ -# Security Policy - -The Solidity team and community take all security bugs in Solidity seriously. -We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions. - -## Scope - -Bugs in the Solidity repository are in scope. -Bugs in third-party dependencies e.g., jsoncpp, boost etc. are not in scope unless they result in a Solidity specific bug. - -Only bugs that have a demonstrable security impact on smart contracts are in scope. -For example, a Solidity program whose optimization is incorrect (e.g., leads to an incorrect output) qualifies as a security bug. -Please note that the [rules][2] of the [Ethereum bounty program][1] have precedence over this security policy. - -## Supported Versions - -As a general rule, only the latest release gets security updates. -Exceptions may be made when the current breaking release is relatively new, e.g. less than three months old. -If you are reporting a bug, please state clearly the Solidity version(s) it affects. - -Example 1: Assuming the current release is `0.6.3` and a security bug has been found in it that affects both `0.5.x` and `0.6.x` trees, we may not only patch `0.6.3` (the bug-fix release numbered `0.6.4`) but `0.5.x` as well (the bug-fix release numbered `0.5.(x+1)`). - -Example 2: Assuming the current release is `0.6.25` and a security bug has been found in it, we may only patch `0.6.25` (in the bug-fix release numbered `0.6.26`) even if the bug affects a previous tree such as `0.5.x`. - -## Reporting a Vulnerability - -To report a vulnerability, please follow the instructions stated in the [Ethereum bounty program][1]. - -In the bug report, please include all details necessary to reproduce the vulnerability such as: - -- Input program that triggers the bug -- Compiler version affected -- Target EVM version -- Framework/IDE if applicable -- EVM execution environment/client if applicable -- Operating system - -Please include steps to reproduce the bug you have found in as much detail as possible. - -Once we have received your bug report, we will try to reproduce it and provide a more detailed response. -Once the reported bug has been successfully reproduced, the Solidity team will work on a fix. - -The Solidity team maintains the following JSON-formatted lists of patched security vulnerabilities: - -- [Summary of known security vulnerabilities][3] -- [List of security vulnerabilities affecting a specific version of the compiler][4]. - - -[1]: https://bounty.ethereum.org/ -[2]: https://bounty.ethereum.org/#rules -[3]: https://docs.soliditylang.org/en/develop/bugs.html -[4]: https://github.com/ethereum/solidity/blob/develop/docs/bugs_by_version.json diff --git a/cmake/EthBuildInfo.cmake b/cmake/EthBuildInfo.cmake deleted file mode 100644 index 1316a888cd53..000000000000 --- a/cmake/EthBuildInfo.cmake +++ /dev/null @@ -1,46 +0,0 @@ -function(create_build_info NAME) - - # Set build platform; to be written to BuildInfo.h - set(ETH_BUILD_OS "${CMAKE_SYSTEM_NAME}") - - if (CMAKE_COMPILER_IS_MINGW) - set(ETH_BUILD_COMPILER "mingw") - elseif (CMAKE_COMPILER_IS_MSYS) - set(ETH_BUILD_COMPILER "msys") - elseif (CMAKE_COMPILER_IS_GNUCXX) - set(ETH_BUILD_COMPILER "g++") - elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - set(ETH_BUILD_COMPILER "msvc") - elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(ETH_BUILD_COMPILER "clang") - elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") - set(ETH_BUILD_COMPILER "appleclang") - else () - set(ETH_BUILD_COMPILER "unknown") - endif () - - set(ETH_BUILD_PLATFORM "${ETH_BUILD_OS}.${ETH_BUILD_COMPILER}") - - #cmake build type may be not speCified when using msvc - if (CMAKE_BUILD_TYPE) - set(_cmake_build_type ${CMAKE_BUILD_TYPE}) - else() - set(_cmake_build_type "${CMAKE_CFG_INTDIR}") - endif() - - # Generate header file containing useful build information - add_custom_target(${NAME}_BuildInfo.h ALL - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMAND ${CMAKE_COMMAND} -DETH_SOURCE_DIR=${PROJECT_SOURCE_DIR} -DETH_BUILDINFO_IN=${ETH_CMAKE_DIR}/templates/BuildInfo.h.in -DETH_DST_DIR=${PROJECT_BINARY_DIR}/include/${PROJECT_NAME} -DETH_CMAKE_DIR=${ETH_CMAKE_DIR} - -DETH_BUILD_TYPE="${_cmake_build_type}" - -DETH_BUILD_OS="${ETH_BUILD_OS}" - -DETH_BUILD_COMPILER="${ETH_BUILD_COMPILER}" - -DETH_BUILD_PLATFORM="${ETH_BUILD_PLATFORM}" - -DPROJECT_VERSION="${PROJECT_VERSION}" - -DPROJECT_VERSION_MAJOR="${PROJECT_VERSION_MAJOR}" - -DPROJECT_VERSION_MINOR="${PROJECT_VERSION_MINOR}" - -DPROJECT_VERSION_PATCH="${PROJECT_VERSION_PATCH}" - -P "${ETH_SCRIPTS_DIR}/buildinfo.cmake" - ) - include_directories("${PROJECT_BINARY_DIR}/include") -endfunction() diff --git a/cmake/EthCcache.cmake b/cmake/EthCcache.cmake deleted file mode 100644 index 9410cbcde7f1..000000000000 --- a/cmake/EthCcache.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# Setup ccache. -# -# The ccache is auto-enabled if the tool is found. -# To disable set -DCCACHE=OFF option. -if(NOT DEFINED CMAKE_CXX_COMPILER_LAUNCHER) - find_program(CCACHE ccache DOC "ccache tool path; set to OFF to disable") - if(CCACHE) - set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE}) - if(COMMAND cotire) - # Change ccache config to meet cotire requirements. - set(ENV{CCACHE_SLOPPINESS} pch_defines,time_macros) - endif() - message(STATUS "[ccache] Enabled: ${CCACHE}") - endif() -endif() diff --git a/cmake/EthCheckCXXCompilerFlag.cmake b/cmake/EthCheckCXXCompilerFlag.cmake deleted file mode 100644 index 3e62885fe8ef..000000000000 --- a/cmake/EthCheckCXXCompilerFlag.cmake +++ /dev/null @@ -1,25 +0,0 @@ -include(CheckCXXCompilerFlag) - -# Adds CXX compiler flag if the flag is supported by the compiler. -# -# This is effectively a combination of CMake's check_cxx_compiler_flag() -# and add_compile_options(): -# -# if(check_cxx_compiler_flag(flag)) -# add_compile_options(flag) -# -function(eth_add_cxx_compiler_flag_if_supported FLAG) - # Remove leading - or / from the flag name. - string(REGEX REPLACE "^[-/]" "" name ${FLAG}) - # Deletes any ':' because it's invalid variable names. - string(REGEX REPLACE ":" "" name ${name}) - check_cxx_compiler_flag(${FLAG} ${name}) - if(${name}) - add_compile_options(${FLAG}) - endif() - - # If the optional argument passed, store the result there. - if(ARGV1) - set(${ARGV1} ${name} PARENT_SCOPE) - endif() -endfunction() diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake deleted file mode 100644 index 6cfa864c1d1a..000000000000 --- a/cmake/EthCompilerSettings.cmake +++ /dev/null @@ -1,279 +0,0 @@ -#------------------------------------------------------------------------------ -# EthCompilerSettings.cmake -# -# CMake file for cpp-ethereum project which specifies our compiler settings -# for each supported platform and build configuration. -# -# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org -# -# Copyright (c) 2014-2016 cpp-ethereum contributors. -#------------------------------------------------------------------------------ - -# Clang seeks to be command-line compatible with GCC as much as possible, so -# most of our compiler settings are common between GCC and Clang. -# -# These settings then end up spanning all POSIX platforms (Linux, OS X, BSD, etc) - -include(EthCheckCXXCompilerFlag) - -if(NOT EMSCRIPTEN) - eth_add_cxx_compiler_flag_if_supported(-fstack-protector-strong have_stack_protector_strong_support) - if(NOT have_stack_protector_strong_support) - eth_add_cxx_compiler_flag_if_supported(-fstack-protector) - endif() -endif() - -if(PEDANTIC) - eth_add_cxx_compiler_flag_if_supported(-Wimplicit-fallthrough) -endif() - -# Prevent the path of the source directory from ending up in the binary via __FILE__ macros. -eth_add_cxx_compiler_flag_if_supported("-fmacro-prefix-map=${PROJECT_SOURCE_DIR}=/solidity") - -# -Wpessimizing-move warns when a call to std::move would prevent copy elision -# if the argument was not wrapped in a call. This happens when moving a local -# variable in a return statement when the variable is the same type as the -# return type or using a move to create a new object from a temporary object. -if(PEDANTIC) - eth_add_cxx_compiler_flag_if_supported(-Wpessimizing-move) -endif() - -# -Wredundant-move warns when an implicit move would already be made, so the -# std::move call is not needed, such as when moving a local variable in a return -# that is different from the return type. -if(PEDANTIC) - eth_add_cxx_compiler_flag_if_supported(-Wredundant-move) -endif() - -if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) - # Enables all the warnings about constructions that some users consider questionable, - # and that are easy to avoid. Also enable some extra warning flags that are not - # enabled by -Wall. Finally, treat at warnings-as-errors, which forces developers - # to fix warnings as they arise, so they don't accumulate "to be fixed later". - if(PEDANTIC) - add_compile_options(-Wall) - add_compile_options(-Wextra) - add_compile_options(-Werror) - add_compile_options(-pedantic) - add_compile_options(-Wmissing-declarations) - add_compile_options(-Wno-unknown-pragmas) - add_compile_options(-Wimplicit-fallthrough) - add_compile_options(-Wsign-conversion) - add_compile_options(-Wconversion) - - check_cxx_compiler_flag(-Wextra-semi WEXTRA_SEMI) - if(WEXTRA_SEMI) - add_compile_options($<$:-Wextra-semi>) - endif() - # See https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=6b927b1297e66e26e62e722bf15c921dcbbd25b9 - check_cxx_compiler_flag(-Wno-dangling-reference WNO_DANGLING_REFERENCE) - if (WNO_DANGLING_REFERENCE) - add_compile_options($<$:-Wno-dangling-reference>) - endif() - - - eth_add_cxx_compiler_flag_if_supported(-Wfinal-dtor-non-final-class) - eth_add_cxx_compiler_flag_if_supported(-Wnewline-eof) - eth_add_cxx_compiler_flag_if_supported(-Wsuggest-destructor-override) - eth_add_cxx_compiler_flag_if_supported(-Wduplicated-cond) - eth_add_cxx_compiler_flag_if_supported(-Wduplicate-enum) - eth_add_cxx_compiler_flag_if_supported(-Wlogical-op) - eth_add_cxx_compiler_flag_if_supported(-Wno-unknown-attributes) - endif() - - # Configuration-specific compiler settings. - set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -DETH_DEBUG") - set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG") - set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g3") - - # Additional GCC-specific compiler settings. - if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") - # Check that we've got GCC 8.0 or newer. - if (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)) - message(FATAL_ERROR "${PROJECT_NAME} requires g++ 8.0 or greater.") - endif () - - # Use fancy colors in the compiler diagnostics - add_compile_options(-fdiagnostics-color) - - # Additional Clang-specific compiler settings. - elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - # Check that we've got clang 7.0 or newer. - if (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0)) - message(FATAL_ERROR "${PROJECT_NAME} requires clang++ 7.0 or greater.") - endif () - - if ("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin") - # Set stack size to 32MB - by default Apple's clang defines a stack size of 8MB. - # Normally 16MB is enough to run all tests, but it will exceed the stack, if -DSANITIZE=address is used. - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-stack_size -Wl,0x2000000") - - # Boost libraries use visibility=hidden to reduce unnecessary DWARF entries. - # Unless we match visibility, ld will give a warning message like: - # ld: warning: direct access in function 'boost::filesystem... from file ... - # means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") - endif() - - # Some Linux-specific Clang settings. We don't want these for OS X. - if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") - # Use fancy colors in the compiler diagnostics - add_compile_options(-fcolor-diagnostics) - - # See "How to silence unused command line argument error with clang without disabling it?" - # When using -Werror with clang, it transforms "warning: argument unused during compilation" messages - # into errors, which makes sense. - # http://stackoverflow.com/questions/21617158/how-to-silence-unused-command-line-argument-error-with-clang-without-disabling-i - add_compile_options(-Qunused-arguments) - elseif(EMSCRIPTEN) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --memory-init-file 0") - # Leave only exported symbols as public and aggressively remove others - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections -fvisibility=hidden") - # Optimisation level - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") - # Re-enable exception catching (optimisations above -O1 disable it) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0") - # Remove any code related to exit (such as atexit) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXIT_RUNTIME=0") - # Remove any code related to filesystem access - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s FILESYSTEM=0") - # Allow memory growth, but disable some optimisations - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1") - # Disable eval() - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DYNAMIC_EXECUTION=0") - # Disable greedy exception catcher - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s NODEJS_CATCH_EXIT=0") - # Abort if linking results in any undefined symbols - # Note: this is on by default in the CMake Emscripten module which we aren't using - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1") - # Disallow deprecated emscripten build options. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s STRICT=1") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s STRICT=1") - # Export the Emscripten-generated auxiliary methods which are needed by solc-js. - # Which methods of libsolc itself are exported is specified in libsolc/CMakeLists.txt. - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS=['cwrap','addFunction','removeFunction','UTF8ToString','lengthBytesUTF8','stringToUTF8','setValue']") - # Build for webassembly target. - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM=1") - # Set webassembly build to synchronous loading. - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM_ASYNC_COMPILATION=0") - # Allow new functions to be added to the wasm module via addFunction. - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_TABLE_GROWTH=1") - # Disable warnings about not being pure asm.js due to memory growth. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-almost-asm") - endif() - endif() - -# The major alternative compiler to GCC/Clang is Microsoft's Visual C++ compiler, only available on Windows. -elseif (DEFINED MSVC) - # Remove NDEBUG from RELWITHDEBINFO (to enable asserts) - # CMAKE_CXX_FLAGS_RELWITHDEBINFO for GCC/Clang does not include NDEBUG - string(REPLACE "/DNDEBUG" " " CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") - - add_compile_options(/MP) # enable parallel compilation - add_compile_options(/EHsc) # specify Exception Handling Model in msvc - if(PEDANTIC) - add_compile_options(/WX) # enable warnings-as-errors - endif() - add_compile_options(/wd4068) # disable unknown pragma warning (4068) - add_compile_options(/wd4996) # disable unsafe function warning (4996) - add_compile_options(/wd4503) # disable decorated name length exceeded, name was truncated (4503) - add_compile_options(/wd4267) # disable conversion from 'size_t' to 'type', possible loss of data (4267) - add_compile_options(/wd4180) # disable qualifier applied to function type has no meaning; ignored (4180) - add_compile_options(/wd4290) # disable C++ exception specification ignored except to indicate a function is not __declspec(nothrow) (4290) - add_compile_options(/wd4244) # disable conversion from 'type1' to 'type2', possible loss of data (4244) - add_compile_options(/wd4800) # disable forcing value to bool 'true' or 'false' (performance warning) (4800) - add_compile_options(-D_WIN32_WINNT=0x0600) # declare Windows Vista API requirement - add_compile_options(-DNOMINMAX) # undefine windows.h MAX && MIN macros cause it cause conflicts with std::min && std::max functions - add_compile_options(/utf-8) # enable utf-8 encoding (solves warning 4819) - add_compile_options(-DBOOST_REGEX_NO_LIB) # disable automatic boost::regex library selection - add_compile_options(-D_REGEX_MAX_STACK_COUNT=200000L) # increase std::regex recursion depth limit - add_compile_options(/permissive-) # specify standards conformance mode to the compiler - - # disable empty object file warning - set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") - # warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification - # warning LNK4099: pdb was not found with lib - # stack size 16MB - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099,4075 /STACK:16777216") - -# If you don't have GCC, Clang or VC++ then you are on your own. Good luck! -else () - message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.") -endif () - -if (SANITIZE) - # Perform case-insensitive string compare - string(TOLOWER "${SANITIZE}" sanitizer) - # -fno-omit-frame-pointer gives more informative stack trace in case of an error - # -fsanitize-address-use-after-scope throws an error when a variable is used beyond its scope - if (sanitizer STREQUAL "address") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize-address-use-after-scope") - elseif (sanitizer STREQUAL "undefined") - # The following flags not used by fuzzer but used by us may create problems, so consider - # disabling them: alignment, pointer-overflow. - # The following flag is not used by us to reduce terminal noise - # i.e., warnings printed on stderr: unsigned-integer-overflow - # Note: The C++ standard does not officially consider unsigned integer overflows - # to be undefined behavior since they are implementation independent. - # Flags are alphabetically sorted and are for clang v10.0 - list(APPEND undefinedSanitizerChecks - alignment - array-bounds - bool - builtin - enum - float-divide-by-zero - function - integer-divide-by-zero - null - object-size - pointer-overflow - return - returns-nonnull-attribute - shift - signed-integer-overflow - unreachable - vla-bound - vptr - ) - list(JOIN undefinedSanitizerChecks "," sanitizerChecks) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=${sanitizerChecks} -fno-sanitize-recover=${sanitizerChecks}") - endif() -endif() - -# Code coverage support. -# Copied from Cable: -# https://github.com/ethereum/cable/blob/v0.2.4/CableCompilerSettings.cmake#L118-L132 -option(COVERAGE "Build with code coverage support" OFF) -if(COVERAGE) - # Set the linker flags first, they are required to properly test the compiler flag. - set(CMAKE_SHARED_LINKER_FLAGS "--coverage ${CMAKE_SHARED_LINKER_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS "--coverage ${CMAKE_EXE_LINKER_FLAGS}") - - set(CMAKE_REQUIRED_LIBRARIES "--coverage ${CMAKE_REQUIRED_LIBRARIES}") - check_cxx_compiler_flag(--coverage have_coverage) - string(REPLACE "--coverage " "" CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) - if(NOT have_coverage) - message(FATAL_ERROR "Coverage not supported") - endif() - add_compile_options(-g --coverage) -endif() - -# SMT Solvers integration -option(USE_Z3 "Allow compiling with Z3 SMT solver integration" ON) -if(UNIX AND NOT APPLE) - option(USE_Z3_DLOPEN "Dynamically load the Z3 SMT solver instead of linking against it." OFF) -endif() -option(USE_CVC4 "Allow compiling with CVC4 SMT solver integration" ON) - -if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) - option(USE_LD_GOLD "Use GNU gold linker" ON) - if (USE_LD_GOLD) - execute_process(COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION) - if ("${LD_VERSION}" MATCHES "GNU gold") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold") - endif () - endif () -endif () diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake deleted file mode 100644 index 7a84a01d9868..000000000000 --- a/cmake/EthDependencies.cmake +++ /dev/null @@ -1,64 +0,0 @@ -# all dependencies that are not directly included in the cpp-ethereum distribution are defined here -# for this to work, download the dependency via the cmake script in extdep or install them manually! - -if (DEFINED MSVC) - # by defining CMAKE_PREFIX_PATH variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ... - # this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory - - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.0) - set (ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_LIST_DIR}/../extdep/install/windows/x64") - else() - get_filename_component(DEPS_DIR "${CMAKE_CURRENT_LIST_DIR}/../deps/install" ABSOLUTE) - set(ETH_DEPENDENCY_INSTALL_DIR - "${DEPS_DIR}/x64" # Old location for deps. - "${DEPS_DIR}/win64" # New location for deps. - "${DEPS_DIR}/win64/Release/share" # LLVM shared cmake files. - ) - endif() - set (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR} ${CMAKE_PREFIX_PATH}) -endif() - -# custom cmake scripts -set(ETH_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR}) -set(ETH_SCRIPTS_DIR ${ETH_CMAKE_DIR}/scripts) - -## use multithreaded boost libraries, with -mt suffix -set(Boost_USE_MULTITHREADED ON) -option(Boost_USE_STATIC_LIBS "Link Boost statically" ON) -if (WIN32) - option(Boost_USE_STATIC_RUNTIME "Link Boost against static C++ runtime libraries" ON) -endif() - -set(BOOST_COMPONENTS "filesystem;unit_test_framework;program_options;system") - -if (WIN32) - # Boost 1.77 fixes a bug that causes crashes on Windows for some relative paths in --allow-paths. - # See https://github.com/boostorg/filesystem/issues/201 - find_package(Boost 1.77.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS}) -else() - # Boost 1.65 is the first to also provide boost::get for rvalue-references (#5787). - find_package(Boost 1.65.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS}) -endif() - -# If cmake is older than boost and boost is older than 1.70, -# find_package does not define imported targets, so we have to -# define them manually. - -if (NOT TARGET Boost::boost) # header only target - add_library(Boost::boost INTERFACE IMPORTED) - set_property(TARGET Boost::boost APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIRS}) -endif() -get_property(LOCATION TARGET Boost::boost PROPERTY INTERFACE_INCLUDE_DIRECTORIES) -message(STATUS "Found Boost headers in ${LOCATION}") - -foreach (BOOST_COMPONENT IN LISTS BOOST_COMPONENTS) - if (NOT TARGET Boost::${BOOST_COMPONENT}) - add_library(Boost::${BOOST_COMPONENT} UNKNOWN IMPORTED) - string(TOUPPER ${BOOST_COMPONENT} BOOST_COMPONENT_UPPER) - set_property(TARGET Boost::${BOOST_COMPONENT} PROPERTY IMPORTED_LOCATION ${Boost_${BOOST_COMPONENT_UPPER}_LIBRARY}) - set_property(TARGET Boost::${BOOST_COMPONENT} PROPERTY INTERFACE_LINK_LIBRARIES ${Boost_${BOOST_COMPONENT_UPPER}_LIBRARIES}) - set_property(TARGET Boost::${BOOST_COMPONENT} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIRS}) - endif() - get_property(LOCATION TARGET Boost::${BOOST_COMPONENT} PROPERTY IMPORTED_LOCATION) - message(STATUS "Found Boost::${BOOST_COMPONENT} at ${LOCATION}") -endforeach() diff --git a/cmake/EthOptions.cmake b/cmake/EthOptions.cmake deleted file mode 100644 index cd6fe8133732..000000000000 --- a/cmake/EthOptions.cmake +++ /dev/null @@ -1,46 +0,0 @@ -# CMAKE macros to set default CMAKE options and to show the -# resulting configuration. - -macro(configure_project) - set(NAME ${PROJECT_NAME}) - - # features - eth_default_option(COVERAGE OFF) - eth_default_option(OSSFUZZ OFF) - - # components - eth_default_option(TESTS ON) - eth_default_option(TOOLS ON) - - # Define a matching property name of each of the "features". - foreach(FEATURE ${ARGN}) - set(SUPPORT_${FEATURE} TRUE) - endforeach() - - include(EthBuildInfo) - create_build_info(${NAME}) - print_config(${NAME}) -endmacro() - -macro(print_config NAME) - message("") - message("------------------------------------------------------------------------") - message("-- Configuring ${NAME} ${PROJECT_VERSION}") - message("------------------------------------------------------------------------") - message("-- CMake Version ${CMAKE_VERSION}") - message("-- CMAKE_BUILD_TYPE Build type ${CMAKE_BUILD_TYPE}") - message("-- TARGET_PLATFORM Target platform ${CMAKE_SYSTEM_NAME}") - message("--------------------------------------------------------------- features") - message("-- COVERAGE Coverage support ${COVERAGE}") - message("------------------------------------------------------------- components") -if (SUPPORT_TESTS) - message("-- TESTS Build tests ${TESTS}") -endif() -if (SUPPORT_TOOLS) - message("-- TOOLS Build tools ${TOOLS}") -endif() - message("------------------------------------------------------------------ flags") - message("-- OSSFUZZ ${OSSFUZZ}") - message("------------------------------------------------------------------------") - message("") -endmacro() diff --git a/cmake/EthPolicy.cmake b/cmake/EthPolicy.cmake deleted file mode 100644 index eb5c37e246f7..000000000000 --- a/cmake/EthPolicy.cmake +++ /dev/null @@ -1,35 +0,0 @@ -# it must be a macro cause policies have scopes -# http://www.cmake.org/cmake/help/v3.0/command/cmake_policy.html -macro (eth_policy) - # link_directories() treats paths relative to the source dir. - cmake_policy(SET CMP0015 NEW) - - # Avoid warnings in CMake 3.0.2: - cmake_policy(SET CMP0042 NEW) - cmake_policy(SET CMP0043 NEW) - - # allow VERSION argument in project() - cmake_policy(SET CMP0048 NEW) - - if (POLICY CMP0054) - # do not interpret if() arguments as variables! - cmake_policy(SET CMP0054 NEW) - endif() - - if (POLICY CMP0091) - # Allow selecting MSVC runtime library using CMAKE_MSVC_RUNTIME_LIBRARY. - cmake_policy(SET CMP0091 NEW) - endif() - - # Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24: - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") - cmake_policy(SET CMP0135 NEW) - endif() - - if(POLICY CMP0115) - # Require explicit extensions for source files, do not guess. - # The extra calls to GetFileAttributesW significantly slow down cmake on Windows. - # https://gitlab.kitware.com/cmake/cmake/-/issues/23154 - cmake_policy(SET CMP0115 NEW) - endif() -endmacro() diff --git a/cmake/EthToolchains.cmake b/cmake/EthToolchains.cmake deleted file mode 100644 index c2306bd75d11..000000000000 --- a/cmake/EthToolchains.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# Require C++17. -if (NOT DEFINED CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 17) # This requires at least CMake 3.8 to accept this C++17 flag. -endif () -set(CMAKE_CXX_STANDARD_REQUIRED TRUE) -set(CMAKE_CXX_EXTENSIONS OFF) - -if(NOT CMAKE_TOOLCHAIN_FILE) - # Use default toolchain file if none is provided. - set( - CMAKE_TOOLCHAIN_FILE - "${CMAKE_CURRENT_LIST_DIR}/toolchains/default.cmake" - CACHE FILEPATH "The CMake toolchain file" - ) -endif() diff --git a/cmake/EthUtils.cmake b/cmake/EthUtils.cmake deleted file mode 100644 index 44b92f4a0aa1..000000000000 --- a/cmake/EthUtils.cmake +++ /dev/null @@ -1,58 +0,0 @@ -# -# renames the file if it is different from its destination -include(CMakeParseArguments) -# -macro(replace_if_different SOURCE DST) - set(extra_macro_args ${ARGN}) - set(options CREATE) - set(one_value_args) - set(multi_value_args) - cmake_parse_arguments(REPLACE_IF_DIFFERENT "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") - - if (REPLACE_IF_DIFFERENT_CREATE AND (NOT (EXISTS "${DST}"))) - file(WRITE "${DST}" "") - endif() - - execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files "${SOURCE}" "${DST}" RESULT_VARIABLE DIFFERENT OUTPUT_QUIET ERROR_QUIET) - - if (DIFFERENT) - execute_process(COMMAND ${CMAKE_COMMAND} -E rename "${SOURCE}" "${DST}") - else() - execute_process(COMMAND ${CMAKE_COMMAND} -E remove "${SOURCE}") - endif() -endmacro() - -macro(eth_default_option O DEF) - if (DEFINED ${O}) - if (${${O}}) - set(${O} ON) - else () - set(${O} OFF) - endif() - else () - set(${O} ${DEF}) - endif() -endmacro() - -function(detect_stray_source_files FILELIST DIRECTORY) - if(CMAKE_VERSION VERSION_LESS 3.12) - file(GLOB sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${DIRECTORY}/*.cpp" "${DIRECTORY}/*.h") - else() - file(GLOB sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" CONFIGURE_DEPENDS "${DIRECTORY}/*.cpp" "${DIRECTORY}/*.h") - endif() - foreach(path IN LISTS FILELIST) - list(REMOVE_ITEM sources ${path}) - endforeach() - list(LENGTH sources leftover_sources) - if (leftover_sources) - message(SEND_ERROR "The following source files are present but are not compiled: ${sources}") - endif() -endfunction(detect_stray_source_files) - -# CreateExportedFunctionsForEMSDK(OUTPUT_VARIABLE Symbol1 Symbol2 ... SymbolN) -function(CreateExportedFunctionsForEMSDK OUTPUT_VARIABLE) - list(TRANSFORM ARGN PREPEND "\"_") - list(TRANSFORM ARGN APPEND "\"") - list(JOIN ARGN "," ARGN) - set(${OUTPUT_VARIABLE} "[${ARGN}]" PARENT_SCOPE) -endfunction() diff --git a/cmake/FindCLN.cmake b/cmake/FindCLN.cmake deleted file mode 100644 index 0b574ab9f7cb..000000000000 --- a/cmake/FindCLN.cmake +++ /dev/null @@ -1,8 +0,0 @@ -find_library(CLN_LIBRARY NAMES cln) -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(CLN DEFAULT_MSG CLN_LIBRARY) - -if(CLN_FOUND AND NOT TARGET CLN::CLN) - add_library(CLN::CLN UNKNOWN IMPORTED) - set_property(TARGET CLN::CLN PROPERTY IMPORTED_LOCATION ${CLN_LIBRARY}) -endif() diff --git a/cmake/FindCVC4.cmake b/cmake/FindCVC4.cmake deleted file mode 100644 index 887b907b8320..000000000000 --- a/cmake/FindCVC4.cmake +++ /dev/null @@ -1,33 +0,0 @@ -if (USE_CVC4) - find_path(CVC4_INCLUDE_DIR cvc4/cvc4.h) - find_library(CVC4_LIBRARY NAMES cvc4) - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(CVC4 DEFAULT_MSG CVC4_LIBRARY CVC4_INCLUDE_DIR) - if(CVC4_FOUND) - # CVC4 may depend on either CLN or GMP. - # We can assume that the one it requires is present on the system, - # so we quietly try to find both and link against them, if they are - # present. - find_package(CLN QUIET) - find_package(GMP QUIET) - - set(CVC4_LIBRARIES ${CVC4_LIBRARY}) - - if (CLN_FOUND) - set(CVC4_LIBRARIES ${CVC4_LIBRARIES} CLN::CLN) - endif () - - if (GMP_FOUND) - set(CVC4_LIBRARIES ${CVC4_LIBRARIES} GMP::GMP) - endif () - - if (NOT TARGET CVC4::CVC4) - add_library(CVC4::CVC4 UNKNOWN IMPORTED) - set_property(TARGET CVC4::CVC4 PROPERTY IMPORTED_LOCATION ${CVC4_LIBRARY}) - set_property(TARGET CVC4::CVC4 PROPERTY INTERFACE_LINK_LIBRARIES ${CVC4_LIBRARIES}) - set_property(TARGET CVC4::CVC4 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CVC4_INCLUDE_DIR}) - endif() - endif() -else() - set(CVC4_FOUND FALSE) -endif() diff --git a/cmake/FindGMP.cmake b/cmake/FindGMP.cmake deleted file mode 100644 index c3a0265429b8..000000000000 --- a/cmake/FindGMP.cmake +++ /dev/null @@ -1,8 +0,0 @@ -find_library(GMP_LIBRARY NAMES gmp) -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GMP DEFAULT_MSG GMP_LIBRARY) - -if(GMP_FOUND AND NOT TARGET GMP::GMP) - add_library(GMP::GMP UNKNOWN IMPORTED) - set_property(TARGET GMP::GMP PROPERTY IMPORTED_LOCATION ${GMP_LIBRARY}) -endif() diff --git a/cmake/FindZ3.cmake b/cmake/FindZ3.cmake deleted file mode 100644 index 092b8636b8e9..000000000000 --- a/cmake/FindZ3.cmake +++ /dev/null @@ -1,51 +0,0 @@ -if (USE_Z3) - # Save and clear Z3_FIND_VERSION, since the - # Z3 config module cannot handle version requirements. - set(Z3_FIND_VERSION_ORIG ${Z3_FIND_VERSION}) - set(Z3_FIND_VERSION) - # Try to find Z3 using its stock cmake files. - find_package(Z3 QUIET CONFIG) - # Restore Z3_FIND_VERSION for find_package_handle_standard_args. - set(Z3_FIND_VERSION ${Z3_FIND_VERSION_ORIG}) - set(Z3_FIND_VERSION_ORIG) - - include(FindPackageHandleStandardArgs) - - if (Z3_FOUND) - set(Z3_VERSION ${Z3_VERSION_STRING}) - find_package_handle_standard_args(Z3 CONFIG_MODE) - else() - find_path(Z3_INCLUDE_DIR NAMES z3++.h PATH_SUFFIXES z3) - find_library(Z3_LIBRARY NAMES z3) - find_program(Z3_EXECUTABLE z3 PATH_SUFFIXES bin) - - if(Z3_INCLUDE_DIR AND Z3_LIBRARY) - if(Z3_EXECUTABLE) - execute_process (COMMAND ${Z3_EXECUTABLE} -version - OUTPUT_VARIABLE libz3_version_str - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - - string(REGEX REPLACE "^Z3 version ([0-9.]+).*" "\\1" - Z3_VERSION_STRING "${libz3_version_str}") - unset(libz3_version_str) - else() - message(WARNING "Could not determine the version of z3, since the z3 executable was not found.") - set(Z3_VERSION_STRING "0.0.0") - endif() - endif() - mark_as_advanced(Z3_VERSION_STRING z3_DIR) - - find_package_handle_standard_args(Z3 - REQUIRED_VARS Z3_LIBRARY Z3_INCLUDE_DIR - VERSION_VAR Z3_VERSION_STRING) - - if (NOT TARGET z3::libz3) - add_library(z3::libz3 UNKNOWN IMPORTED) - set_property(TARGET z3::libz3 PROPERTY IMPORTED_LOCATION ${Z3_LIBRARY}) - set_property(TARGET z3::libz3 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Z3_INCLUDE_DIR}) - endif() - endif() -else() - set(Z3_FOUND FALSE) -endif() diff --git a/cmake/fmtlib.cmake b/cmake/fmtlib.cmake deleted file mode 100644 index 032a68cd52a0..000000000000 --- a/cmake/fmtlib.cmake +++ /dev/null @@ -1,20 +0,0 @@ -include(FetchContent) - -FetchContent_Declare( - fmtlib - PREFIX "${PROJECT_BINARY_DIR}/deps" - DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads" - DOWNLOAD_NAME fmt-9.1.0.tar.gz - URL https://github.com/fmtlib/fmt/archive/9.1.0.tar.gz - URL_HASH SHA256=5dea48d1fcddc3ec571ce2058e13910a0d4a6bab4cc09a809d8b1dd1c88ae6f2 -) - -if (CMAKE_VERSION VERSION_LESS "3.14.0") - FetchContent_GetProperties(fmtlib) - if (NOT fmtlib_POPULATED) - FetchContent_Populate(fmtlib) - add_subdirectory(${fmtlib_SOURCE_DIR} ${fmtlib_BINARY_DIR}) - endif() -else() - FetchContent_MakeAvailable(fmtlib) -endif() diff --git a/cmake/jsoncpp.cmake b/cmake/jsoncpp.cmake deleted file mode 100644 index cf1cc656b3b0..000000000000 --- a/cmake/jsoncpp.cmake +++ /dev/null @@ -1,70 +0,0 @@ -include(ExternalProject) - -if (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") - set(JSONCPP_CMAKE_COMMAND emcmake cmake) -else() - set(JSONCPP_CMAKE_COMMAND ${CMAKE_COMMAND}) -endif() - -set(prefix "${PROJECT_BINARY_DIR}/deps") -set(JSONCPP_LIBRARY "${prefix}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsoncpp${CMAKE_STATIC_LIBRARY_SUFFIX}") -set(JSONCPP_INCLUDE_DIR "${prefix}/include") - -# TODO: Investigate why this breaks some emscripten builds and -# check whether this can be removed after updating the emscripten -# versions used in the CI runs. -if(EMSCRIPTEN) - # Do not include all flags in CMAKE_CXX_FLAGS for emscripten, - # but only use -std=c++17. Using all flags causes build failures - # at the moment. - set(JSONCPP_CXX_FLAGS -std=c++17) -else() - # jsoncpp uses implicit casts for comparing integer and - # floating point numbers. This causes clang-10 (used by ossfuzz builder) - # to error on the implicit conversions. Here, we request jsoncpp - # to unconditionally use static casts for these conversions by defining the - # JSON_USE_INT64_DOUBLE_CONVERSION preprocessor macro. Doing so, - # not only gets rid of the implicit conversion error that clang-10 produces - # but also forces safer behavior in general. - set(JSONCPP_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DJSON_USE_INT64_DOUBLE_CONVERSION") -endif() - -set(byproducts "") -if(CMAKE_VERSION VERSION_GREATER 3.1) - set(byproducts BUILD_BYPRODUCTS "${JSONCPP_LIBRARY}") -endif() - -# Propagate CMAKE_MSVC_RUNTIME_LIBRARY on Windows builds, if set. -if (WIN32 AND POLICY CMP0091 AND CMAKE_MSVC_RUNTIME_LIBRARY) - list(APPEND JSONCPP_CMAKE_ARGS "-DCMAKE_POLICY_DEFAULT_CMP0091:STRING=NEW") - list(APPEND JSONCPP_CMAKE_ARGS "-DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}") -endif() - -ExternalProject_Add(jsoncpp-project - PREFIX "${prefix}" - DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads" - DOWNLOAD_NAME jsoncpp-1.9.3.tar.gz - URL https://github.com/open-source-parsers/jsoncpp/archive/1.9.3.tar.gz - URL_HASH SHA256=8593c1d69e703563d94d8c12244e2e18893eeb9a8a9f8aa3d09a327aa45c8f7d - CMAKE_COMMAND ${JSONCPP_CMAKE_COMMAND} - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_INSTALL_LIBDIR=lib - # Build static lib but suitable to be included in a shared lib. - -DCMAKE_POSITION_INDEPENDENT_CODE=${BUILD_SHARED_LIBS} - -DJSONCPP_WITH_EXAMPLE=OFF - -DJSONCPP_WITH_TESTS=OFF - -DJSONCPP_WITH_PKGCONFIG_SUPPORT=OFF - -DCMAKE_CXX_FLAGS=${JSONCPP_CXX_FLAGS} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - ${JSONCPP_CMAKE_ARGS} - ${byproducts} -) - -# Create jsoncpp imported library -add_library(jsoncpp STATIC IMPORTED) -file(MAKE_DIRECTORY ${JSONCPP_INCLUDE_DIR}) # Must exist. -set_property(TARGET jsoncpp PROPERTY IMPORTED_LOCATION ${JSONCPP_LIBRARY}) -set_property(TARGET jsoncpp PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${JSONCPP_INCLUDE_DIR}) -set_property(TARGET jsoncpp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${JSONCPP_INCLUDE_DIR}) -add_dependencies(jsoncpp jsoncpp-project) diff --git a/cmake/range-v3.cmake b/cmake/range-v3.cmake deleted file mode 100644 index d2f54452b319..000000000000 --- a/cmake/range-v3.cmake +++ /dev/null @@ -1,38 +0,0 @@ -include(ExternalProject) - -if (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") - set(RANGE_V3_CMAKE_COMMAND emcmake cmake) -else() - set(RANGE_V3_CMAKE_COMMAND ${CMAKE_COMMAND}) -endif() - -set(prefix "${PROJECT_BINARY_DIR}/deps") -set(RANGE_V3_INCLUDE_DIR "${prefix}/include") - -ExternalProject_Add(range-v3-project - PREFIX "${prefix}" - DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads" - DOWNLOAD_NAME range-v3-0.12.0.tar.gz - URL https://github.com/ericniebler/range-v3/archive/0.12.0.tar.gz - URL_HASH SHA256=015adb2300a98edfceaf0725beec3337f542af4915cec4d0b89fa0886f4ba9cb - CMAKE_COMMAND ${RANGE_V3_CMAKE_COMMAND} - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DBUILD_TESTING=OFF - -DRANGES_CXX_STD=${CMAKE_CXX_STANDARD} - -DRANGE_V3_DOCS=OFF - -DRANGE_V3_EXAMPLES=OFF - -DRANGE_V3_TESTS=OFF - -DRANGES_BUILD_CALENDAR_EXAMPLE=OFF - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - BUILD_BYPRODUCTS "${RANGE_V3_INCLUDE_DIR}/range/v3/all.hpp" -) - -# Create range-v3 imported library -add_library(range-v3 INTERFACE IMPORTED) -file(MAKE_DIRECTORY ${RANGE_V3_INCLUDE_DIR}) # Must exist. -set_target_properties(range-v3 PROPERTIES - INTERFACE_COMPILE_OPTIONS "\$<\$:/permissive->" - INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${RANGE_V3_INCLUDE_DIR} - INTERFACE_INCLUDE_DIRECTORIES ${RANGE_V3_INCLUDE_DIR}) -add_dependencies(range-v3 range-v3-project) diff --git a/cmake/scripts/buildinfo.cmake b/cmake/scripts/buildinfo.cmake deleted file mode 100644 index 3fb6beb2b787..000000000000 --- a/cmake/scripts/buildinfo.cmake +++ /dev/null @@ -1,74 +0,0 @@ -# generates BuildInfo.h -# -# this module expects -# ETH_SOURCE_DIR - main CMAKE_SOURCE_DIR -# ETH_DST_DIR - main CMAKE_BINARY_DIR -# ETH_BUILD_TYPE -# ETH_BUILD_PLATFORM -# -# example usage: -# cmake -DETH_SOURCE_DIR=. -DETH_DST_DIR=build -DETH_BUILD_TYPE=Debug -DETH_BUILD_PLATFORM=Darwin.appleclang -P scripts/buildinfo.cmake -# -# Its main output variables are SOL_VERSION_BUILDINFO and SOL_VERSION_PRERELEASE - -if (NOT ETH_BUILD_TYPE) - set(ETH_BUILD_TYPE "unknown") -endif() - -if (NOT ETH_BUILD_PLATFORM) - set(ETH_BUILD_PLATFORM "unknown") -endif() - -# Logic here: If prerelease.txt exists but is empty, it is a non-pre release. -# If it does not exist, create our own prerelease string -if (EXISTS ${ETH_SOURCE_DIR}/prerelease.txt) - file(READ ${ETH_SOURCE_DIR}/prerelease.txt SOL_VERSION_PRERELEASE) - string(STRIP "${SOL_VERSION_PRERELEASE}" SOL_VERSION_PRERELEASE) -else() - string(TIMESTAMP SOL_VERSION_PRERELEASE "develop.%Y.%m.%d" UTC) - string(REPLACE .0 . SOL_VERSION_PRERELEASE "${SOL_VERSION_PRERELEASE}") -endif() - -if (EXISTS ${ETH_SOURCE_DIR}/commit_hash.txt) - file(READ ${ETH_SOURCE_DIR}/commit_hash.txt SOL_COMMIT_HASH) - string(STRIP ${SOL_COMMIT_HASH} SOL_COMMIT_HASH) -else() - execute_process( - COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} rev-parse --short=8 HEAD - OUTPUT_VARIABLE SOL_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET - ) - execute_process( - COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} diff HEAD --shortstat - OUTPUT_VARIABLE SOL_LOCAL_CHANGES OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET - ) -endif() - -if (SOL_COMMIT_HASH) - string(STRIP ${SOL_COMMIT_HASH} SOL_COMMIT_HASH) - string(SUBSTRING ${SOL_COMMIT_HASH} 0 8 SOL_COMMIT_HASH) -endif() - -if (NOT SOL_COMMIT_HASH) - message(FATAL_ERROR "Unable to determine commit hash. Either compile from within git repository or " - "supply a file called commit_hash.txt") -endif() -if (NOT SOL_COMMIT_HASH MATCHES [a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]) - message(FATAL_ERROR "Malformed commit hash \"${SOL_COMMIT_HASH}\". It has to consist of exactly 8 hex digits.") -endif() - -if (SOL_COMMIT_HASH AND SOL_LOCAL_CHANGES) - set(SOL_COMMIT_HASH "${SOL_COMMIT_HASH}.mod") -endif() - -set(SOL_VERSION_COMMIT "commit.${SOL_COMMIT_HASH}") -set(SOl_VERSION_PLATFORM ETH_BUILD_PLATFORM) -set(SOL_VERSION_BUILDINFO "commit.${SOL_COMMIT_HASH}.${ETH_BUILD_PLATFORM}") - -set(TMPFILE "${ETH_DST_DIR}/BuildInfo.h.tmp") -set(OUTFILE "${ETH_DST_DIR}/BuildInfo.h") - -configure_file("${ETH_BUILDINFO_IN}" "${TMPFILE}") - -include("${ETH_CMAKE_DIR}/EthUtils.cmake") -replace_if_different("${TMPFILE}" "${OUTFILE}" CREATE) - diff --git a/cmake/templates/BuildInfo.h.in b/cmake/templates/BuildInfo.h.in deleted file mode 100644 index 9c295a85f0c7..000000000000 --- a/cmake/templates/BuildInfo.h.in +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#define ETH_PROJECT_VERSION "@PROJECT_VERSION@" -#define ETH_PROJECT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ -#define ETH_PROJECT_VERSION_MINOR @PROJECT_VERSION_MINOR@ -#define ETH_PROJECT_VERSION_PATCH @PROJECT_VERSION_PATCH@ -#define SOL_COMMIT_HASH "@SOL_COMMIT_HASH@" -#define ETH_BUILD_TYPE "@ETH_BUILD_TYPE@" -#define ETH_BUILD_OS "@ETH_BUILD_OS@" -#define ETH_BUILD_COMPILER "@ETH_BUILD_COMPILER@" -#define ETH_BUILD_PLATFORM "@ETH_BUILD_PLATFORM@" -#define SOL_VERSION_PRERELEASE "@SOL_VERSION_PRERELEASE@" -#define SOL_VERSION_BUILDINFO "@SOL_VERSION_BUILDINFO@" -#define SOL_VERSION_COMMIT "@SOL_VERSION_COMMIT@" -#define SOL_VERSION_PLATFORM "@SOL_VERSION_PLATFORM@" diff --git a/cmake/templates/license.h.in b/cmake/templates/license.h.in deleted file mode 100644 index 2d7f2691a81c..000000000000 --- a/cmake/templates/license.h.in +++ /dev/null @@ -1,177 +0,0 @@ -#pragma once - -#include - -static std::string const otherLicenses{R"(Most of the code is licensed under GPLv3 (see below), the license for individual -parts are as follows: - -libkeccak-tiny: - The file libsolutil/Keccak256.cpp incorporates libkeccak-tiny. - - A single-file implementation of SHA-3 and SHAKE implemented by David Leon Gil - License: CC0, attribution kindly requested. Blame taken too, but not liability. - -picosha2: - The file libsolutil/picosha2.h is imported. - - Copyright (C) 2017 okdshin - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - -jsoncpp: - The JsonCpp library's source code, including accompanying documentation, - tests and demonstration applications, are licensed under the following - conditions... - - The JsonCpp Authors explicitly disclaim copyright in all - jurisdictions which recognize such a disclaimer. In such jurisdictions, - this software is released into the Public Domain. - - In jurisdictions which do not recognize Public Domain property (e.g. Germany as of - 2010), this software is Copyright (c) 2007-2010 by The JsonCpp Authors, and is - released under the terms of the MIT License (see below). - - In jurisdictions which recognize Public Domain property, the user of this - software may choose to accept it either as 1) Public Domain, 2) under the - conditions of the MIT License (see below), or 3) under the terms of dual - Public Domain/MIT License conditions described here, as they choose. - - The MIT License is about as close to Public Domain as a license can get, and is - described in clear, concise terms at: - - http://en.wikipedia.org/wiki/MIT_License - - The full text of the MIT License follows: - - ======================================================================== - Copyright (c) 2007-2010 The JsonCpp Authors - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - ======================================================================== - (END LICENSE TEXT) - - The MIT license is compatible with both the GPL and commercial - software, affording one all of the rights of Public Domain with the - minor nuisance of being required to keep the above copyright notice - and license text in the source code. Note also that by accepting the - Public Domain "license" you can re-license your copy using whatever - license you like. - -scanner/token: - The liblangutil/{CharStream,Scanner,Token}.{h,cpp} files are derived from - code originating from the V8 project licensed under the following terms: - - Copyright 2006-2012, the V8 project authors. All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -evmc: - The code in test/evmc is licensed under the Apache License version 2: - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -mini-lz4: - The file scripts/ci/mini-lz4.js is derived from the emscripten adaptation of - node-lz4 and licensed under the following terms: - - Copyright (c) 2012 Pierre Curto - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - -base64: - The file scripts/ci/base64DecToArr.js is derived from a code example - in the MDN Web Docs, which permits use under CC0 terms: - - Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ - - -All other code is licensed under GPL version 3: - -)"}; - -static char const licenseText[] = { - @LICENSE_TEXT@, 0 -}; diff --git a/cmake/toolchains/default.cmake b/cmake/toolchains/default.cmake deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/cmake/toolchains/libfuzzer.cmake b/cmake/toolchains/libfuzzer.cmake deleted file mode 100644 index a734df975ec4..000000000000 --- a/cmake/toolchains/libfuzzer.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# Inherit default options -include("${CMAKE_CURRENT_LIST_DIR}/default.cmake") -# Enable Z3, disable CVC4 -set(USE_Z3 ON CACHE BOOL "Enable Z3" FORCE) -set(USE_CVC4 OFF CACHE BOOL "Disable CVC4" FORCE) -# Build fuzzing binaries -set(OSSFUZZ ON CACHE BOOL "Enable fuzzer build" FORCE) -# Use libfuzzer as the fuzzing back-end -set(LIB_FUZZING_ENGINE "-fsanitize=fuzzer" CACHE STRING "Use libfuzzer back-end" FORCE) -# clang/libfuzzer specific flags for UBSan instrumentation -set(CMAKE_CXX_FLAGS "-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -I /usr/local/include/c++/v1 -fsanitize=undefined -fsanitize=fuzzer-no-link -stdlib=libc++" CACHE STRING "Custom compilation flags" FORCE) -# Link statically against boost libraries -set(BOOST_FOUND ON CACHE BOOL "" FORCE) -set(Boost_USE_STATIC_LIBS ON CACHE BOOL "Link against static Boost libraries" FORCE) -set(Boost_USE_STATIC_RUNTIME ON CACHE BOOL "Link against static Boost runtime library" FORCE) diff --git a/cmake/toolchains/ossfuzz.cmake b/cmake/toolchains/ossfuzz.cmake deleted file mode 100644 index fb7b8d0b36cb..000000000000 --- a/cmake/toolchains/ossfuzz.cmake +++ /dev/null @@ -1,12 +0,0 @@ -# Inherit default options -include("${CMAKE_CURRENT_LIST_DIR}/default.cmake") -# Disable CVC4 and Z3. -set(USE_CVC4 OFF CACHE BOOL "Disable CVC4" FORCE) -set(USE_Z3 OFF CACHE BOOL "Disable Z3" FORCE) -# Enable fuzzers -set(OSSFUZZ ON CACHE BOOL "Enable fuzzer build" FORCE) -set(LIB_FUZZING_ENGINE $ENV{LIB_FUZZING_ENGINE} CACHE STRING "Use fuzzer back-end defined by environment variable" FORCE) -# Link statically against boost libraries -set(BOOST_FOUND ON CACHE BOOL "" FORCE) -set(Boost_USE_STATIC_LIBS ON CACHE BOOL "Link against static Boost libraries" FORCE) -set(Boost_USE_STATIC_RUNTIME ON CACHE BOOL "Link against static Boost runtime library" FORCE) diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index c0b72761e411..000000000000 --- a/codecov.yml +++ /dev/null @@ -1,22 +0,0 @@ -codecov: - branch: develop -coverage: - range: 70...100 - status: - patch: - default: - target: "50%" - paths: "!test/" - project: - default: - target: auto - paths: "!test/" - syntax: - target: auto - paths: "libsolidity/analysis" - flags: syntax - tests: - target: auto - paths: "test/" -comment: - layout: "reach, diff, flags" diff --git a/docs/050-breaking-changes.rst b/docs/050-breaking-changes.rst index a40bbcf6e9d8..e79aba14fd88 100644 --- a/docs/050-breaking-changes.rst +++ b/docs/050-breaking-changes.rst @@ -1,152 +1,142 @@ ******************************** -Solidity v0.5.0 Breaking Changes +Solidity v0.5.0 çªç ´æ€§å˜åŒ– ******************************** -This section highlights the main breaking changes introduced in Solidity -version 0.5.0, along with the reasoning behind the changes and how to update -affected code. -For the full list check -`the release changelog `_. +本节强调了 Solidity 0.5.0 版本中引入的主è¦çªç ´æ€§å˜åŒ–, +以åŠè¿™äº›å˜åŒ–背åŽçš„原因和如何更新å—å½±å“的代ç ã€‚ +对于完整的列表,请查看 `版本更新日志 `_。 .. note:: - Contracts compiled with Solidity v0.5.0 can still interface with contracts - and even libraries compiled with older versions without recompiling or - redeploying them. Changing the interfaces to include data locations and - visibility and mutability specifiers suffices. See the - :ref:`Interoperability With Older Contracts ` section below. + 用 Solidity v0.5.0 编译的åˆçº¦ä»ç„¶å¯ä»¥ä¸Žåˆçº¦ç”šè‡³ç”¨æ—§ç‰ˆæœ¬ç¼–译的库对接, + 而无需é‡æ–°ç¼–译或é‡æ–°éƒ¨ç½²ã€‚ + 将接å£æ›´æ”¹ä¸ºåŒ…å«æ•°æ®ä½ç½®ï¼Œå¯è§æ€§å’Œå¯å˜æ€§è¯´æ˜Žç¬¦å°±è¶³å¤Ÿäº†ã€‚ + å‚è§ä¸‹é¢çš„ :ref:`与旧åˆçº¦çš„互æ“作性 ` 部分。 -Semantic Only Changes +仅有语义上的å˜åŒ– ===================== -This section lists the changes that are semantic-only, thus potentially -hiding new and different behavior in existing code. +本节仅列出了语义的å˜åŒ–,因此有å¯èƒ½åœ¨çŽ°æœ‰ä»£ç ä¸­éšè—新的且ä¸åŒçš„行为。 -* Signed right shift now uses proper arithmetic shift, i.e. rounding towards - negative infinity, instead of rounding towards zero. Signed and unsigned - shift will have dedicated opcodes in Constantinople, and are emulated by - Solidity for the moment. +* 有符å·çš„å³ç§»çŽ°åœ¨ä½¿ç”¨æ­£ç¡®çš„算术移ä½ï¼Œå³å‘负无穷大å–整,而ä¸æ˜¯å‘零å–整。 + 有符å·å’Œæ— ç¬¦å·ç§»ä½åœ¨ å›å£«å¦ä¸å ¡ï¼ˆConstantinople)版本将有专门的æ“作ç ï¼Œ + ç›®å‰ç”±Solidity模拟。 -* The ``continue`` statement in a ``do...while`` loop now jumps to the - condition, which is the common behavior in such cases. It used to jump to the - loop body. Thus, if the condition is false, the loop terminates. +* 在 ``do...while`` 循环中的 ``continue`` 语å¥çŽ°åœ¨è·³è½¬åˆ°æ¡ä»¶ï¼Œè¿™æ˜¯åœ¨è¿™ç§æƒ…况下的常è§è¡Œä¸ºã€‚ + 以å‰æ˜¯è·³åˆ°å¾ªçŽ¯ä¸»ä½“。因此,如果æ¡ä»¶æ˜¯å‡çš„,循环就终止了。 -* The functions ``.call()``, ``.delegatecall()`` and ``.staticcall()`` do not - pad anymore when given a single ``bytes`` parameter. +* 函数 ``.call()``, ``.delegatecall()`` å’Œ ``.staticcall()`` 在给定一个 ``bytes`` å‚数时, + ä¸å†è¿›è¡Œå¡«å……。 -* Pure and view functions are now called using the opcode ``STATICCALL`` - instead of ``CALL`` if the EVM version is Byzantium or later. This - disallows state changes on the EVM level. +* 如果EVM的版本是 æ‹œå åº­ï¼ˆByzantium) 或更高版本, + 现在调用 pure å’Œ view 函数时使用æ“ä½œç  ``STATICCALL`` 而ä¸æ˜¯ ``CALL``。 + è¿™ä¸å…许在EVM层é¢ä¸Šæ”¹å˜çŠ¶æ€ã€‚ -* The ABI encoder now properly pads byte arrays and strings from calldata - (``msg.data`` and external function parameters) when used in external - function calls and in ``abi.encode``. For unpadded encoding, use - ``abi.encodePacked``. +* 当在外部函数调用和 ``abi.encode`` 中使用时, + ABIç¼–ç å™¨çŽ°åœ¨å¯ä»¥æ­£ç¡®åœ°å¯¹æ¥è‡ª calldata( ``msg.data`` 和外部函数å‚数)的字节数组和字符串进行填充。 + 对于未填充的编ç ï¼Œè¯·ä½¿ç”¨ ``abi.encodePacked``。 -* The ABI decoder reverts in the beginning of functions and in - ``abi.decode()`` if passed calldata is too short or points out of bounds. - Note that dirty higher order bits are still simply ignored. +* 如果传入的 calldata 太短或指å‘界外,ABI解ç å™¨ä¼šåœ¨å‡½æ•°çš„开头和 ``abi.decode()`` 中回退。 + 注æ„,è„的高阶ä½ä»ç„¶ä¼šè¢«å¿½ç•¥ã€‚ -* Forward all available gas with external function calls starting from - Tangerine Whistle. +* 从蜜桔å‰å“¨ï¼ˆTangerine Whistle)开始,用外部功能调用转å‘所有å¯ç”¨æ°”体。 -Semantic and Syntactic Changes +语义和语法的å˜åŒ– ============================== -This section highlights changes that affect syntax and semantics. - -* The functions ``.call()``, ``.delegatecall()``, ``staticcall()``, - ``keccak256()``, ``sha256()`` and ``ripemd160()`` now accept only a single - ``bytes`` argument. Moreover, the argument is not padded. This was changed to - make more explicit and clear how the arguments are concatenated. Change every - ``.call()`` (and family) to a ``.call("")`` and every ``.call(signature, a, - b, c)`` to use ``.call(abi.encodeWithSignature(signature, a, b, c))`` (the - last one only works for value types). Change every ``keccak256(a, b, c)`` to - ``keccak256(abi.encodePacked(a, b, c))``. Even though it is not a breaking - change, it is suggested that developers change - ``x.call(bytes4(keccak256("f(uint256)")), a, b)`` to - ``x.call(abi.encodeWithSignature("f(uint256)", a, b))``. - -* Functions ``.call()``, ``.delegatecall()`` and ``.staticcall()`` now return - ``(bool, bytes memory)`` to provide access to the return data. Change - ``bool success = otherContract.call("f")`` to ``(bool success, bytes memory - data) = otherContract.call("f")``. - -* Solidity now implements C99-style scoping rules for function local - variables, that is, variables can only be used after they have been - declared and only in the same or nested scopes. Variables declared in the - initialization block of a ``for`` loop are valid at any point inside the - loop. - -Explicitness Requirements -========================= +本节é‡ç‚¹ä»‹ç»å½±å“语法和语义的å˜åŒ–。 + +* 函数 ``.call()``, ``.delegatecall()``, ``staticcall()``, ``keccak256()``, ``sha256()`` + å’Œ ``ripemd160()`` 现在åªæŽ¥å—一个 ``bytes`` å‚数。此外,该å‚数没有被填充。 + 这样åšæ˜¯ä¸ºäº†ä½¿å‚数的连接方å¼æ›´åŠ æ˜Žç¡®å’Œæ¸…晰。 + å°†æ¯ä¸ª ``.call()`` (和家æ—)改为 ``.call("")``, + å°†æ¯ä¸ª ``.call(signature, a,b, c)`` 改为 ``.call(abi.encodeWithSignature(signature, a, b, c))`` + (最åŽä¸€é¡¹åªå¯¹å€¼ç±»åž‹æœ‰æ•ˆï¼‰ã€‚ + å°†æ¯ä¸ª ``keccak256(a, b, c)`` 改为 ``keccak256(abi.encodePacked(a, b, c))``。 + 尽管这ä¸æ˜¯ä¸€ä¸ªçªç ´æ€§çš„改å˜ï¼Œå»ºè®®å¼€å‘者将 ``x.call(bytes4(keccak256("f(uint256)")), a, b)`` + 改为 ``x.call(abi.encodeWithSignature("f(uint256)", a, b))``。 + +* 函数 ``.call()``, ``.delegatecall()`` å’Œ ``.staticcall()`` + 现在返回 ``(bool, bytes memory)`` 以æ供对返回数æ®çš„访问。 + å°† ``bool success = otherContract.call("f")`` 改为 + ``(bool success, bytes memory data) = otherContract.call("f")``。 -This section lists changes where the code now needs to be more explicit. -For most of the topics the compiler will provide suggestions. - -* Explicit function visibility is now mandatory. Add ``public`` to every - function and constructor, and ``external`` to every fallback or interface - function that does not specify its visibility already. - -* Explicit data location for all variables of struct, array or mapping types is - now mandatory. This is also applied to function parameters and return - variables. For example, change ``uint[] x = z`` to ``uint[] storage x = - z``, and ``function f(uint[][] x)`` to ``function f(uint[][] memory x)`` - where ``memory`` is the data location and might be replaced by ``storage`` or - ``calldata`` accordingly. Note that ``external`` functions require - parameters with a data location of ``calldata``. - -* Contract types do not include ``address`` members anymore in - order to separate the namespaces. Therefore, it is now necessary to - explicitly convert values of contract type to addresses before using an - ``address`` member. Example: if ``c`` is a contract, change - ``c.transfer(...)`` to ``address(c).transfer(...)``, - and ``c.balance`` to ``address(c).balance``. - -* Explicit conversions between unrelated contract types are now disallowed. You can only - convert from a contract type to one of its base or ancestor types. If you are sure that - a contract is compatible with the contract type you want to convert to, although it does not - inherit from it, you can work around this by converting to ``address`` first. - Example: if ``A`` and ``B`` are contract types, ``B`` does not inherit from ``A`` and - ``b`` is a contract of type ``B``, you can still convert ``b`` to type ``A`` using ``A(address(b))``. - Note that you still need to watch out for matching payable fallback functions, as explained below. - -* The ``address`` type was split into ``address`` and ``address payable``, - where only ``address payable`` provides the ``transfer`` function. An - ``address payable`` can be directly converted to an ``address``, but the - other way around is not allowed. Converting ``address`` to ``address - payable`` is possible via conversion through ``uint160``. If ``c`` is a - contract, ``address(c)`` results in ``address payable`` only if ``c`` has a - payable fallback function. If you use the :ref:`withdraw pattern`, - you most likely do not have to change your code because ``transfer`` - is only used on ``msg.sender`` instead of stored addresses and ``msg.sender`` - is an ``address payable``. - -* Conversions between ``bytesX`` and ``uintY`` of different size are now - disallowed due to ``bytesX`` padding on the right and ``uintY`` padding on - the left which may cause unexpected conversion results. The size must now be - adjusted within the type before the conversion. For example, you can convert - a ``bytes4`` (4 bytes) to a ``uint64`` (8 bytes) by first converting the - ``bytes4`` variable to ``bytes8`` and then to ``uint64``. You get the - opposite padding when converting through ``uint32``. Before v0.5.0 any - conversion between ``bytesX`` and ``uintY`` would go through ``uint8X``. For - example ``uint8(bytes3(0x291807))`` would be converted to ``uint8(uint24(bytes3(0x291807)))`` - (the result is ``0x07``). - -* Using ``msg.value`` in non-payable functions (or introducing it via a - modifier) is disallowed as a security feature. Turn the function into - ``payable`` or create a new internal function for the program logic that - uses ``msg.value``. +* Solidity 现在为函数局部å˜é‡å®žçŽ°äº†C99风格的范围规则, + 也就是说,å˜é‡åªèƒ½åœ¨å®ƒä»¬è¢«å£°æ˜ŽåŽä½¿ç”¨ï¼Œå¹¶ä¸”åªèƒ½åœ¨ç›¸åŒæˆ–嵌套的范围内使用。 + 在 ``for`` 循环的åˆå§‹åŒ–å—中声明的å˜é‡åœ¨å¾ªçŽ¯å†…部的任何一点都是有效的。 +明确性è¦æ±‚ +========================= + +本节列出了现在的代ç éœ€è¦æ›´åŠ æ˜Žç¡®çš„å˜åŒ–。 +对于大多数的主题,编译器会æ供建议。 + +* 明确的函数å¯è§æ€§çŽ°åœ¨æ˜¯å¼ºåˆ¶æ€§çš„。 在æ¯ä¸ªå‡½æ•°å’Œæž„造函数中添加 ``public``, + 在æ¯ä¸ªæœªæŒ‡å®šå¯è§æ€§çš„回退或接å£å‡½æ•°ä¸­æ·»åŠ  ``external``。 + +* 所有结构,数组或映射类型的å˜é‡çš„明确数æ®ä½ç½®çŽ°åœ¨æ˜¯å¼ºåˆ¶æ€§çš„。 + 这也适用于函数å‚数和返回å˜é‡ã€‚ 例如,将 ``uint[] x = z`` 改为 ``uint[] storage x = z``, + å°† ``function f(uint[] [] x)`` 改为 ``function f(uint[] [] memory x)``, + 其中 ``memory`` 是数æ®ä½ç½®ï¼Œå¯ä»¥ç›¸åº”地替æ¢ä¸º ``storage`` 或 ``calldata``。 + 注æ„, ``external`` 函数è¦æ±‚å‚æ•°çš„æ•°æ®ä½ç½®ä¸º ``calldata``。 + +* åˆçº¦ç±»åž‹ä¸å†åŒ…括 ``address`` æˆå‘˜ï¼Œä»¥ä¾¿åˆ†ç¦»å‘½å空间。 + 因此,现在有必è¦åœ¨ä½¿ç”¨ ``address`` æˆå‘˜ä¹‹å‰ï¼Œæ˜Žç¡®åœ°å°†åˆçº¦ç±»åž‹çš„值转æ¢ä¸ºåœ°å€ã€‚ + 例如:如果 ``c`` 是一个åˆçº¦ï¼ŒæŠŠ ``c.transfer(...)`` 改为 ``address(c).transfer(...)``, + 把 ``c.balance`` 改为 ``address(c).balance``。 + +* 现在ä¸å…许在ä¸ç›¸å…³çš„åˆçº¦ç±»åž‹ä¹‹é—´è¿›è¡Œæ˜¾å¼çš„转æ¢ã€‚您åªèƒ½ä»Žä¸€ä¸ªåˆçº¦ç±»åž‹è½¬æ¢åˆ°å®ƒçš„一个基础或祖先类型。 + 如果您确定一个åˆçº¦ä¸Žæ‚¨æƒ³è½¬æ¢çš„åˆçº¦ç±»åž‹æ˜¯å…¼å®¹çš„,尽管它没有继承它, + 您å¯ä»¥é€šè¿‡å…ˆè½¬æ¢ä¸º ``address`` æ¥è§£å†³è¿™ä¸ªé—®é¢˜ã€‚ + 例如:如果 ``A`` å’Œ ``B`` 是åˆçº¦ç±»åž‹ï¼Œ ``B`` ä¸ç»§æ‰¿ ``A``,而 ``b`` 是 ``B`` 类型的åˆçº¦ï¼Œ + 您ä»ç„¶å¯ä»¥ç”¨ ``A(address(b))`` å°† ``b`` 转æ¢æˆ ``A`` 类型。 + 请注æ„,您ä»ç„¶éœ€è¦æ³¨æ„匹é…çš„payable修饰的回退函数,如下文所述。 + +* ``address`` ç±»åž‹è¢«åˆ†æˆ ``address`` å’Œ ``address payable``, + 其中åªæœ‰ ``address payable`` æä¾› ``transfer`` 功能。 + 一个 ``address payable`` å¯ä»¥ç›´æŽ¥è½¬æ¢ä¸º ``address``, + 但ä¸å…许以其他方å¼è½¬æ¢ã€‚å°† ``address`` 转æ¢ä¸º ``address payable`` 是å¯ä»¥é€šè¿‡ ``uint160`` 转æ¢çš„。 + 如果 ``c`` 是一个åˆçº¦ï¼Œ åªæœ‰å½“ ``c`` 有一个 payable 修饰的回退函数时, + ``address(c)`` 的结果是 ``address payable``。 + 如果您使用 :ref:`å–å›žæ¨¡å¼ `,您很å¯èƒ½ä¸å¿…改å˜æ‚¨çš„代ç ï¼Œ + 因为 ``transfer`` åªç”¨äºŽ ``msg.sender`` 而ä¸æ˜¯å­˜å‚¨åœ°å€ï¼Œ + 而且 ``msg.sender`` 是一个 ``address payable`` 类型。 + +* 现在ä¸å…许ä¸åŒä½æ•°çš„ ``bytesX`` å’Œ ``uintY`` 之间的转æ¢äº†ï¼Œ + 因为 ``bytesX`` 会在å³ä¾§å¡«å……, ``uintY`` 会在左侧填充,这å¯èƒ½å¯¼è‡´æ„外的转æ¢ç»“果。 + 现在在转æ¢å‰å¿…须在类型内调整ä½æ•°ã€‚ 例如, + 您想è¦å°† ``bytes4`` (4字节)转æ¢ä¸º ``uint64`` (8字节), + 首先将 ``bytes4`` å˜é‡è½¬æ¢ä¸º ``bytes8``,然åŽå†è½¬æ¢ä¸º ``uint64``。 + 当通过 ``uint32`` 转æ¢æ—¶ï¼Œæ‚¨ä¼šå¾—到相å的填充结果。 + 在v0.5.0之å‰ï¼Œä»»ä½• ``bytesX`` å’Œ ``uintY`` 之间的转æ¢éƒ½è¦é€šè¿‡ ``uint8X``。 + 例如, ``uint8(bytes3(0x291807))`` 将被转æ¢ä¸º ``uint8(uint24(bytes3(0x291807)))`` + (结果是 ``0x07``)。 + +* 在éž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 -Deprecated Elements +废弃的元素 =================== -This section lists changes that deprecate prior features or syntax. Note that -many of these changes were already enabled in the experimental mode -``v0.5.0``. +这一节列出了废弃以å‰çš„功能或语法的å˜åŒ–。 请注æ„,其中许多å˜åŒ–å·²ç»åœ¨å®žéªŒæ¨¡å¼ ``v0.5.0`` 中å¯ç”¨ã€‚ +<<<<<<< HEAD +命令行和JSONæŽ¥å£ +-------------------------------- + +* 命令行选项 ``--formal`` (用于生æˆWhy3输出以进一步形å¼åŒ–验è¯ï¼‰å·²è¢«åºŸå¼ƒï¼ŒçŽ°åœ¨å·²è¢«åˆ é™¤ã€‚ + 一个新的形å¼åŒ–验è¯æ¨¡å—,SMTChecker,å¯ä»¥é€šè¿‡ ``pragma experimental SMTChecker;`` å¯ç”¨ã€‚ + +* 由于中间语言 ``Julia`` æ›´å为 ``Yul``,命令行选项 ``--julia`` 被更å为 ``--yul``。 + +* 删除了 ``--clone-bin`` å’Œ ``--combined-json clone-bin`` 命令行选项。 +======= Command-line and JSON Interfaces -------------------------------- @@ -160,145 +150,126 @@ Command-line and JSON Interfaces * The ``--clone-bin`` and ``--combined-json clone-bin`` command-line options were removed. +>>>>>>> english/develop -* Remappings with empty prefix are disallowed. +* ä¸å…许使用空å‰ç¼€çš„é‡æ˜ å°„。 -* The JSON AST fields ``constant`` and ``payable`` were removed. The - information is now present in the ``stateMutability`` field. +* JSON AST字段 ``constant`` å’Œ ``payable`` 被删除。 + 这些信æ¯çŽ°åœ¨å‡ºçŽ°åœ¨ ``stateMutability`` 字段中。 -* The JSON AST field ``isConstructor`` of the ``FunctionDefinition`` - node was replaced by a field called ``kind`` which can have the - value ``"constructor"``, ``"fallback"`` or ``"function"``. +* ``FunctionDefinition`` 节点的JSON AST字段 ``isConstructor`` 被一个å为 ``kind`` 的字段å–代, + 该字段的值å¯ä»¥æ˜¯ ``"constructor"``, ``"fallback"`` 或 ``"function"``。 -* In unlinked binary hex files, library address placeholders are now - the first 36 hex characters of the keccak256 hash of the fully qualified - library name, surrounded by ``$...$``. Previously, - just the fully qualified library name was used. - This reduces the chances of collisions, especially when long paths are used. - Binary files now also contain a list of mappings from these placeholders - to the fully qualified names. +* 在éžé“¾æŽ¥çš„二进制å六进制文件中,库地å€å ä½ç¬¦çŽ°åœ¨æ˜¯å®Œå…¨ç­‰åŒçš„库åçš„keccak256哈希值的å‰36个å六进制字符, + 用 ``$...$`` 包围。以å‰ï¼Œåªä½¿ç”¨å®Œå…¨ç­‰åŒçš„库å。这å‡å°‘了碰撞的机会,特别是在使用长路径的时候。 + 二进制文件现在也包å«ä¸€ä¸ªä»Žè¿™äº›å ä½ç¬¦åˆ°å®Œå…¨ç­‰åŒå称的映射列表。 -Constructors +构造函数 ------------ -* Constructors must now be defined using the ``constructor`` keyword. +* 现在必须使用 ``constructor`` 关键字æ¥å®šä¹‰æž„造函数。 -* Calling base constructors without parentheses is now disallowed. +* 现在ä¸å…许在没有括å·çš„情况下调用基本构造函数。 -* Specifying base constructor arguments multiple times in the same inheritance - hierarchy is now disallowed. +* 现在ä¸å…许在åŒä¸€ç»§æ‰¿å±‚次中多次指定基本构造函数å‚数。 -* Calling a constructor with arguments but with wrong argument count is now - disallowed. If you only want to specify an inheritance relation without - giving arguments, do not provide parentheses at all. +* 现在ä¸å…许调用有å‚数但å‚数个数错误的构造函数。 + 如果您åªæ˜¯æƒ³æŒ‡å®šä¸€ä¸ªç»§æ‰¿å…³ç³»è€Œä¸æ˜¯ç»™å‚数,完全ä¸è¦æ供括å·ã€‚ -Functions +函数 --------- -* Function ``callcode`` is now disallowed (in favor of ``delegatecall``). It - is still possible to use it via inline assembly. +* 函数 ``callcode`` 现在被ç¦æ­¢ä½¿ç”¨ï¼ˆæ”¹ç”¨ ``delegatecall``)。 + 但ä»ç„¶å¯ä»¥é€šè¿‡å†…è”汇编使用它。 -* ``suicide`` is now disallowed (in favor of ``selfdestruct``). +* 现在ä¸å…许使用 ``suicide`` (改用 ``selfdestruct``)。 -* ``sha3`` is now disallowed (in favor of ``keccak256``). +* 现在ä¸å…许使用 ``sha3`` (改用 ``keccak256``)。 -* ``throw`` is now disallowed (in favor of ``revert``, ``require`` and - ``assert``). +* 现在ä¸å…许使用 ``throw`` (改用 ``revert``, ``require`` å’Œ ``assert``)。 -Conversions +è½¬æ¢ ----------- -* Explicit and implicit conversions from decimal literals to ``bytesXX`` types - is now disallowed. +* 现在ä¸å…许从数字到 ``bytesXX`` 类型的显性和éšæ€§è½¬æ¢ã€‚ -* Explicit and implicit conversions from hex literals to ``bytesXX`` types - of different size is now disallowed. +* 现在ä¸å…许从å六进制字数到ä¸åŒå¤§å°çš„ ``bytesXX`` 类型的显性和éšæ€§è½¬æ¢ã€‚ -Literals and Suffixes +å­—é¢å¸¸é‡å’ŒåŽç¼€ --------------------- -* The unit denomination ``years`` is now disallowed due to complications and - confusions about leap years. +* 由于闰年的å¤æ‚性和混乱性,现在ä¸å…许使用å•ä½å称 ``years``。 -* Trailing dots that are not followed by a number are now disallowed. +* 现在ä¸å…许出现åŽé¢æ²¡æœ‰æ•°å­—的尾部圆点。 -* Combining hex numbers with unit denominations (e.g. ``0x1e wei``) is now - disallowed. +* 现在ä¸å…许将å六进制数字与å•ä½å€¼ç›¸ç»“åˆï¼ˆä¾‹å¦‚: ``0x1e wei``)。 -* The prefix ``0X`` for hex numbers is disallowed, only ``0x`` is possible. +* å六进制数字的å‰ç¼€ ``0X`` 是ä¸å…许的,åªèƒ½æ˜¯ ``0x``。 -Variables +å˜é‡ --------- -* Declaring empty structs is now disallowed for clarity. +* 为了清晰起è§ï¼ŒçŽ°åœ¨ä¸å…许声明空结构。 -* The ``var`` keyword is now disallowed to favor explicitness. +* 现在ä¸å…许使用 ``var`` 关键字,以利于明确性。 -* Assignments between tuples with different number of components is now - disallowed. +* 现在ä¸å…许在具有ä¸åŒç»„件数é‡çš„元组之间进行分é…。 -* Values for constants that are not compile-time constants are disallowed. +* ä¸å…许使用ä¸å±žäºŽç¼–译时常é‡çš„常é‡å€¼ã€‚ -* Multi-variable declarations with mismatching number of values are now - disallowed. +* 现在ä¸å…许出现数值ä¸åŒ¹é…的多å˜é‡å£°æ˜Žã€‚ -* Uninitialized storage variables are now disallowed. +* 现在ä¸å…许出现未åˆå§‹åŒ–的存储å˜é‡ã€‚ -* Empty tuple components are now disallowed. +* 现在ä¸å…许使用空元组。 -* Detecting cyclic dependencies in variables and structs is limited in - recursion to 256. +* 检测å˜é‡å’Œç»“构中的循环ä¾èµ–关系,在递归中被é™åˆ¶ä¸º256个。 -* Fixed-size arrays with a length of zero are now disallowed. +* 现在ä¸å…许长度为零的固定长度数组。 -Syntax +语法 ------ -* Using ``constant`` as function state mutability modifier is now disallowed. +* 现在ä¸å…许使用 ``constant`` 作为函数状æ€çš„å¯å˜æ€§ä¿®é¥°ç¬¦ã€‚ -* Boolean expressions cannot use arithmetic operations. +* 布尔表达å¼ä¸èƒ½ä½¿ç”¨ç®—术è¿ç®—。 -* The unary ``+`` operator is now disallowed. +* 现在ä¸å…许使用å•æ•°çš„ ``+`` æ“作符。 -* Literals cannot anymore be used with ``abi.encodePacked`` without prior - conversion to an explicit type. +* 如果没有事先转æ¢ä¸ºæ˜Žç¡®çš„类型,字é¢é‡ä¸èƒ½å†ä½¿ç”¨ ``abi.encodePacked``。 -* Empty return statements for functions with one or more return values are now - disallowed. +* 现在ä¸å…许有一个或多个返回值的函数的空返回语å¥ã€‚ -* The "loose assembly" syntax is now disallowed entirely, that is, jump labels, - jumps and non-functional instructions cannot be used anymore. Use the new - ``while``, ``switch`` and ``if`` constructs instead. +* 现在完全ä¸å…许使用 "æ¾æ•£æ±‡ç¼–" 语法,也就是说, + ä¸èƒ½å†ä½¿ç”¨è·³è½¬æ ‡ç­¾ï¼Œè·³è½¬å’ŒéžåŠŸèƒ½æŒ‡ä»¤ã€‚使用新的 ``while``, ``switch`` å’Œ ``if`` 结构代替。 -* Functions without implementation cannot use modifiers anymore. +* 没有实现的函数ä¸èƒ½å†ä½¿ç”¨ä¿®æ”¹å™¨ã€‚ -* Function types with named return values are now disallowed. +* 现在ä¸å…许具有命å返回值的函数类型。 -* Single statement variable declarations inside if/while/for bodies that are - not blocks are now disallowed. +* 现在ä¸å…许在ä¸æ˜¯ç¨‹åºå—çš„ if/while/for 语å¥ä½“中进行å•è¯­å¥å˜é‡å£°æ˜Žã€‚ -* New keywords: ``calldata`` and ``constructor``. +* 新的关键字: ``calldata`` å’Œ ``constructor``。 -* New reserved keywords: ``alias``, ``apply``, ``auto``, ``copyof``, - ``define``, ``immutable``, ``implements``, ``macro``, ``mutable``, - ``override``, ``partial``, ``promise``, ``reference``, ``sealed``, - ``sizeof``, ``supports``, ``typedef`` and ``unchecked``. +* æ–°çš„ä¿ç•™å…³é”®å­—: ``alias``, ``apply``, ``auto``, ``copyof``, + ``define``, ``immutable``, ``implements``, ``macro``, ``mutable``, + ``override``, ``partial``, ``promise``, ``reference``, ``sealed``, + ``sizeof``, ``supports``, ``typedef`` å’Œ ``unchecked``。 .. _interoperability: -Interoperability With Older Contracts +与旧åˆçº¦çš„互æ“作性 ===================================== -It is still possible to interface with contracts written for Solidity versions prior to -v0.5.0 (or the other way around) by defining interfaces for them. -Consider you have the following pre-0.5.0 contract already deployed: +通过为它们定义接å£ï¼Œä»ç„¶å¯ä»¥ä¸Žä¸º0.5.0之å‰çš„Solidity版本编写的åˆäºŽå¯¹æŽ¥ï¼ˆæˆ–者å过æ¥ï¼‰ã€‚ +考虑到您已ç»éƒ¨ç½²äº†ä»¥ä¸‹0.5.0之å‰çš„åˆçº¦ï¼š .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.4.25; - // This will report a warning until version 0.4.25 of the compiler - // This will not compile after 0.5.0 + // 在0.4.25版本的编译器之å‰ï¼Œè¿™å°†æŠ¥å‘Šä¸€ä¸ªè­¦å‘Š + // 这在0.5.0之åŽå°†æ— æ³•ç¼–译。 contract OldContract { function someOldFunction(uint8 a) { //... @@ -309,7 +280,7 @@ Consider you have the following pre-0.5.0 contract already deployed: // ... } -This will no longer compile with Solidity v0.5.0. However, you can define a compatible interface for it: +这将ä¸å†åœ¨Solidity 0.5.0版本中进行编译。然而,您å¯ä»¥ä¸ºå®ƒå®šä¹‰ä¸€ä¸ªå…¼å®¹çš„接å£ï¼š .. code-block:: solidity @@ -320,14 +291,14 @@ This will no longer compile with Solidity v0.5.0. However, you can define a comp function anotherOldFunction() external returns (bool); } -Note that we did not declare ``anotherOldFunction`` to be ``view``, despite it being declared ``constant`` in the original -contract. This is due to the fact that starting with Solidity v0.5.0 ``staticcall`` is used to call ``view`` functions. -Prior to v0.5.0 the ``constant`` keyword was not enforced, so calling a function declared ``constant`` with ``staticcall`` -may still revert, since the ``constant`` function may still attempt to modify storage. Consequently, when defining an -interface for older contracts, you should only use ``view`` in place of ``constant`` in case you are absolutely sure that -the function will work with ``staticcall``. +请注æ„,我们没有声明 ``anotherOldFunction`` 是 ``view``,尽管它在原始åˆçº¦ä¸­è¢«å£°æ˜Žä¸º ``constant``。 +这是由于从Solidity 0.5.0版本开始,``staticcall`` 被用æ¥è°ƒç”¨ ``view`` 函数。 +在 0.5.0 版本之å‰ï¼Œ ``constant`` 关键字没有被强制执行, +所以用 ``staticcall`` 调用一个被声明为 ``constant`` 的函数ä»ç„¶å¯èƒ½è¢«è¿˜åŽŸï¼Œ +因为 ``constant`` 函数ä»ç„¶å¯èƒ½è¯•å›¾ä¿®æ”¹å­˜å‚¨ã€‚因此,当为旧åˆçº¦å®šä¹‰æŽ¥å£æ—¶ï¼Œ +您应该åªä½¿ç”¨ ``view`` æ¥ä»£æ›¿ ``constant``,以防您ç»å¯¹ç¡®å®šè¯¥å‡½æ•°èƒ½ä¸Ž ``staticcall`` 一起工作。 -Given the interface defined above, you can now easily use the already deployed pre-0.5.0 contract: +有了上é¢å®šä¹‰çš„接å£ï¼Œæ‚¨çŽ°åœ¨å¯ä»¥å¾ˆå®¹æ˜“地使用已ç»éƒ¨ç½²çš„ 0.5.0 之å‰çš„åˆçº¦ï¼š .. code-block:: solidity @@ -346,13 +317,13 @@ Given the interface defined above, you can now easily use the already deployed p } } -Similarly, pre-0.5.0 libraries can be used by defining the functions of the library without implementation and -supplying the address of the pre-0.5.0 library during linking (see :ref:`commandline-compiler` for how to use the -commandline compiler for linking): +åŒæ ·ï¼Œ0.5.0以å‰çš„库å¯ä»¥é€šè¿‡å®šä¹‰åº“的功能而ä¸éœ€è¦å®žçŽ°ï¼Œ +并在连接时æä¾›0.5.0以å‰çš„库的地å€æ¥ä½¿ç”¨ +(关于如何使用命令行编译器进行连接,请å‚è§ :ref:`commandline-compiler`)。 .. code-block:: solidity - // This will not compile after 0.6.0 + // 这在0.6.0版本之åŽå°†æ— æ³•ç¼–译。 // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.5.0; @@ -367,11 +338,10 @@ commandline compiler for linking): } -Example +示例 ======= -The following example shows a contract and its updated version for Solidity -v0.5.0 with some of the changes listed in this section. +下é¢çš„例å­æ˜¾ç¤ºäº†Solidity 0.5.0 版本的åˆçº¦åŠå…¶æ›´æ–°ç‰ˆæœ¬ï¼Œå…¶ä¸­åŒ…括本节中列出的一些å˜åŒ–。 Old version: @@ -379,7 +349,7 @@ Old version: // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.4.25; - // This will not compile after 0.5.0 + // 这在0.5.0版本之åŽå°†æ— æ³•ç¼–译。 contract OtherContract { uint x; @@ -393,56 +363,56 @@ Old version: OtherContract other; uint myNumber; - // Function mutability not provided, not an error. + // 没有æ供函数的å¯å˜æ€§ï¼Œä¸æ˜¯é”™è¯¯ã€‚ function someInteger() internal returns (uint) { return 2; } - // Function visibility not provided, not an error. - // Function mutability not provided, not an error. + // 没有æ供函数的å¯è§æ€§ï¼Œä¸æ˜¯é”™è¯¯ã€‚ + // 没有æ供函数的å¯å˜æ€§ï¼Œä¸æ˜¯é”™è¯¯ã€‚ function f(uint x) returns (bytes) { - // Var is fine in this version. + // 在这个版本中,var是å¯ä»¥ä½¿ç”¨çš„。 var z = someInteger(); x += z; - // Throw is fine in this version. + // 在这个版本中,throw是å¯ä»¥ä½¿ç”¨çš„。 if (x > 100) throw; bytes memory b = new bytes(x); y = -3 >> 1; - // y == -1 (wrong, should be -2) + // y == -1(错,应该是-2)。 do { x += 1; if (x > 10) continue; - // 'Continue' causes an infinite loop. + // 'Continue' 会导致无é™å¾ªçŽ¯ã€‚ } while (x < 11); - // Call returns only a Bool. + // 调用åªè¿”回一个布尔值。 bool success = address(other).call("f"); if (!success) revert(); else { - // Local variables could be declared after their use. + // 局部å˜é‡å¯ä»¥åœ¨å…¶ä½¿ç”¨åŽå£°æ˜Žã€‚ int y; } return b; } - // No need for an explicit data location for 'arr' + //ä¸éœ€è¦ä¸º'arr'设置明确的数æ®ä½ç½® function g(uint[] arr, bytes8 x, OtherContract otherContract) public { otherContract.transfer(1 ether); - // Since uint32 (4 bytes) is smaller than bytes8 (8 bytes), - // the first 4 bytes of x will be lost. This might lead to - // unexpected behavior since bytesX are right padded. + // 由于uint32(4个字节)å°äºŽbyte8(8个字节), + // xçš„å‰4个字节将被丢失。 + // è¿™å¯èƒ½ä¼šå¯¼è‡´æ„想ä¸åˆ°çš„行为,因为bytesX是å‘å³å¡«å……的。 uint32 y = uint32(x); myNumber += y + msg.value; } } -New version: +新版本: .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.5.0; - // This will not compile after 0.6.0 + // 这在0.6.0版本之åŽå°†æ— æ³•ç¼–译。 contract OtherContract { uint x; @@ -456,27 +426,27 @@ New version: OtherContract other; uint myNumber; - // Function mutability must be specified. + // 必须指定函数的å¯å˜æ€§ã€‚ function someInteger() internal pure returns (uint) { return 2; } - // Function visibility must be specified. - // Function mutability must be specified. + // 必须指定函数的å¯è§æ€§ã€‚ + // 必须指定函数的å¯å˜æ€§ã€‚ function f(uint x) public returns (bytes memory) { - // The type must now be explicitly given. + // 现在必须明确地给出类型。 uint z = someInteger(); x += z; - // Throw is now disallowed. + // 现在ä¸å…许使用throw。 require(x <= 100); int y = -3 >> 1; require(y == -2); do { x += 1; if (x > 10) continue; - // 'Continue' jumps to the condition below. + // 'Continue'跳转到下é¢çš„æ¡ä»¶ã€‚ } while (x < 11); - // Call returns (bool, bytes). - // Data location must be specified. + // call返回值为(bool, bytes). + // 必须指定数æ®ä½ç½®ã€‚ (bool success, bytes memory data) = address(other).call("f"); if (!success) revert(); @@ -484,38 +454,35 @@ New version: } using AddressMakePayable for address; - // Data location for 'arr' must be specified + // 必须指定'arr'çš„æ•°æ®ä½ç½® function g(uint[] memory /* arr */, bytes8 x, OtherContract otherContract, address unknownContract) public payable { - // 'otherContract.transfer' is not provided. - // Since the code of 'OtherContract' is known and has the fallback - // function, address(otherContract) has type 'address payable'. + // 没有æä¾›'otherContract.transfer'。 + // 由于'OtherContract'的代ç æ˜¯å·²çŸ¥çš„,并且具有回退功能, + // address(otherContract)具有'address payable'类型。 address(otherContract).transfer(1 ether); - // 'unknownContract.transfer' is not provided. - // 'address(unknownContract).transfer' is not provided - // since 'address(unknownContract)' is not 'address payable'. - // If the function takes an 'address' which you want to send - // funds to, you can convert it to 'address payable' via 'uint160'. - // Note: This is not recommended and the explicit type - // 'address payable' should be used whenever possible. - // To increase clarity, we suggest the use of a library for - // the conversion (provided after the contract in this example). + // 没有æä¾›'unknownContract.transfer'。 + // 没有æä¾›'address(unknownContract).transfer' + // 因为'address(unknownContract)'ä¸æ˜¯'address payable'类型。 + // 如果该函数需è¦ä¸€ä¸ªæ‚¨æƒ³å‘é€èµ„金的'address'类型, + // 您å¯ä»¥é€šè¿‡'uint160'将其转æ¢ä¸º'address payable'类型。 + // 注æ„:ä¸å»ºè®®è¿™æ ·åšï¼Œåº”å°½å¯èƒ½ä½¿ç”¨æ˜Žç¡®çš„'address payable'类型。 + // 为了æ高明确性,我们建议使用一个库æ¥è¿›è¡Œè½¬æ¢ï¼ˆåœ¨è¿™ä¸ªä¾‹å­ä¸­çš„åˆåŒåŽé¢æ供)。 address payable addr = unknownContract.makePayable(); require(addr.send(1 ether)); - // Since uint32 (4 bytes) is smaller than bytes8 (8 bytes), - // the conversion is not allowed. - // We need to convert to a common size first: + // 由于uint32(4字节)å°äºŽbytes8(8字节), + // 所以ä¸å…许进行转æ¢ã€‚ + // 我们需è¦å…ˆè½¬æ¢åˆ°ä¸€ä¸ªé€šç”¨çš„大å°ï¼š bytes4 x4 = bytes4(x); // Padding happens on the right uint32 y = uint32(x4); // Conversion is consistent - // 'msg.value' cannot be used in a 'non-payable' function. - // We need to make the function payable + // 'msg.value'ä¸èƒ½ç”¨åœ¨'éžpayable'类型的函数中。 + // 我们需è¦æŠŠå‡½æ•°å˜æˆpayable类型 myNumber += y + msg.value; } } - // We can define a library for explicitly converting ``address`` - // to ``address payable`` as a workaround. + // 我们å¯ä»¥å®šä¹‰ä¸€ä¸ªåº“,将 ``address`` 类型明确转æ¢ä¸º ``address payable`` 类型,作为一ç§å˜é€šæ–¹æ³•ã€‚ library AddressMakePayable { function makePayable(address x) internal pure returns (address payable) { return address(uint160(x)); diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst index e7c93057f62a..ee29e1cca9db 100644 --- a/docs/060-breaking-changes.rst +++ b/docs/060-breaking-changes.rst @@ -1,181 +1,188 @@ ******************************** -Solidity v0.6.0 Breaking Changes +Solidity 0.6.0 版本çªç ´æ€§å˜åŒ– ******************************** -This section highlights the main breaking changes introduced in Solidity -version 0.6.0, along with the reasoning behind the changes and how to update -affected code. -For the full list check -`the release changelog `_. +本节强调了 Solidity 0.6.0 版本中引入的主è¦çªç ´æ€§å˜åŒ–,以åŠè¿™äº›å˜åŒ–背åŽçš„原因和如何更新å—å½±å“的代ç ã€‚ +对于完整的列表,请查看 `版本更新日志 `_。 -Changes the Compiler Might not Warn About +编译器å¯èƒ½ä¸ä¼šå‘出警告的å˜åŒ– ========================================= +<<<<<<< HEAD +本节列出了一些å˜åŒ–,在这些å˜åŒ–中,您的代ç çš„行为å¯èƒ½ä¼šå‘生å˜åŒ–,而编译器ä¸ä¼šå‘Šè¯‰æ‚¨ã€‚ +======= This section lists changes where the behavior of your code might change without the compiler telling you about it. +>>>>>>> english/develop -* The resulting type of an exponentiation is the type of the base. It used to be the smallest type - that can hold both the type of the base and the type of the exponent, as with symmetric - operations. Additionally, signed types are allowed for the base of the exponentiation. +* 指数è¿ç®—的结果类型是基数的类型。 + å°±åƒå¯¹ç§°è¿ç®—一样,它曾ç»æ˜¯å¯ä»¥åŒæ—¶å®¹çº³åŸºæ•°ç±»åž‹å’ŒæŒ‡æ•°ç±»åž‹çš„最å°ç±»åž‹ã€‚ + 此外,指数化的基数å…许是有符å·çš„类型。 - -Explicitness Requirements +显性è¦æ±‚ ========================= -This section lists changes where the code now needs to be more explicit, -but the semantics do not change. -For most of the topics the compiler will provide suggestions. +这一节列出了代ç çŽ°åœ¨éœ€è¦æ›´æ˜¾å¼çš„更改,但是语义没有改å˜ã€‚ +对于大多数主题,编译器会æ供建议。 -* Functions can now only be overridden when they are either marked with the - ``virtual`` keyword or defined in an interface. Functions without - implementation outside an interface have to be marked ``virtual``. - When overriding a function or modifier, the new keyword ``override`` - must be used. When overriding a function or modifier defined in multiple - parallel bases, all bases must be listed in parentheses after the keyword - like so: ``override(Base1, Base2)``. +* 现在,åªæœ‰å½“函数被标记为 ``virtual`` 关键字或被定义在一个接å£ä¸­æ—¶ï¼Œæ‰èƒ½è¢«é‡è½½ã€‚ + 在接å£ä¹‹å¤–没有实现的函数必须被标记为 ``virtual``。 + 当é‡è½½ä¸€ä¸ªå‡½æ•°æˆ–修改器时,必须使用新的关键字 ``override``。 + 当é‡è½½ä¸€ä¸ªå®šä¹‰åœ¨å¤šä¸ªå¹¶è¡ŒåŸºç±»çš„函数或修改器时,所有基必须在关键字åŽé¢çš„括å·ä¸­åˆ—出, + åƒè¿™æ ·ï¼š ``override(Base1, Base2)``。 -* Member-access to ``length`` of arrays is now always read-only, even for storage arrays. It is no - longer possible to resize storage arrays by assigning a new value to their length. Use ``push()``, - ``push(value)`` or ``pop()`` instead, or assign a full array, which will of course overwrite the existing content. - The reason behind this is to prevent storage collisions of gigantic - storage arrays. +* æˆå‘˜å¯¹æ•°ç»„çš„ ``length`` 的访问现在总是åªè¯»çš„,å³ä½¿æ˜¯å­˜å‚¨æ•°ç»„。 + ä¸å†å¯èƒ½é€šè¿‡ç»™å­˜å‚¨æ•°ç»„的长度分é…一个新值æ¥è°ƒæ•´å…¶å¤§å°ã€‚ + 使用 ``push()``, ``push(value)`` 或 ``pop()`` 代替, + 或者分é…一个完整的数组,当然这将覆盖现有内容。 + 这背åŽçš„原因是为了防止巨大的存储阵列的存储碰撞。 -* The new keyword ``abstract`` can be used to mark contracts as abstract. It has to be used - if a contract does not implement all its functions. Abstract contracts cannot be created using the ``new`` operator, - and it is not possible to generate bytecode for them during compilation. +* 新的关键字 ``abstract`` å¯ä»¥ç”¨æ¥æ ‡è®°åˆçº¦ä¸ºæŠ½è±¡çš„。 + 如果一个åˆçº¦æ²¡æœ‰å®žçŽ°å®ƒçš„所有功能,就必须使用这个关键字。抽象åˆçº¦ä¸èƒ½ç”¨ ``new`` æ“作符创建, + 在编译过程中也ä¸å¯èƒ½ä¸ºå…¶ç”Ÿæˆå­—节ç ã€‚ -* Libraries have to implement all their functions, not only the internal ones. +* 库åˆçº¦å¿…须实现其所有功能,而ä¸ä»…仅是内部功能。 -* The names of variables declared in inline assembly may no longer end in ``_slot`` or ``_offset``. +* 在内è”汇编中声明的å˜é‡å称ä¸èƒ½å†ä»¥ ``_slot`` 或 ``_offset`` 结尾。 -* Variable declarations in inline assembly may no longer shadow any declaration outside the inline assembly block. - If the name contains a dot, its prefix up to the dot may not conflict with any declaration outside the inline - assembly block. +* 内è”汇编中的å˜é‡å£°æ˜Žä¸èƒ½å†å½±å°„内è”汇编å—外的任何声明。 + 如果å˜é‡å称中包å«ä¸€ä¸ªç‚¹ï¼Œé‚£ä¹ˆå®ƒçš„å‰ç¼€åˆ°ç‚¹çš„部分ä¸èƒ½ä¸Žå†…è”汇编å—外的任何声明冲çªã€‚ -* In inline assembly, opcodes that do not take arguments are now represented as "built-in functions" instead of standalone identifiers. So ``gas`` is now ``gas()``. +* 在内è”汇编中,ä¸å¸¦å‚æ•°çš„æ“作ç çŽ°åœ¨è¡¨ç¤ºä¸ºâ€œå†…置函数â€è€Œä¸æ˜¯ç‹¬ç«‹æ ‡è¯†ç¬¦ã€‚所以 ``gas`` 现在是 ``gas()``。 -* State variable shadowing is now disallowed. A derived contract can only - declare a state variable ``x``, if there is no visible state variable with - the same name in any of its bases. +* 现在ä¸å…许影å­çŠ¶æ€å˜é‡ã€‚ 一个派生åˆçº¦åªèƒ½å£°æ˜Žä¸€ä¸ªçŠ¶æ€å˜é‡ ``x``, + 如果在它的任何基类åˆçº¦ä¸­éƒ½æ²¡æœ‰åŒåçš„å¯è§çŠ¶æ€å˜é‡ã€‚ -Semantic and Syntactic Changes +语义和语法å˜åŒ– ============================== -This section lists changes where you have to modify your code -and it does something else afterwards. +这一部分列出了您必须修改您的代ç ï¼Œè€Œä¹‹åŽå®ƒåˆåšäº†ä¸€äº›åˆ«çš„事情的å˜åŒ–。 -* Conversions from external function types to ``address`` are now disallowed. Instead external - function types have a member called ``address``, similar to the existing ``selector`` member. +* 现在ä¸å…许从外部函数类型转æ¢ä¸º ``address`` 类型。 + 相å,外部函数类型有一个å«åš ``address`` çš„æˆå‘˜ï¼Œç±»ä¼¼äºŽçŽ°æœ‰çš„ ``selector`` æˆå‘˜ã€‚ -* The function ``push(value)`` for dynamic storage arrays does not return the new length anymore (it returns nothing). +* 动æ€å­˜å‚¨æ•°ç»„的函数 ``push(value)`` ä¸å†è¿”回新的长度(它什么也ä¸è¿”回)。 -* The unnamed function commonly referred to as "fallback function" was split up into a new - fallback function that is defined using the ``fallback`` keyword and a receive ether function - defined using the ``receive`` keyword. +* 通常被称为 "回退函数" çš„æ— å函数被拆分为一个新的回退函数,该函数使用 ``fallback`` 关键字定义, + 并使用 ``receive`` 关键字定义一个接收以太的函数。 - * If present, the receive ether function is called whenever the call data is empty (whether - or not ether is received). This function is implicitly ``payable``. + * 如果存在,æ¯å½“调用数æ®ä¸ºç©ºæ—¶ï¼ˆæ— è®ºæ˜¯å¦æ”¶åˆ°ä»¥å¤ªï¼‰ï¼Œ + 都会调用接收以太函数 receive。此函数是éšå¼çš„ ``payable``。 - * The new fallback function is called when no other function matches (if the receive ether - function does not exist then this includes calls with empty call data). - You can make this function ``payable`` or not. If it is not ``payable`` then transactions - not matching any other function which send value will revert. You should only need to - implement the new fallback function if you are following an upgrade or proxy pattern. + * 当没有其他函数匹é…时,就会调用新的回退函数(如果接收以太的函数receiveä¸å­˜åœ¨ï¼Œåˆ™åŒ…括调用数æ®ä¸ºç©ºçš„调用)。 + 您å¯ä»¥è®©è¿™ä¸ªå‡½æ•°æ˜¯ ``payable`` 函数或ä¸æ˜¯ã€‚如果它ä¸æ˜¯ ``payable`` 函数, + 那么ä¸åŒ¹é…任何其他å‘é€ä»·å€¼çš„函数的交易将æ¢å¤ã€‚ + åªæœ‰åœ¨é‡‡ç”¨å‡çº§æˆ–代ç†æ¨¡å¼æ—¶ï¼Œæ‰éœ€è¦å®žçŽ°æ–°çš„回退函数。 -New Features +新功能 ============ -This section lists things that were not possible prior to Solidity 0.6.0 -or were more difficult to achieve. +本节列出了在Solidity 0.6.0之å‰ä¸å¯èƒ½å®žçŽ°æˆ–很难实现的事情。 -* The :ref:`try/catch statement ` allows you to react on failed external calls. -* ``struct`` and ``enum`` types can be declared at file level. -* Array slices can be used for calldata arrays, for example ``abi.decode(msg.data[4:], (uint, uint))`` - is a low-level way to decode the function call payload. -* Natspec supports multiple return parameters in developer documentation, enforcing the same naming check as ``@param``. -* Yul and Inline Assembly have a new statement called ``leave`` that exits the current function. -* Conversions from ``address`` to ``address payable`` are now possible via ``payable(x)``, where - ``x`` must be of type ``address``. +* :ref:`try/catchè¯­å¥ ` å…许您对失败的外部调用åšå‡ºå应。 +* ``struct`` å’Œ ``enum`` 类型å¯ä»¥åœ¨æ–‡ä»¶çº§åˆ«å£°æ˜Žã€‚ +* 数组切片å¯ä»¥ç”¨äºŽcalldata数组,例如 ``abi.decode(msg.data[4:], (uint, uint))`` + 是对函数调用有效负载进行解ç çš„低级方法。 +* Natspec在开å‘者文档中支æŒå¤šä¸ªè¿”回å‚数,执行与 ``@param`` 相åŒçš„命å检查。 +* Yul 和内è”汇编有一个新的语å¥ï¼Œå«åš ``leave``,å¯ä»¥é€€å‡ºå½“å‰å‡½æ•°ã€‚ +* 现在å¯ä»¥é€šè¿‡ ``payable(x)`` å°† ``address`` 转æ¢ä¸º ``address payable``, + 其中 ``x`` 必须是 ``address`` 类型。 -Interface Changes +接å£å˜åŒ– ================= +<<<<<<< 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 -New Error Reporter +新的错误报告器 ~~~~~~~~~~~~~~~~~~ +<<<<<<< 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 -Metadata Hash Options +元数æ®å“ˆå¸Œé€‰é¡¹ ~~~~~~~~~~~~~~~~~~~~~ +<<<<<<< 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 -These changes can also be used via the :ref:`Standard JSON Interface` and effect the metadata JSON generated by the compiler. +这些å˜åŒ–也å¯ä»¥é€šè¿‡ :ref:`标准JSONæŽ¥å£ ` 使用,并影å“编译器生æˆçš„元数æ®JSON。 -The recommended way to read the metadata is to read the last two bytes to determine the length of the CBOR encoding -and perform a proper decoding on that data block as explained in the :ref:`metadata section`. +读å–元数æ®çš„推è方法是读å–最åŽä¸¤ä¸ªå­—节,以确定CBORç¼–ç çš„长度,并对该数æ®å—进行适当的解ç ï¼Œ +这在 :ref:`元数æ®éƒ¨åˆ† ` 中有所解释。 -Yul Optimizer +Yul 优化器 ~~~~~~~~~~~~~ -Together with the legacy bytecode optimizer, the :doc:`Yul ` optimizer is now enabled by default when you call the compiler -with ``--optimize``. It can be disabled by calling the compiler with ``--no-optimize-yul``. -This mostly affects code that uses ABI coder v2. +与传统的字节ç ä¼˜åŒ–器一起,:doc:`Yul ` 优化器现在在用 ``--optimize`` å‚数调用编译器时默认å¯ç”¨ã€‚ +å¯ä»¥é€šè¿‡ ``--no-optimize-yul`` å‚数在调用编译器时ç¦ç”¨å®ƒã€‚这主è¦å½±å“到使用ABI coder v2的代ç ã€‚ -C API Changes +C API å˜åŒ– ~~~~~~~~~~~~~ -The client code that uses the C API of ``libsolc`` is now in control of the memory used by the compiler. To make -this change consistent, ``solidity_free`` was renamed to ``solidity_reset``, the functions ``solidity_alloc`` and -``solidity_free`` were added and ``solidity_compile`` now returns a string that must be explicitly freed via -``solidity_free()``. +使用 ``libsolc`` çš„C API的客户端代ç çŽ°åœ¨å¯ä»¥æŽ§åˆ¶ç¼–译器使用的内存。 +为了使这一å˜åŒ–ä¿æŒä¸€è‡´ï¼Œ ``solidity_free`` 被é‡æ–°å‘½å为 ``solidity_reset``, +增加了函数 ``solidity_alloc`` å’Œ ``solidity_free``, +``solidity_compile`` 现在返回一个必须通过 ``solidity_free()`` 显å¼é‡Šæ”¾çš„字符串。 -How to update your code +å¦‚ä½•æ›´æ–°æ‚¨çš„ä»£ç  ======================= -This section gives detailed instructions on how to update prior code for every breaking change. +本节详细说明了如何为æ¯ä¸€ä¸ªçªç ´æ€§å˜åŒ–æ›´æ–°å…ˆå‰çš„代ç ã€‚ -* Change ``address(f)`` to ``f.address`` for ``f`` being of external function type. +* å°† ``address(f)`` 改为 ``f.address``,因为 ``f`` 是外部函数类型。 -* Replace ``function () external [payable] { ... }`` by either ``receive() external payable { ... }``, - ``fallback() external [payable] { ... }`` or both. Prefer - using a ``receive`` function only, whenever possible. +* 用 ``receive() external payable { ... }``, ``fallback() external [payable] { ... }`` + 或这两个函数一起æ¥æ›¿æ¢ ``function () external [payable] { ... }``。 + åªè¦æœ‰å¯èƒ½ï¼Œæœ€å¥½åªä½¿ç”¨ ``receive`` 函数。 -* Change ``uint length = array.push(value)`` to ``array.push(value);``. The new length can be - accessed via ``array.length``. +* å°† ``uint length = array.push(value)`` 改为 ``array.push(value);``。 + 新的长度å¯ä»¥é€šè¿‡ ``array.length`` 访问。 -* Change ``array.length++`` to ``array.push()`` to increase, and use ``pop()`` to decrease - the length of a storage array. +* å°† ``array.length++`` 改为 ``array.push()`` æ¥å¢žåŠ æ•°ç»„长度,使用 ``pop()`` æ¥å‡å°‘存储数组的长度。 -* For every named return parameter in a function's ``@dev`` documentation define a ``@return`` - entry which contains the parameter's name as the first word. E.g. if you have function ``f()`` defined - like ``function f() public returns (uint value)`` and a ``@dev`` annotating it, document its return - parameters like so: ``@return value The return value.``. You can mix named and un-named return parameters - documentation so long as the notices are in the order they appear in the tuple return type. +* 在一个函数的 ``@dev`` 文档中,为æ¯ä¸ªå‘½å的返回å‚数定义一个 ``@return`` æ¡ç›®ï¼Œ + å°†å‚æ•°çš„å称作为第一个è¯ã€‚例如, + 如果您有定义为 ``function f() public returns (uint value)`` 的函数 ``f()``, + 并且有 ``@dev`` 注释,那么记录它的返回å‚数如下: ``@return value The return value.``。 + 您å¯ä»¥æ··åˆä½¿ç”¨å‘½å的和未命å的返回å‚数文档,åªè¦è¿™äº›å£°æ˜Žæ˜¯æŒ‰ç…§å®ƒä»¬åœ¨å…ƒç»„返回类型中出现的顺åºå³å¯ã€‚ -* Choose unique identifiers for variable declarations in inline assembly that do not conflict - with declarations outside the inline assembly block. +* 为内è”汇编中的å˜é‡å£°æ˜Žé€‰æ‹©å”¯ä¸€çš„标识符,ä¸ä¸Žå†…è”汇编å—外的声明冲çªã€‚ -* Add ``virtual`` to every non-interface function you intend to override. Add ``virtual`` - to all functions without implementation outside interfaces. For single inheritance, add - ``override`` to every overriding function. For multiple inheritance, add ``override(A, B, ..)``, - where you list all contracts that define the overridden function in the parentheses. When - multiple bases define the same function, the inheriting contract must override all conflicting functions. +* 在æ¯ä¸€ä¸ªæ‚¨æ‰“ç®—é‡è½½çš„éžæŽ¥å£å‡½æ•°ä¸Šæ·»åŠ  ``virtual``。 + 在所有没有具体实现的接å£ä¹‹å¤–的函数上添加 ``virtual``。 + 对于å•ç»§æ‰¿ï¼Œåœ¨æ¯ä¸ªé‡è½½çš„函数上添加 ``override``。对于多é‡ç»§æ‰¿ï¼Œæ·»åŠ  ``override(A, B, ..)``, + 在括å·ä¸­åˆ—出所有定义了é‡è½½å‡½æ•°çš„åˆçº¦ã€‚当多个基类定义åŒä¸€ä¸ªå‡½æ•°æ—¶ï¼Œç»§æ‰¿çš„åˆçº¦å¿…é¡»é‡è½½æ‰€æœ‰å†²çªçš„函数。 -* In inline assembly, add ``()`` to all opcodes that do not otherwise accept an argument. - For example, change ``pc`` to ``pc()``, and ``gas`` to ``gas()``. +* 在内è”汇编中,将 ``()`` 添加到所有ä¸æŽ¥å—å‚æ•°çš„æ“作ç åŽã€‚ + 例如,将 ``pc`` 更改为 ``pc()``,将 ``gas`` 更改为 ``gas()``。 diff --git a/docs/070-breaking-changes.rst b/docs/070-breaking-changes.rst index 05e98a4dcc21..de984c4f33f5 100644 --- a/docs/070-breaking-changes.rst +++ b/docs/070-breaking-changes.rst @@ -1,133 +1,118 @@ ******************************** -Solidity v0.7.0 Breaking Changes +Solidity v0.7.0 çªç ´æ€§å˜åŒ– ******************************** -This section highlights the main breaking changes introduced in Solidity -version 0.7.0, along with the reasoning behind the changes and how to update -affected code. -For the full list check -`the release changelog `_. +本节强调了 Solidity 0.7.0 版本中引入的主è¦çªç ´æ€§å˜åŒ–, +以åŠè¿™äº›å˜åŒ–背åŽçš„原因和如何更新å—å½±å“的代ç ã€‚ +对于完整的列表,请查看 `版本更新日志 `_。 -Silent Changes of the Semantics +语义的微å°å˜åŒ– =============================== -* Exponentiation and shifts of literals by non-literals (e.g. ``1 << x`` or ``2 ** x``) - will always use either the type ``uint256`` (for non-negative literals) or - ``int256`` (for negative literals) to perform the operation. - Previously, the operation was performed in the type of the shift amount / the - exponent which can be misleading. +* 用éžå­—符é‡è¿›è¡ŒæŒ‡æ•°å’Œç§»ä½ï¼ˆä¾‹å¦‚: ``1 << x`` 或 ``2 ** x``) + 将总是使用 ``uint256`` 类型(对于éžè´Ÿæ•°ï¼‰æˆ– + ``int256`` 类型(对于负数)æ¥æ‰§è¡Œæ“作。 + 在此之å‰ï¼Œè¯¥æ“作是在移ä½é‡/指数的类型中进行的,这å¯èƒ½ä¼šäº§ç”Ÿè¯¯å¯¼ã€‚ -Changes to the Syntax +语法的å˜åŒ– ===================== -* In external function and contract creation calls, Ether and gas is now specified using a new syntax: - ``x.f{gas: 10000, value: 2 ether}(arg1, arg2)``. - The old syntax -- ``x.f.gas(10000).value(2 ether)(arg1, arg2)`` -- will cause an error. +* 在外部函数和åˆçº¦åˆ›å»ºè°ƒç”¨ä¸­ï¼ŒçŽ°åœ¨ä½¿ç”¨æ–°çš„语法指定以太和gas: ``x.f{gas: 10000, value: 2 ether}(arg1, arg2)``。 + 旧的语法 -- ``x.f.gas(10000).value(2 ether)(arg1, arg2)`` -- 会导致错误。 -* The global variable ``now`` is deprecated, ``block.timestamp`` should be used instead. - The single identifier ``now`` is too generic for a global variable and could give the impression - that it changes during transaction processing, whereas ``block.timestamp`` correctly - reflects the fact that it is just a property of the block. +* 全局å˜é‡ ``now`` 已被弃用, 应该使用 ``block.timestamp`` æ¥æ›¿æ¢ã€‚ + 对于一个全局å˜é‡æ¥è¯´ï¼Œå•ä¸€çš„标识符 ``now`` 太通用了,å¯èƒ½ä¼šè®©äººè§‰å¾—它在事务处ç†è¿‡ç¨‹ä¸­å‘生å˜åŒ–, + 而 ``block.timestamp`` 正确地å映了它åªæ˜¯å—的一个属性。 -* NatSpec comments on variables are only allowed for public state variables and not - for local or internal variables. +* 对å˜é‡çš„NatSpec注释åªå…许用于公共状æ€å˜é‡ï¼Œè€Œä¸å…许用于本地或内部å˜é‡ã€‚ -* The token ``gwei`` is a keyword now (used to specify, e.g. ``2 gwei`` as a number) - and cannot be used as an identifier. +* ä»£å· ``gwei`` 现在是一个关键è¯ï¼ˆç”¨äºŽæŒ‡å®šï¼Œä¾‹å¦‚ ``2 gwei`` 作为一个数字),ä¸èƒ½ä½œä¸ºä¸€ä¸ªæ ‡è¯†ç¬¦ä½¿ç”¨ã€‚ -* String literals now can only contain printable ASCII characters and this also includes a variety of - escape sequences, such as hexadecimal (``\xff``) and unicode escapes (``\u20ac``). +* 字符串现在åªèƒ½åŒ…å«å¯æ‰“å°çš„ASCII字符,这也包括å„ç§è½¬ä¹‰åºåˆ—, + 如å六进制( ``\xff``)和unicode转义( ``\u20ac``)。 -* Unicode string literals are supported now to accommodate valid UTF-8 sequences. They are identified - with the ``unicode`` prefix: ``unicode"Hello 😃"``. +* 现在支æŒUnicode字符串文本æ¥å®¹çº³æœ‰æ•ˆçš„UTF-8åºåˆ—。 + 它们用 ``unicode`` å‰ç¼€æ¥æ ‡è¯†ï¼š ``unicode"Hello 😃"``。 -* State Mutability: The state mutability of functions can now be restricted during inheritance: - Functions with default state mutability can be overridden by ``pure`` and ``view`` functions - while ``view`` functions can be overridden by ``pure`` functions. - At the same time, public state variables are considered ``view`` and even ``pure`` - if they are constants. +* 状æ€å¯å˜æ€§ï¼šçŽ°åœ¨å¯ä»¥åœ¨ç»§æ‰¿è¿‡ç¨‹ä¸­é™åˆ¶å‡½æ•°çš„状æ€å¯å˜æ€§ã€‚ + 具有默认状æ€å¯å˜æ€§çš„函数å¯ä»¥è¢« ``pure`` å’Œ ``view`` 函数所覆盖, + 而 ``view`` 函数å¯ä»¥è¢« ``pure`` 函数所覆盖。 + åŒæ—¶ï¼Œå…¬å…±çŠ¶æ€å˜é‡è¢«è®¤ä¸ºæ˜¯ ``view``,甚至是 ``pure``,如果它们是常é‡ã€‚ -Inline Assembly +内è”汇编 --------------- -* Disallow ``.`` in user-defined function and variable names in inline assembly. - It is still valid if you use Solidity in Yul-only mode. +* 在用户定义的函数和å˜é‡å称中,ä¸å…许在内è”汇编中使用 ``.``。 + 如果您在“仅Yulâ€æ¨¡å¼ä¸‹ä½¿ç”¨Solidity,它ä»ç„¶æœ‰æ•ˆã€‚ -* Slot and offset of storage pointer variable ``x`` are accessed via ``x.slot`` - and ``x.offset`` instead of ``x_slot`` and ``x_offset``. +* 存储指针å˜é‡ ``x`` 的槽和å移é‡é€šè¿‡ ``x.slot`` å’Œ ``x.offset`` 访问, + 而ä¸æ˜¯ ``x_slot`` å’Œ ``x_offset``。 -Removal of Unused or Unsafe Features +移除未使用或ä¸å®‰å…¨çš„功能 ==================================== -Mappings outside Storage +存储之外的映射关系 ------------------------ -* If a struct or array contains a mapping, it can only be used in storage. - Previously, mapping members were silently skipped in memory, which - is confusing and error-prone. +* 如果一个结构或数组包å«ä¸€ä¸ªæ˜ å°„,它åªèƒ½åœ¨å­˜å‚¨ä¸­ä½¿ç”¨ã€‚ + 以å‰ï¼Œæ˜ å°„æˆå‘˜åœ¨å†…存中被默默地跳过,这让人困惑,也容易出错。 -* Assignments to structs or arrays in storage does not work if they contain - mappings. - Previously, mappings were silently skipped during the copy operation, which - is misleading and error-prone. +* 如果存储中的结构或数组包å«æ˜ å°„,则对其进行赋值是ä¸å¯è¡Œçš„。 + 以å‰ï¼Œåœ¨å¤åˆ¶æ“作过程中,映射会被默默地跳过,这是一ç§è¯¯å¯¼ï¼Œè€Œä¸”容易出错。 -Functions and Events +函数和事件 -------------------- -* Visibility (``public`` / ``internal``) is not needed for constructors anymore: - To prevent a contract from being created, it can be marked ``abstract``. - This makes the visibility concept for constructors obsolete. +* 构造函数ä¸å†éœ€è¦å¯è§æ€§ï¼ˆ ``public`` / ``internal``)了。 + 为了防止åˆçº¦è¢«åˆ›å»ºï¼Œå¯ä»¥å°†å…¶æ ‡è®°ä¸º ``abstract``。 + 这使得构造函数的å¯è§æ€§æ¦‚念å˜å¾—过时了。 -* Type Checker: Disallow ``virtual`` for library functions: - Since libraries cannot be inherited from, library functions should not be virtual. +* 类型检查器:ä¸å…许库函数为 ``virtual``: + 由于库åˆçº¦ä¸èƒ½è¢«ç»§æ‰¿ï¼Œåº“函数ä¸åº”该被标记为 virtual。 -* Multiple events with the same name and parameter types in the same - inheritance hierarchy are disallowed. +* ä¸å…许在åŒä¸€ç»§æ‰¿å±‚次中具有相åŒå称和å‚数类型的多个事件。 -* ``using A for B`` only affects the contract it is mentioned in. - Previously, the effect was inherited. Now, you have to repeat the ``using`` - statement in all derived contracts that make use of the feature. +* ``using A for B`` åªå½±å“到它所æ到的åˆçº¦ã€‚以å‰ï¼Œè¿™ç§å½±å“是继承的。 + 现在,您必须在所有使用该特性的派生åˆçº¦ä¸­é‡å¤ ``using`` 语å¥ã€‚ -Expressions +è¡¨è¾¾å¼ ----------- -* Shifts by signed types are disallowed. - Previously, shifts by negative amounts were allowed, but reverted at runtime. +* 有符å·ç±»åž‹çš„移ä½æ˜¯ä¸å…许的。以å‰ï¼Œå…许负数的移ä½ï¼Œä½†å®ƒåœ¨è¿è¡Œæ—¶ä¼šè¢«è¿˜åŽŸã€‚ -* The ``finney`` and ``szabo`` denominations are removed. - They are rarely used and do not make the actual amount readily visible. Instead, explicit - values like ``1e20`` or the very common ``gwei`` can be used. +* ``finney`` å’Œ ``szabo`` çš„é¢é¢è¢«åˆ é™¤ã€‚它们很少被使用,并且ä¸èƒ½ä½¿å®žé™…的金é¢æ¸…æ™°å¯è§ã€‚ + 相å,å¯ä»¥ä½¿ç”¨æ˜Žç¡®çš„数值,如 ``1e20`` 或éžå¸¸å¸¸è§çš„ ``gwei``。 -Declarations +声明 ------------ -* The keyword ``var`` cannot be used anymore. - Previously, this keyword would parse but result in a type error and - a suggestion about which type to use. Now, it results in a parser error. +* 关键字 ``var`` ä¸èƒ½å†ä½¿ç”¨äº†ã€‚ + 以å‰ï¼Œè¿™ä¸ªå…³é”®è¯å¯ä»¥è§£æžï¼Œä½†ä¼šå¯¼è‡´ä¸€ä¸ªç±»åž‹é”™è¯¯ï¼Œ + 并建议使用哪ç§ç±»åž‹ã€‚现在,它导致一个解æžå™¨é”™è¯¯ã€‚ -Interface Changes +接å£å˜åŒ– ================= -* JSON AST: Mark hex string literals with ``kind: "hexString"``. -* JSON AST: Members with value ``null`` are removed from JSON output. -* NatSpec: Constructors and functions have consistent userdoc output. +* JSON AST:用 ``kind: "hexString"`` æ¥æ ‡è®°å六进制字符串文本。 +* JSON AST:值为 ``null`` çš„æˆå‘˜å°†ä»ŽJSON输出中删除。 +* NatSpec:构造器和函数有一致的用户文档输出。 -How to update your code +å¦‚ä½•æ›´æ–°æ‚¨çš„ä»£ç  ======================= -This section gives detailed instructions on how to update prior code for every breaking change. - -* Change ``x.f.value(...)()`` to ``x.f{value: ...}()``. Similarly ``(new C).value(...)()`` to - ``new C{value: ...}()`` and ``x.f.gas(...).value(...)()`` to ``x.f{gas: ..., value: ...}()``. -* Change ``now`` to ``block.timestamp``. -* Change types of right operand in shift operators to unsigned types. For example change ``x >> (256 - y)`` to - ``x >> uint(256 - y)``. -* Repeat the ``using A for B`` statements in all derived contracts if needed. -* Remove the ``public`` keyword from every constructor. -* Remove the ``internal`` keyword from every constructor and add ``abstract`` to the contract (if not already present). -* Change ``_slot`` and ``_offset`` suffixes in inline assembly to ``.slot`` and ``.offset``, respectively. +本节详细说明了如何为æ¯ä¸€ä¸ªçªç ´æ€§å˜åŒ–æ›´æ–°å…ˆå‰çš„代ç ã€‚ + +* å°† ``x.f.value(...)()`` 改为 ``x.f{value: ...}()``。类似地, ``(new C).value(...)()`` 改为 + ``new C{value: ...}()``, ``x.f.gas(...).value(...)()`` 改为 ``x.f{gas: ..., value: ...}()``。 +* å°† ``now`` 改为 ``block.timestamp``. +* 将移ä½è¿ç®—符中的å³æ“作数的类型改为无符å·ç±»åž‹ã€‚ + 例如,将 ``x >> (256 - y)`` 改为 ``x >> uint(256 - y)``。 +* 如果需è¦ï¼Œåœ¨æ‰€æœ‰æ´¾ç”Ÿåˆçº¦ä¸­é‡å¤ ``using A for B`` 的语å¥ã€‚ +* 从æ¯ä¸ªæž„造函数中删除 ``public`` 关键字。 +* 从æ¯ä¸ªæž„造函数中删除 ``internal`` 关键字,并在åˆçº¦ä¸­æ·»åŠ  ``abstract`` (如果还没有存在)。 +* 将内è”汇编中的 ``_slot`` å’Œ ``_offset`` åŽç¼€åˆ†åˆ«æ”¹ä¸º ``.slot`` å’Œ ``.offset``。 diff --git a/docs/080-breaking-changes.rst b/docs/080-breaking-changes.rst index 524d12ac3b58..a546e91074f3 100644 --- a/docs/080-breaking-changes.rst +++ b/docs/080-breaking-changes.rst @@ -1,176 +1,178 @@ ******************************** -Solidity v0.8.0 Breaking Changes +Solidity v0.8.0 çªç ´æ€§å˜åŒ– ******************************** -This section highlights the main breaking changes introduced in Solidity -version 0.8.0. -For the full list check -`the release changelog `_. +本节强调了 Solidity 0.8.0 版本中引入的主è¦çªç ´æ€§å˜åŒ–。对于完整的列表,请查看 +`版本更新日志 `_。 -Silent Changes of the Semantics +语义的微å°å˜åŒ– =============================== +<<<<<<< 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 - Checks for overflow are very common, so we made them the default to increase readability of code, - even if it comes at a slight increase of gas costs. + 溢出的检查是éžå¸¸æ™®é的,所以我们把它作为默认的检查, + 以增加代ç çš„å¯è¯»æ€§ï¼Œå³ä½¿å®ƒæ˜¯ä»¥ç•¥å¾®å¢žåŠ gasæˆæœ¬ä¸ºä»£ä»·çš„。 -* ABI coder v2 is activated by default. +* 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 - Note that ABI coder v2 supports more types than v1 and performs more sanity checks on the inputs. - ABI coder v2 makes some function calls more expensive and it can also make contract calls - revert that did not revert with ABI coder v1 when they contain data that does not conform to the - parameter types. + 请注æ„,ABI coder v2比v1支æŒæ›´å¤šçš„类型,并对输入进行更多的åˆç†æ€§æ£€æŸ¥ã€‚ + ABI coder v2使一些函数调用更加昂贵,而且当åˆçº¦ä¸­åŒ…å«ä¸ç¬¦åˆå‚数类型的数æ®æ—¶ï¼Œå®ƒè¿˜ä¼šä½¿åˆçº¦è°ƒç”¨å›žé€€ï¼Œ + 而在ABI coder v1中则没有回退。 -* Exponentiation is right associative, i.e., the expression ``a**b**c`` is parsed as ``a**(b**c)``. - Before 0.8.0, it was parsed as ``(a**b)**c``. +* 指数是å³è”çš„ï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œè¡¨è¾¾å¼ ``a**b**c`` 被解æžä¸º ``a**(b**c)``。 + 在0.8.0之å‰ï¼Œå®ƒè¢«è§£æžä¸º ``(a**b)**c``。 - This is the common way to parse the exponentiation operator. + 这是解æžæŒ‡æ•°è¿ç®—符的常用方法。 -* Failing assertions and other internal checks like division by zero or arithmetic overflow do - not use the invalid opcode but instead the revert opcode. - More specifically, they will use error data equal to a function call to ``Panic(uint256)`` with an error code specific - to the circumstances. +* 失败的断言和其他内部检查,如除以零或算术溢出,ä¸ä½¿ç”¨æ— æ•ˆçš„æ“作ç ï¼Œè€Œæ˜¯ä½¿ç”¨æ¢å¤æ“作ç ã€‚ + 更具体地说,它们将使用等于对 ``Panic(uint256)`` 的函数调用的错误数æ®ï¼Œå…¶é”™è¯¯ä»£ç æ˜¯é’ˆå¯¹å…·ä½“情况的。 - This will save gas on errors while it still allows static analysis tools to distinguish - these situations from a revert on invalid input, like a failing ``require``. + 这将节çœé”™è¯¯çš„gas,åŒæ—¶å®ƒä»ç„¶å…许é™æ€åˆ†æžå·¥å…·å°†è¿™äº›æƒ…况与无效输入的æ¢å¤åŒºåˆ†å¼€æ¥ï¼Œ + 比如一个失败的 ``require``。 -* If a byte array in storage is accessed whose length is encoded incorrectly, a panic is caused. - A contract cannot get into this situation unless inline assembly is used to modify the raw representation of storage byte arrays. +* 如果访问存储中的一个字节数组,其长度被错误地编ç ï¼Œå°±ä¼šå¼•èµ·panic错误。 + åˆçº¦ä¸ä¼šå‡ºçŽ°è¿™ç§æƒ…况,除éžä½¿ç”¨å†…è”汇编æ¥ä¿®æ”¹å­˜å‚¨å­—节数组的原始表示。 -* If constants are used in array length expressions, previous versions of Solidity would use arbitrary precision - in all branches of the evaluation tree. Now, if constant variables are used as intermediate expressions, - their values will be properly rounded in the same way as when they are used in run-time expressions. +* 如果常数被用于数组长度表达å¼ä¸­ï¼ŒSolidity çš„å…ˆå‰ç‰ˆæœ¬å°†åœ¨è¯„估树的所有分支中使用任æ„精度。 + 现在,如果常é‡å˜é‡è¢«ç”¨ä½œä¸­é—´è¡¨è¾¾å¼ï¼Œå®ƒä»¬çš„值将以与它们在è¿è¡Œæ—¶è¡¨è¾¾å¼ä¸­ä½¿ç”¨æ—¶ç›¸åŒçš„æ–¹å¼è¢«æ­£ç¡®èˆå…¥ã€‚ -* The type ``byte`` has been removed. It was an alias of ``bytes1``. +* 类型 ``byte`` å·²ç»è¢«åˆ é™¤ã€‚它是 ``bytes1`` 的别å。 -New Restrictions +æ–°çš„é™åˆ¶æ¡ä»¶ ================ -This section lists changes that might cause existing contracts to not compile anymore. +本节列出了å¯èƒ½å¯¼è‡´çŽ°æœ‰åˆçº¦ä¸å†ç¼–译的å˜åŒ–。 +<<<<<<< HEAD +* 有一些与字é¢å¸¸é‡çš„显å¼è½¬æ¢æœ‰å…³çš„æ–°é™åˆ¶ã€‚以å‰åœ¨ä»¥ä¸‹æƒ…况下的行为å¯èƒ½æ˜¯æ¨¡ç³Šçš„: +======= * There are new restrictions related to explicit conversions of literals. The previous behavior in the following cases was likely ambiguous: - - 1. Explicit conversions from negative literals and literals larger than ``type(uint160).max`` to - ``address`` are disallowed. - 2. Explicit conversions between literals and an integer type ``T`` are only allowed if the literal - lies between ``type(T).min`` and ``type(T).max``. In particular, replace usages of ``uint(-1)`` - with ``type(uint).max``. - 3. Explicit conversions between literals and enums are only allowed if the literal can - represent a value in the enum. - 4. Explicit conversions between literals and ``address`` type (e.g. ``address(literal)``) have the - type ``address`` instead of ``address payable``. One can get a payable address type by using an - explicit conversion, i.e., ``payable(literal)``. - -* :ref:`Address literals` have the type ``address`` instead of ``address - payable``. They can be converted to ``address payable`` by using an explicit conversion, e.g. - ``payable(0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF)``. - -* There are new restrictions on explicit type conversions. The conversion is only allowed when there - is at most one change in sign, width or type-category (``int``, ``address``, ``bytesNN``, etc.). - To perform multiple changes, use multiple conversions. - - Let us use the notation ``T(S)`` to denote the explicit conversion ``T(x)``, where, ``T`` and - ``S`` are types, and ``x`` is any arbitrary variable of type ``S``. An example of such a - disallowed conversion would be ``uint16(int8)`` since it changes both width (8 bits to 16 bits) - and sign (signed integer to unsigned integer). In order to do the conversion, one has to go - through an intermediate type. In the previous example, this would be ``uint16(uint8(int8))`` or - ``uint16(int16(int8))``. Note that the two ways to convert will produce different results e.g., - for ``-1``. The following are some examples of conversions that are disallowed by this rule. - - - ``address(uint)`` and ``uint(address)``: converting both type-category and width. Replace this by - ``address(uint160(uint))`` and ``uint(uint160(address))`` respectively. - - ``payable(uint160)``, ``payable(bytes20)`` and ``payable(integer-literal)``: converting both - type-category and state-mutability. Replace this by ``payable(address(uint160))``, - ``payable(address(bytes20))`` and ``payable(address(integer-literal))`` respectively. Note that - ``payable(0)`` is valid and is an exception to the rule. - - ``int80(bytes10)`` and ``bytes10(int80)``: converting both type-category and sign. Replace this by - ``int80(uint80(bytes10))`` and ``bytes10(uint80(int80)`` respectively. - - ``Contract(uint)``: converting both type-category and width. Replace this by - ``Contract(address(uint160(uint)))``. - - These conversions were disallowed to avoid ambiguity. For example, in the expression ``uint16 x = - uint16(int8(-1))``, the value of ``x`` would depend on whether the sign or the width conversion - was applied first. - -* Function call options can only be given once, i.e. ``c.f{gas: 10000}{value: 1}()`` is invalid and has to be changed to ``c.f{gas: 10000, value: 1}()``. - -* The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed. - +>>>>>>> english/develop + + 1. ä¸å…许从负数字段和大于 ``type(uint160).max`` 的字段显å¼è½¬æ¢ä¸º ``address``。 + 2. åªæœ‰å½“å­—é¢å¸¸é‡ä½äºŽ ``type(T).min`` å’Œ ``type(T).max`` 之间时, + æ‰å…许字é¢å¸¸é‡ä¸Žæ•´æ•°ç±»åž‹ ``T`` 之间的明确转æ¢ã€‚ + 特别的是,用 ``type(uint).max`` 代替 ``uint(-1)`` 的使用。 + 3. åªæœ‰å½“å­—é¢å¸¸é‡èƒ½å¤Ÿä»£è¡¨æžšä¸¾ä¸­çš„一个值时,æ‰å…许字é¢å¸¸é‡å’Œæžšä¸¾ä¹‹é—´çš„显å¼è½¬æ¢ã€‚ + 4. å­—é¢å¸¸é‡å’Œ ``address`` 类型之间的显å¼è½¬æ¢ï¼ˆä¾‹å¦‚, ``address(literal)``)是 ``address`` 类型, + 而ä¸æ˜¯ ``address payable`` 类型。通过使用显å¼è½¬æ¢ï¼Œå³ ``payable(literal)``, + å¯ä»¥å¾—到一个payable类型的地å€ç±»åž‹ã€‚ + +* :ref:`地å€å­—é¢å¸¸é‡ ` 的类型是 ``address``,而ä¸æ˜¯ ``address payable``。 + 它们å¯ä»¥é€šè¿‡æ˜¾å¼çš„转æ¢è½¬æ¢ä¸º ``address payable`` 类型, + 例如: ``payable(0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF)``。 + +* 对显å¼ç±»åž‹è½¬æ¢æœ‰æ–°çš„é™åˆ¶ã€‚åªæœ‰å½“符å·ï¼Œå®½åº¦æˆ–类型类别( ``int``, ``address``, ``bytesNN`` 等) + 有最多一次å˜åŒ–时,æ‰å…许进行转æ¢ã€‚è¦æ‰§è¡Œå¤šä¸ªå˜åŒ–,请使用多个转æ¢ã€‚ + + è®©æˆ‘ä»¬ä½¿ç”¨ç¬¦å· ``T(S)`` æ¥è¡¨ç¤ºæ˜¾å¼è½¬æ¢ ``T(x)``,其中, ``T`` å’Œ ``S`` 是类型, + ``x`` 是 ``S`` 类型的任何任æ„å˜é‡ã€‚è¿™ç§ä¸å…许的转æ¢çš„例å­æ˜¯ ``uint16(int8)``, + 因为它åŒæ—¶æ”¹å˜äº†å®½åº¦ï¼ˆ8ä½åˆ°16ä½ï¼‰å’Œç¬¦å·ï¼ˆæœ‰ç¬¦å·æ•´æ•°åˆ°æ— ç¬¦å·æ•´æ•°ï¼‰ã€‚为了进行转æ¢ï¼Œæˆ‘们必须通过一个中间类型。 + 在å‰é¢çš„例å­ä¸­ï¼Œè¿™å°†æ˜¯ ``uint16(uint8(int8))`` 或者 ``uint16(int16(int8))``。 + 请注æ„,这两ç§è½¬æ¢æ–¹å¼å°†äº§ç”Ÿä¸åŒçš„结果,例如,对于 ``-1``。下é¢æ˜¯è¿™ä¸ªè§„则ä¸å…许的一些转æ¢çš„例å­ã€‚ + + - ``address(uint)`` å’Œ ``uint(address)``:åŒæ—¶è½¬æ¢ç±»åž‹å’Œå®½åº¦ã€‚ + 分别用 ``address(uint160(uint))`` å’Œ ``uint(uint160(address))`` 代替。 + - ``payable(uint160)``, ``payable(bytes20)`` å’Œ ``payable(integer-literal)``: åŒæ—¶è½¬æ¢äº†ç±»åž‹å’ŒçŠ¶æ€å¯å˜æ€§ã€‚ + 分别用 ``payable(address(uint160))``, ``payable(address(bytes20))`` å’Œ + ``payable(address(integer-literal))`` 代替。请注æ„, ``payable(0)`` 是有效的,是规则的例外。 + - ``int80(bytes10)`` å’Œ ``bytes10(int80)``:åŒæ—¶è½¬æ¢äº†ç±»åž‹å’Œç¬¦å·ã€‚ + 分别用 ``int80(uint80(bytes10))`` å’Œ ``bytes10(uint80(int80))`` 代替。 + - ``Contract(uint)``: åŒæ—¶è½¬æ¢ç±»åž‹å’Œå®½åº¦ã€‚用 ``Contract(address(uint160(uint)))`` 代替。 + + 这些转æ¢æ˜¯ä¸å…许的,以é¿å…æ­§ä¹‰ã€‚ä¾‹å¦‚ï¼Œåœ¨è¡¨è¾¾å¼ ``uint16 x = uint16(int8(-1))`` 中, + ``x`` 的值å–决于是先应用符å·è¿˜æ˜¯å®½åº¦è½¬æ¢ã€‚ + +* 函数调用选项åªèƒ½ç»™å‡ºä¸€æ¬¡ï¼Œå³ ``c.f{gas: 10000}{value: 1}()`` 是无效的, + å¿…é¡»æ”¹æˆ ``c.f{gas: 10000, value: 1}()``。 + +* 全局函数 ``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`` definitions cannot contain more than 256 members. +* ``enum`` 定义包å«çš„æˆå‘˜ä¸èƒ½è¶…过256个。 - This will make it safe to assume that the underlying type in the ABI is always ``uint8``. + 这将使我们å¯ä»¥å®‰å…¨åœ°å‡è®¾ABI中的底层类型总是 ``uint8``。 -* Declarations with the name ``this``, ``super`` and ``_`` are disallowed, with the exception of - public functions and events. The exception is to make it possible to declare interfaces of contracts - implemented in languages other than Solidity that do permit such function names. +* 除了公共函数和事件之外,ä¸å…许使用 ``this``, ``super`` å’Œ ``_`` çš„å称进行声明。 + 这个例外是为了使声明用Solidity以外的语言实现的åˆçº¦çš„接å£æˆä¸ºå¯èƒ½ï¼Œè¿™äº›è¯­è¨€ç¡®å®žå…许这ç§å‡½æ•°å称。 -* Remove support for the ``\b``, ``\f``, and ``\v`` escape sequences in code. - They can still be inserted via hexadecimal escapes, e.g. ``\x08``, ``\x0c``, and ``\x0b``, respectively. +* 移除对代ç ä¸­çš„ ``\b``, ``\f`` å’Œ ``\v`` 转义åºåˆ—的支æŒã€‚ + 它们ä»ç„¶å¯ä»¥é€šè¿‡å六进制转义æ’入,例如:分别是 ``\x08``, ``\x0c``, å’Œ ``\x0b``。 -* The global variables ``tx.origin`` and ``msg.sender`` have the type ``address`` instead of - ``address payable``. One can convert them into ``address payable`` by using an explicit - conversion, i.e., ``payable(tx.origin)`` or ``payable(msg.sender)``. +* 全局å˜é‡ ``tx.origin`` å’Œ ``msg.sender`` 的类型是 ``address`` 而ä¸æ˜¯ ``address payable``。 + 我们å¯ä»¥é€šè¿‡æ˜¾å¼è½¬æ¢å°†å®ƒä»¬è½¬æ¢ä¸º ``address payable`` 类型, + å³ ``payable(tx.origin)`` 或 ``payable(msg.sender)``。 - This change was done since the compiler cannot determine whether or not these addresses - are payable or not, so it now requires an explicit conversion to make this requirement visible. + åšè¿™ä¸ªæ”¹å˜æ˜¯å› ä¸ºç¼–译器ä¸èƒ½ç¡®å®šè¿™äº›åœ°å€æ˜¯å¦å¯ä»¥æ”¯ä»˜ï¼Œæ‰€ä»¥çŽ°åœ¨éœ€è¦ä¸€ä¸ªæ˜Žç¡®çš„转æ¢æ¥ä½¿è¿™ä¸ªè¦æ±‚å¯è§ã€‚ -* Explicit conversion into ``address`` type always returns a non-payable ``address`` type. In - particular, the following explicit conversions have the type ``address`` instead of ``address - payable``: +* 显å¼è½¬æ¢ä¸º ``address`` 类型总是返回一个éž-payable类型的 ``address``。 + 特别是,以下显å¼è½¬æ¢çš„类型是 ``address`` 而ä¸æ˜¯ ``address payable``: - - ``address(u)`` where ``u`` is a variable of type ``uint160``. One can convert ``u`` - into the type ``address payable`` by using two explicit conversions, i.e., - ``payable(address(u))``. - - ``address(b)`` where ``b`` is a variable of type ``bytes20``. One can convert ``b`` - into the type ``address payable`` by using two explicit conversions, i.e., - ``payable(address(b))``. - - ``address(c)`` where ``c`` is a contract. Previously, the return type of this - conversion depended on whether the contract can receive Ether (either by having a receive - function or a payable fallback function). The conversion ``payable(c)`` has the type ``address - payable`` and is only allowed when the contract ``c`` can receive Ether. In general, one can - always convert ``c`` into the type ``address payable`` by using the following explicit - conversion: ``payable(address(c))``. Note that ``address(this)`` falls under the same category - as ``address(c)`` and the same rules apply for it. + - ``address(u)`` 其中 ``u`` 是一个 ``uint160`` 类型的å˜é‡ã€‚ + 我们å¯ä»¥é€šè¿‡ä¸¤ä¸ªæ˜¾å¼è½¬æ¢å°† ``u`` 转æ¢ä¸º ``address payable`` ç±»åž‹ï¼Œå³ ``payable(address(u))``。 + - ``address(b)`` 其中 ``b`` 是一个 ``bytes20`` 类型的å˜é‡ã€‚ + 我们å¯ä»¥é€šè¿‡ä¸¤ä¸ªæ˜¾å¼è½¬æ¢å°† ``b`` 转æ¢ä¸º ``address payable`` ç±»åž‹ï¼Œå³ ``payable(address(b))``。 + - ``address(c)`` 其中 ``c`` 是一个åˆçº¦ã€‚以å‰ï¼Œè¿™ç§è½¬æ¢çš„返回类型å–决于åˆçº¦æ˜¯å¦å¯ä»¥æŽ¥æ”¶ä»¥å¤ª + (è¦ä¹ˆæœ‰ä¸€ä¸ªreceive函数,è¦ä¹ˆæœ‰ä¸€ä¸ªpayable类型的fallback函数)。 + è½¬æ¢ ``payable(c)`` 的类型为 ``address payable``,åªæœ‰å½“åˆçº¦ ``c`` å¯ä»¥æŽ¥æ”¶ä»¥å¤ªæ—¶æ‰å…许。 + 一般æ¥è¯´ï¼Œäººä»¬æ€»æ˜¯å¯ä»¥é€šè¿‡ä½¿ç”¨ä»¥ä¸‹æ˜¾å¼è½¬æ¢å°† ``c`` 转æ¢ä¸º ``address payable`` 的类型: + ``payable(address(c))``。请注æ„, ``address(this)`` 与 ``address(c)`` 属于åŒä¸€ç±»åˆ«ï¼Œ + åŒæ ·çš„规则也适用于它。 -* The ``chainid`` builtin in inline assembly is now considered ``view`` instead of ``pure``. +* 内è”汇编中的 ``chainid`` 现在被认为是 ``view`` 而ä¸æ˜¯ ``pure``。 -* Unary negation cannot be used on unsigned integers anymore, only on signed integers. +* 一元求åä¸èƒ½å†ç”¨äºŽæ— ç¬¦å·æ•´æ•°ï¼Œåªèƒ½ç”¨äºŽæœ‰ç¬¦å·æ•´æ•°ã€‚ -Interface Changes +接å£å˜åŒ– ================= -* The output of ``--combined-json`` has changed: JSON fields ``abi``, ``devdoc``, ``userdoc`` and - ``storage-layout`` are sub-objects now. Before 0.8.0 they used to be serialised as strings. +* ``--combined-json`` 的输出已ç»æ”¹å˜ã€‚JSON字段 ``abi``, ``devdoc``, ``userdoc`` å’Œ + ``storage-layout`` 现在是å­å¯¹è±¡ã€‚在0.8.0之å‰ï¼Œå®ƒä»¬æ›¾è¢«åºåˆ—化为字符串。 -* The "legacy AST" has been removed (``--ast-json`` on the commandline interface and ``legacyAST`` for standard JSON). - Use the "compact AST" (``--ast-compact--json`` resp. ``AST``) as replacement. +* “传统AST“ 已被删除( ``--ast-json`` 在命令行界é¢ï¼Œ ``legacyAST`` 用于标准JSON)。 + 使用 “紧凑型ASTâ€ï¼ˆ ``--ast-compact-json`` å‚æ•°. ``AST``)作为替代。 -* The old error reporter (``--old-reporter``) has been removed. +* 旧的错误报告器( ``--old-reporter`` )已ç»è¢«åˆ é™¤ã€‚ -How to update your code +å¦‚ä½•æ›´æ–°æ‚¨çš„ä»£ç  ======================= -- If you rely on wrapping arithmetic, surround each operation with ``unchecked { ... }``. -- Optional: If you use SafeMath or a similar library, change ``x.add(y)`` to ``x + y``, ``x.mul(y)`` to ``x * y`` etc. -- Add ``pragma abicoder v1;`` if you want to stay with the old ABI coder. -- Optionally remove ``pragma experimental ABIEncoderV2`` or ``pragma abicoder v2`` since it is redundant. -- Change ``byte`` to ``bytes1``. -- Add intermediate explicit type conversions if required. -- Combine ``c.f{gas: 10000}{value: 1}()`` to ``c.f{gas: 10000, value: 1}()``. -- Change ``msg.sender.transfer(x)`` to ``payable(msg.sender).transfer(x)`` or use a stored variable of ``address payable`` type. -- Change ``x**y**z`` to ``(x**y)**z``. +- 如果您ä¾èµ–包装算术,请用 ``unchecked { ... }`` 包裹æ¯ä¸ªæ“作。 +- å¯é€‰ï¼šå¦‚果您使用SafeMath或类似的库,将 ``x.add(y)`` 改为 ``x + y``, ``x.mul(y)`` 改为 ``x * y`` 等等。 +- 如果您想继续使用旧的ABIç¼–ç å™¨ï¼Œè¯·æ·»åŠ  ``pragma abicoder v1;``。 +- å¯ä»¥é€‰æ‹©åˆ é™¤ ``pragma experimental ABIEncoderV2`` 或 ``pragma abicoder v2`` 因为它是多余的。 +- å°† ``byte`` 改为 ``bytes1``。 +- 如果需è¦çš„è¯ï¼Œæ·»åŠ ä¸­é—´æ˜¾å¼ç±»åž‹è½¬æ¢ã€‚ +- å°† ``c.f{gas: 10000}{value: 1}()`` åˆå¹¶ä¸º ``c.f{gas: 10000, value: 1}()``。 +- å°† ``msg.sender.transfer(x)`` 改为 ``payable(msg.sender).transfer(x)`` + 或者使用 ``address payable`` 类型的存储å˜é‡ã€‚ +- å°† ``x**y**z`` 改为 ``(x**y)**z``。 - Use inline assembly as a replacement for ``log0``, ..., ``log4``. -- Negate unsigned integers by subtracting them from the maximum value of the type and adding 1 (e.g. ``type(uint256).max - x + 1``, while ensuring that ``x`` is not zero) +- 将无符å·æ•´æ•°å–å的方法是从该类型的最大值中å‡åŽ»è¯¥æ•´æ•°ï¼Œå¹¶åŠ ä¸Š1(例如, ``type(uint256).max - x + 1``,åŒæ—¶ç¡®ä¿ `x` ä¸ä¸ºé›¶ï¼‰ diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 41967dd46d6b..9e9a894b0a1c 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -3,241 +3,227 @@ .. _ABI: ************************** -Contract ABI Specification +åˆçº¦ABI规范 ************************** -Basic Design +基本设计 ============ -The Contract Application Binary Interface (ABI) is the standard way to interact with contracts in the Ethereum ecosystem, both -from outside the blockchain and for contract-to-contract interaction. Data is encoded according to its type, -as described in this specification. The encoding is not self describing and thus requires a schema in order to decode. +åˆçº¦åº”用二进制接å£ï¼ˆABI)是在以太åŠç”Ÿæ€ç³»ç»Ÿä¸­ä¸Žåˆçº¦äº¤äº’的标准方å¼ï¼Œ +包括从区å—链外部和åˆçº¦é—´çš„交互。数æ®æ ¹æ®å…¶ç±»åž‹è¿›è¡Œç¼–ç ï¼Œå¦‚本规范中所述。 +ç¼–ç ä¸æ˜¯è‡ªæ述的,因此需è¦ä¸€ç§ç‰¹å®šçš„概è¦ï¼ˆschema)æ¥è¿›è¡Œè§£ç ã€‚ -We assume that the interface functions of a contract are strongly typed, known at compilation time and static. -We assume that all contracts will have the interface definitions of any contracts they call available at compile-time. +我们å‡è®¾åˆçº¦çš„接å£å‡½æ•°æ˜¯å¼ºç±»åž‹çš„,在编译时就知é“,并且是é™æ€çš„。 +我们å‡è®¾æ‰€æœ‰åˆçº¦åœ¨ç¼–译时都有它们所调用的任何åˆçº¦çš„接å£å®šä¹‰ã€‚ -This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. +本规范ä¸æ¶‰åŠå…¶æŽ¥å£æ˜¯åŠ¨æ€çš„或其他åªæœ‰åœ¨è¿è¡Œæ—¶æ‰çŸ¥é“çš„åˆçº¦ã€‚ .. _abi_function_selector: .. index:: ! selector; of a function -Function Selector +函数选择器 ================= -The first four bytes of the call data for a function call specifies the function to be called. It is the -first (left, high-order in big-endian) four bytes of the Keccak-256 hash of the signature of -the function. The signature is defined as the canonical expression of the basic prototype without data -location specifier, i.e. -the function name with the parenthesised list of parameter types. Parameter types are split by a single -comma — no spaces are used. +一个函数调用数æ®çš„å‰å››ä¸ªå­—节指定了è¦è°ƒç”¨çš„函数。 +它是函数签åçš„ Keccak-256 哈希值的å‰4字节(高ä½åœ¨å·¦çš„大端åºï¼‰ã€‚ +ç­¾å被定义为基本原型的典型表达,没有数æ®ä½ç½®çš„指定, +也就是带有括å·çš„å‚数类型列表的函数å。å‚数类型由一个逗å·åˆ†å‰² - ä¸ä½¿ç”¨ç©ºæ ¼ã€‚ .. note:: - The return type of a function is not part of this signature. In - :ref:`Solidity's function overloading ` return types are not considered. - The reason is to keep function call resolution context-independent. - The :ref:`JSON description of the ABI` however contains both inputs and outputs. + 一个函数的返回类型ä¸æ˜¯è¿™ä¸ªç­¾å的一部分。在 :ref:`Solidity的函数é‡è½½ ` 中, + 返回类型ä¸è¢«è€ƒè™‘。原因是为了ä¿æŒå‡½æ•°è°ƒç”¨è§£æžä¸Žä¸Šä¸‹æ–‡æ— å…³ã€‚ + 然而 :ref:`JSONæè¿°çš„ABI ` å´åŒæ—¶åŒ…å«äº†è¾“入和输出。 -Argument Encoding +å‚æ•°ç¼–ç  ================= -Starting from the fifth byte, the encoded arguments follow. This encoding is also used in -other places, e.g. the return values and also event arguments are encoded in the same way, -without the four bytes specifying the function. +从第5字节开始是被编ç çš„å‚数。这ç§ç¼–ç ä¹Ÿè¢«ç”¨åœ¨å…¶ä»–地方, +比如,返回值和事件的å‚数也会被用åŒæ ·çš„æ–¹å¼è¿›è¡Œç¼–ç ï¼Œ +而用æ¥æŒ‡å®šå‡½æ•°çš„4个字节则ä¸éœ€è¦å†è¿›è¡Œç¼–ç ã€‚ -Types +类型 ===== -The following elementary types exist: +以下是基础类型: -- ``uint``: unsigned integer type of ``M`` bits, ``0 < M <= 256``, ``M % 8 == 0``. e.g. ``uint32``, ``uint8``, ``uint256``. +- ``uint``: ``M`` ä½çš„无符å·æ•´æ•°ï¼Œ ``0 < M <= 256``, ``M % 8 == 0``。例如: ``uint32``, ``uint8``, ``uint256``。 -- ``int``: two's complement signed integer type of ``M`` bits, ``0 < M <= 256``, ``M % 8 == 0``. +- ``int``: 以 2 çš„è¡¥ç ä½œä¸ºç¬¦å·çš„ ``M`` ä½æ•´æ•°ï¼Œ ``0 < M <= 256``, ``M % 8 == 0``。 -- ``address``: equivalent to ``uint160``, except for the assumed interpretation and language typing. - For computing the function selector, ``address`` is used. +- ``address``: 除了字é¢ä¸Šçš„æ„æ€å’Œè¯­è¨€ç±»åž‹çš„区别以外,等价于 ``uint160``, + 在计算和函数选择器中,通常使用 ``address``。 -- ``uint``, ``int``: synonyms for ``uint256``, ``int256`` respectively. For computing the function - selector, ``uint256`` and ``int256`` have to be used. +- ``uint``, ``int``: ``uint256``, ``int256`` å„自的åŒä¹‰è¯. + 在计算和函数选择器中,通常使用 ``uint256`` å’Œ ``int256``。 -- ``bool``: equivalent to ``uint8`` restricted to the values 0 and 1. For computing the function selector, ``bool`` is used. +- ``bool``: 等价于 ``uint8``,å–值é™å®šä¸º 0 或 1。在计算和函数选择器中,通常使用 ``bool``。 -- ``fixedx``: signed fixed-point decimal number of ``M`` bits, ``8 <= M <= 256``, - ``M % 8 == 0``, and ``0 < N <= 80``, which denotes the value ``v`` as ``v / (10 ** N)``. +- ``fixedx``: ``M`` ä½çš„有符å·çš„固定å°æ•°ä½çš„å进制数字, ``8 <= M <= 256``, + ``M % 8 == 0``, 且 ``0 < N <= 80``, 其中值 ``v`` 是 ``v / (10 ** N)``。 -- ``ufixedx``: unsigned variant of ``fixedx``. +- ``ufixedx``: 无符å·çš„ ``fixedx``. -- ``fixed``, ``ufixed``: synonyms for ``fixed128x18``, ``ufixed128x18`` respectively. For - computing the function selector, ``fixed128x18`` and ``ufixed128x18`` have to be used. +- ``fixed``, ``ufixed``: ``fixed128x18``, ``ufixed128x18`` å„自的åŒä¹‰è¯ã€‚ + 在计算和函数选择器中,通常使用 ``fixed128x18`` å’Œ ``ufixed128x18``。 -- ``bytes``: binary type of ``M`` bytes, ``0 < M <= 32``. +- ``bytes``: ``M`` 字节的二进制类型, ``0 < M <= 32``。 -- ``function``: an address (20 bytes) followed by a function selector (4 bytes). Encoded identical to ``bytes24``. +- ``function``: 一个地å€ï¼ˆ20 字节)之åŽç´§è·Ÿä¸€ä¸ªå‡½æ•°é€‰æ‹©å™¨ (4 字节)。编ç ä¹‹åŽç­‰ä»·äºŽ ``bytes24``。 -The following (fixed-size) array type exists: +以下是定长数组类型: -- ``[M]``: a fixed-length array of ``M`` elements, ``M >= 0``, of the given type. +- ``[M]``: 有 ``M`` 个元素的定长数组, ``M >= 0``,数组元素为给定类型。 .. note:: - While this ABI specification can express fixed-length arrays with zero elements, they're not supported by the compiler. + 虽然这个ABI规范å¯ä»¥è¡¨è¾¾é›¶å…ƒç´ çš„固定长度数组,但编译器ä¸æ”¯æŒå®ƒä»¬ã€‚ -The following non-fixed-size types exist: +以下是éžå®šé•¿ç±»åž‹ï¼š -- ``bytes``: dynamic sized byte sequence. +- ``bytes``: 动æ€å¤§å°çš„字节åºåˆ—。 -- ``string``: dynamic sized unicode string assumed to be UTF-8 encoded. +- ``string``: 动æ€å¤§å°çš„ unicode 字符串,通常呈现为 UTF-8 ç¼–ç ã€‚ -- ``[]``: a variable-length array of elements of the given type. +- ``[]``: 元素为给定类型的å˜é•¿æ•°ç»„。 -Types can be combined to a tuple by enclosing them inside parentheses, separated by commas: +å¯ä»¥å°†è‹¥å¹²ç±»åž‹æ”¾åˆ°ä¸€å¯¹æ‹¬å·ä¸­ï¼Œç”¨é€—å·åˆ†éš”开,以此æ¥æž„æˆä¸€ä¸ªå…ƒç»„(tuple): -- ``(T1,T2,...,Tn)``: tuple consisting of the types ``T1``, ..., ``Tn``, ``n >= 0`` +- ``(T1,T2,...,Tn)``: ç”± ``T1``,..., ``Tn``, ``n >= 0`` æž„æˆçš„ 元组 -It is possible to form tuples of tuples, arrays of tuples and so on. It is also possible to form zero-tuples (where ``n == 0``). +用元组构æˆå…ƒç»„,用元组构æˆæ•°ç»„等等也是å¯èƒ½çš„。å¦å¤–也å¯ä»¥æž„æˆé›¶å…ƒç»„(当 ``n == 0`` 时)。 -Mapping Solidity to ABI types +å°†Solidity映射到ABI类型 ----------------------------- -Solidity supports all the types presented above with the same names with the -exception of tuples. On the other hand, some Solidity types are not supported -by the ABI. The following table shows on the left column Solidity types that -are not part of the ABI, and on the right column the ABI types that represent -them. - -+-------------------------------+-----------------------------------------------------------------------------+ -| Solidity | ABI | -+===============================+=============================================================================+ -|:ref:`address payable
`|``address`` | -+-------------------------------+-----------------------------------------------------------------------------+ -|:ref:`contract` |``address`` | -+-------------------------------+-----------------------------------------------------------------------------+ -|:ref:`enum` |``uint8`` | -+-------------------------------+-----------------------------------------------------------------------------+ -|:ref:`user defined value types |its underlying value type | -|` | | -+-------------------------------+-----------------------------------------------------------------------------+ -|:ref:`struct` |``tuple`` | -+-------------------------------+-----------------------------------------------------------------------------+ +Solidity 支æŒä¸Šé¢ä»‹ç»çš„除了元祖之外的所有åŒå类型。 +å¦ä¸€æ–¹é¢ï¼Œä¸€äº› Solidity 类型ä¸è¢« ABI 支æŒã€‚ +下表在左æ æ˜¾ç¤ºäº†ä¸å±žäºŽABIçš„Solidity类型,在å³æ æ˜¾ç¤ºäº†ä»£è¡¨å®ƒä»¬çš„ABI类型。 + ++---------------------------------+-------------------+ +| Solidity | ABI | ++=================================+===================+ +| :ref:`address payable
` | ``address`` | ++---------------------------------+-------------------+ +| :ref:`åˆçº¦` | ``address`` | ++---------------------------------+-------------------+ +| :ref:`枚举` | ``uint8`` | ++---------------------------------+-------------------+ +| :ref:`用户自定义类型 | 其基本值类型 | +| ` | | ++---------------------------------+-------------------+ +| :ref:`结构体 ` | ``元组(tuple)`` | ++---------------------------------+-------------------+ .. warning:: - Before version ``0.8.0`` enums could have more than 256 members and were represented by the - smallest integer type just big enough to hold the value of any member. + 在 ``0.8.0`` 版本之å‰ï¼Œæžšä¸¾å¯ä»¥æœ‰è¶…过256个æˆå‘˜ï¼Œå¹¶ç”±æœ€å°çš„整数类型表示,其大å°åˆšå¥½å¯ä»¥å®¹çº³ä»»ä½•æˆå‘˜çš„值。 -Design Criteria for the Encoding +ç¼–ç çš„设计标准 ================================ -The encoding is designed to have the following properties, which are especially useful if some arguments are nested arrays: +ç¼–ç è¢«è®¾è®¡ä¸ºå…·æœ‰ä»¥ä¸‹å±žæ€§ï¼Œå¦‚果一些å‚数是嵌套的数组,这些属性特别有用: -1. The number of reads necessary to access a value is at most the depth of the value - inside the argument array structure, i.e. four reads are needed to retrieve ``a_i[k][l][r]``. In a - previous version of the ABI, the number of reads scaled linearly with the total number of dynamic - parameters in the worst case. +1. 访问一个值所需的读å–次数最多是å‚数数组结构内的值的深度, + å³éœ€è¦å››æ¬¡è¯»å–次数æ¥æ£€ç´¢ ``a_i[k][l][r]``。 + 在ABIçš„å‰ä¸€ä¸ªç‰ˆæœ¬ä¸­ï¼Œåœ¨æœ€å的情况下,读å–次数的数é‡ä¸ŽåŠ¨æ€å‚数的总数æˆçº¿æ€§æ¯”例。 -2. The data of a variable or an array element is not interleaved with other data and it is - relocatable, i.e. it only uses relative "addresses". +2. å˜é‡æˆ–数组元素的数æ®ä¸ä¸Žå…¶ä»–æ•°æ®äº¤é”™ï¼Œå®ƒæ˜¯å¯é‡å®šä½çš„,å³å®ƒåªä½¿ç”¨ç›¸å¯¹çš„ “地å€â€ã€‚ -Formal Specification of the Encoding +ç¼–ç çš„å½¢å¼åŒ–规范 ==================================== -We distinguish static and dynamic types. Static types are encoded in-place and dynamic types are -encoded at a separately allocated location after the current block. +我们区分了é™æ€å’ŒåŠ¨æ€ç±»åž‹ã€‚é™æ€ç±»åž‹æ˜¯ç›´æŽ¥ç¼–ç çš„, +而动æ€ç±»åž‹æ˜¯åœ¨å½“å‰å—之åŽçš„一个å•ç‹¬åˆ†é…çš„ä½ç½®è¿›è¡Œç¼–ç ã€‚ -**Definition:** The following types are called "dynamic": +**定义:** 以下类型被称为“动æ€â€ï¼š * ``bytes`` * ``string`` -* ``T[]`` for any ``T`` -* ``T[k]`` for any dynamic ``T`` and any ``k >= 0`` -* ``(T1,...,Tk)`` if ``Ti`` is dynamic for some ``1 <= i <= k`` +* ä»»æ„类型 ``T`` 的数组 ``T[]`` +* ä»»æ„动æ€ç±»åž‹ ``T`` 的定长数组 ``T[k]``,其中 ``k >= 0`` +* 由动æ€çš„ ``Ti`` ( ``1 <= i <= k`` )构æˆçš„元组 ``(T1,...,Tk)`` -All other types are called "static". +所有其他类型都被称为“é™æ€â€ã€‚ -**Definition:** ``len(a)`` is the number of bytes in a binary string ``a``. -The type of ``len(a)`` is assumed to be ``uint256``. +**定义:** ``len(a)`` 是一个二进制字符串 ``a`` 的字节长度。 +``len(a)`` 的类型被呈现为 ``uint256``。 -We define ``enc``, the actual encoding, as a mapping of values of the ABI types to binary strings such -that ``len(enc(X))`` depends on the value of ``X`` if and only if the type of ``X`` is dynamic. +æˆ‘ä»¬æŠŠå®žé™…çš„ç¼–ç  ``enc`` 定义为一个由ABI类型到二进制字符串的值的映射, +因而,当且仅当 ``X`` 的类型是动æ€çš„, ``len(enc(X))`` æ‰ä¼šä¾èµ–于 ``X`` 的值。 -**Definition:** For any ABI value ``X``, we recursively define ``enc(X)``, depending -on the type of ``X`` being +**定义:** 对任æ„ABI值 ``X``ï¼Œæˆ‘ä»¬æ ¹æ® ``X`` 的实际类型递归地定义 ``enc(X)``。 -- ``(T1,...,Tk)`` for ``k >= 0`` and any types ``T1``, ..., ``Tk`` +- ``(T1,...,Tk)`` 对于 ``k >= 0`` 且任æ„类型 ``T1``, ..., ``Tk`` ``enc(X) = head(X(1)) ... head(X(k)) tail(X(1)) ... tail(X(k))`` - where ``X = (X(1), ..., X(k))`` and - ``head`` and ``tail`` are defined for ``Ti`` as follows: + 这里, ``X = (X(1), ..., X(k))`` 并且 + ``head`` å’Œ ``tail`` 被定义为如下 ``Ti`` : - if ``Ti`` is static: + 如果 ``Ti`` 是é™æ€ç±»åž‹ï¼š - ``head(X(i)) = enc(X(i))`` and ``tail(X(i)) = ""`` (the empty string) + ``head(X(i)) = enc(X(i))`` å’Œ ``tail(X(i)) = ""`` (空字符串) - otherwise, i.e. if ``Ti`` is dynamic: + å¦åˆ™ï¼Œå³ ``Ti`` 是动æ€ç±»åž‹æ—¶ï¼Œå®ƒä»¬è¢«å®šä¹‰ä¸ºï¼š ``head(X(i)) = enc(len( head(X(1)) ... head(X(k)) tail(X(1)) ... tail(X(i-1)) ))`` ``tail(X(i)) = enc(X(i))`` - Note that in the dynamic case, ``head(X(i))`` is well-defined since the lengths of - the head parts only depend on the types and not the values. The value of ``head(X(i))`` is the offset - of the beginning of ``tail(X(i))`` relative to the start of ``enc(X)``. + 注æ„,在动æ€ç±»åž‹çš„情况下,由于 head 部分的长度仅å–决于类型而éžå€¼ï¼Œæ‰€ä»¥ ``head(X(i))`` 是定义明确的。 + 它的值是从 ``enc(X)`` 的开始算起的, ``tail(X(i))`` 的起始ä½åœ¨ ``head(X(i))`` 中的å移é‡ã€‚ -- ``T[k]`` for any ``T`` and ``k``: +- ``T[k]`` å¯¹äºŽä»»æ„ ``T`` å’Œ ``k``: ``enc(X) = enc((X[0], ..., X[k-1]))`` - i.e. it is encoded as if it were a tuple with ``k`` elements - of the same type. + å³ï¼Œå®ƒå°±åƒæ˜¯ä¸ªç”±ç›¸åŒç±»åž‹çš„ ``k`` 个元素组æˆçš„元组那样被编ç çš„。 -- ``T[]`` where ``X`` has ``k`` elements (``k`` is assumed to be of type ``uint256``): +- ``T[]`` 当 ``X`` 有 ``k`` 个元素 ( ``k`` 的类型为 ``uint256``): ``enc(X) = enc(k) enc((X[0], ..., X[k-1]))`` - i.e. it is encoded as if it were a tuple with ``k`` elements of the same type (resp. an array of static size ``k``), prefixed with - the number of elements. + 也就是说,它被编ç ä¸ºå…·æœ‰ç›¸åŒç±»åž‹çš„ ``k`` 元素的元组(å³é™æ€å¤§å°ä¸º ``k`` 的数组),å‰ç¼€ä¸ºå…ƒç´ çš„æ•°é‡ã€‚ -- ``bytes``, of length ``k`` (which is assumed to be of type ``uint256``): +- 具有 ``k`` 字节长度的 ``bytes``, (å‡è®¾å…¶ç±»åž‹ä¸º ``uint256``): - ``enc(X) = enc(k) pad_right(X)``, i.e. the number of bytes is encoded as a - ``uint256`` followed by the actual value of ``X`` as a byte sequence, followed by - the minimum number of zero-bytes such that ``len(enc(X))`` is a multiple of 32. + ``enc(X) = enc(k) pad_right(X)``,å³ï¼Œå­—节数被编ç ä¸º ``uint256``,紧跟ç€å®žé™…çš„ ``X`` 的字节ç åºåˆ—, + å†åœ¨å‰è¾¹ï¼ˆå·¦è¾¹ï¼‰è¡¥ä¸Šå¯ä»¥ä½¿ ``len(enc(X))`` æˆä¸º 32 çš„å€æ•°çš„最少数é‡çš„ 0 值字节数æ®ã€‚ -- ``string``: +- ``string``: - ``enc(X) = enc(enc_utf8(X))``, i.e. ``X`` is UTF-8 encoded and this value is interpreted - as of ``bytes`` type and encoded further. Note that the length used in this subsequent - encoding is the number of bytes of the UTF-8 encoded string, not its number of characters. + ``enc(X) = enc(enc_utf8(X))``, å³ ``X`` 被 UTF-8 ç¼–ç ï¼Œä¸”在åŽç»­ç¼–ç ä¸­å°†è¿™ä¸ªå€¼è§£é‡Šä¸º ``bytes`` 类型。 + 注æ„,在éšåŽçš„ç¼–ç ä¸­ä½¿ç”¨çš„长度是其 UTF-8 ç¼–ç çš„字符串的字节数,而ä¸æ˜¯å…¶å­—符数。 -- ``uint``: ``enc(X)`` is the big-endian encoding of ``X``, padded on the higher-order - (left) side with zero-bytes such that the length is 32 bytes. -- ``address``: as in the ``uint160`` case -- ``int``: ``enc(X)`` is the big-endian two's complement encoding of ``X``, padded on the higher-order (left) side with ``0xff`` bytes for negative ``X`` and with zero-bytes for non-negative ``X`` such that the length is 32 bytes. -- ``bool``: as in the ``uint8`` case, where ``1`` is used for ``true`` and ``0`` for ``false`` -- ``fixedx``: ``enc(X)`` is ``enc(X * 10**N)`` where ``X * 10**N`` is interpreted as a ``int256``. -- ``fixed``: as in the ``fixed128x18`` case -- ``ufixedx``: ``enc(X)`` is ``enc(X * 10**N)`` where ``X * 10**N`` is interpreted as a ``uint256``. -- ``ufixed``: as in the ``ufixed128x18`` case -- ``bytes``: ``enc(X)`` is the sequence of bytes in ``X`` padded with trailing zero-bytes to a length of 32 bytes. +- ``uint``: ``enc(X)`` 是在 ``X`` 的大端åºç¼–ç çš„高ä½ï¼ˆå·¦ä¾§ï¼‰è¡¥å……若干 0 值字节以使其长度æˆä¸º 32 字节。 +- ``address``: 与 ``uint160`` 的情况相åŒã€‚ +- ``int``: ``enc(X)`` 是在 ``X`` 的大端åºçš„ 2 çš„è¡¥ç ç¼–ç çš„高ä½ï¼ˆå·¦ä¾§ï¼‰æ·»åŠ è‹¥å¹²å­—节数æ®ä»¥ä½¿å…¶é•¿åº¦æˆä¸º 32 字节; + 对于负数,添加值为 ``0xff`` 的字节数æ®ï¼Œå¯¹äºŽæ­£æ•°ï¼Œæ·»åŠ  0 值字节数æ®ã€‚ +- ``bool``: 与 ``uint8`` 的情况相åŒï¼Œ ``1`` 用æ¥è¡¨ç¤º ``true``, ``0`` 表示 ``false``。 +- ``fixedx``: ``enc(X)`` 就是 ``enc(X * 10**N)``,其中 ``X * 10**N`` å¯ä»¥ç†è§£ä¸º ``int256``。 +- ``fixed``: 与 ``fixed128x18`` 的情况相åŒã€‚ +- ``ufixedx``: ``enc(X)`` 就是 ``enc(X * 10**N)`` ,其中 ``X * 10**N`` å¯ä»¥ç†è§£ä¸º ``uint256``。 +- ``ufixed``: 与 ``ufixed128x18`` 的情况相åŒã€‚ +- ``bytes``: ``enc(X)`` 就是 ``X`` 的字节åºåˆ—加上为使长度æˆä¸º 32 字节而添加的若干 0 值字节。 -Note that for any ``X``, ``len(enc(X))`` is a multiple of 32. +注æ„,对于任æ„çš„ ``X``, ``len(enc(X))`` 都是 32 çš„å€æ•°ã€‚ -Function Selector and Argument Encoding +函数选择器和å‚æ•°ç¼–ç  ======================================= -All in all, a call to the function ``f`` with parameters ``a_1, ..., a_n`` is encoded as +总而言之,对带有å‚æ•° ``a_1, ..., a_n`` 的函数 ``f`` 的调用被编ç ä¸ºï¼š ``function_selector(f) enc((a_1, ..., a_n))`` -and the return values ``v_1, ..., v_k`` of ``f`` are encoded as +``f`` 的返回值 ``v_1, ..., v_k`` 会被编ç ä¸ºï¼š ``enc((v_1, ..., v_k))`` -i.e. the values are combined into a tuple and encoded. +也就是说,返回值会被组åˆä¸ºä¸€ä¸ªå…ƒç»„(tuple)进行编ç ã€‚ -Examples +示例 ======== -Given the contract: +给定一个åˆçº¦ï¼š .. code-block:: solidity :force: @@ -252,88 +238,112 @@ Given the contract: } -Thus, for our ``Foo`` example if we wanted to call ``baz`` with the parameters ``69`` and -``true``, we would pass 68 bytes total, which can be broken down into: +<<<<<<< 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: -- ``0xcdcd77c0``: the Method ID. This is derived as the first 4 bytes of the Keccak hash of - the ASCII form of the signature ``baz(uint32,bool)``. -- ``0x0000000000000000000000000000000000000000000000000000000000000045``: the first parameter, - a uint32 value ``69`` padded to 32 bytes -- ``0x0000000000000000000000000000000000000000000000000000000000000001``: the second parameter - boolean - ``true``, padded to 32 bytes +- ``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``: 第一个å‚数, + 一个被用 0 值字节补充到 32 字节的 uint32 值 ``69``。 +- ``0x0000000000000000000000000000000000000000000000000000000000000001``: 第二个å‚数, + 一个被用 0 值字节补充到 32 字节的 boolean 值 ``true``。 + +åˆèµ·æ¥å°±æ˜¯: + .. code-block:: none 0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001 -It returns a single ``bool``. If, for example, it were to return ``false``, its output would be -the single byte array ``0x0000000000000000000000000000000000000000000000000000000000000000``, a single bool. +它返回一个 ``bool``。比如它返回 ``false``, +那么它的输出将是一个字节数组 ``0x0000000000000000000000000000000000000000000000000000000000000000``, +一个 ``bool`` 值。 -If we wanted to call ``bar`` with the argument ``["abc", "def"]``, we would pass 68 bytes total, broken down into: +<<<<<<< HEAD +如果我们想用 ``["abc", "def"]`` åšå‚数调用 ``bar``,我们总共需è¦ä¼ é€ 68 字节,å¯ä»¥åˆ†è§£ä¸ºï¼š -- ``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). +- ``0xfce353f6``: 方法ID。æºè‡ª ``bar(bytes3[2])`` çš„ç­¾å。 +- ``0x6162630000000000000000000000000000000000000000000000000000000000``: 第一个å‚数的第一部分, + 一个 ``bytes3`` 值 ``"abc"`` (左对é½ï¼‰ã€‚ +- ``0x6465660000000000000000000000000000000000000000000000000000000000``: 第一个å‚数的第二部分, + 一个 ``bytes3`` 值 ``"def"`` (左对é½ï¼‰ã€‚ -In total: +åˆèµ·æ¥å°±æ˜¯: .. code-block:: none 0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000 +如果我们想用 ``"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``: the Method ID. This is derived from the signature ``sam(bytes,bool,uint256[])``. Note that ``uint`` is replaced with its canonical representation ``uint256``. -- ``0x0000000000000000000000000000000000000000000000000000000000000060``: the location of the data part of the first parameter (dynamic type), measured in bytes from the start of the arguments block. In this case, ``0x60``. -- ``0x0000000000000000000000000000000000000000000000000000000000000001``: the second parameter: boolean true. -- ``0x00000000000000000000000000000000000000000000000000000000000000a0``: the location of the data part of the third parameter (dynamic type), measured in bytes. In this case, ``0xa0``. -- ``0x0000000000000000000000000000000000000000000000000000000000000004``: the data part of the first argument, it starts with the length of the byte array in elements, in this case, 4. -- ``0x6461766500000000000000000000000000000000000000000000000000000000``: the contents of the first argument: the UTF-8 (equal to ASCII in this case) encoding of ``"dave"``, padded on the right to 32 bytes. -- ``0x0000000000000000000000000000000000000000000000000000000000000003``: the data part of the third argument, it starts with the length of the array in elements, in this case, 3. -- ``0x0000000000000000000000000000000000000000000000000000000000000001``: the first entry of the third parameter. -- ``0x0000000000000000000000000000000000000000000000000000000000000002``: the second entry of the third parameter. -- ``0x0000000000000000000000000000000000000000000000000000000000000003``: the third entry of the third parameter. +- ``0xa5643bf2``: 方法ID。这是从签å ``sam(bytes,bool,uint256[])`` 中导出的。注æ„, ``uint`` 被替æ¢ä¸ºå…¶å…¸åž‹ä»£è¡¨ ``uint256``。 +- ``0x0000000000000000000000000000000000000000000000000000000000000060``: 第一个å‚数(动æ€ç±»åž‹ï¼‰çš„æ•°æ®éƒ¨åˆ†çš„ä½ç½®ï¼Œå³ä»Žå‚æ•°ç¼–ç å—开始ä½ç½®ç®—起的字节数。在这里,是 ``0x60`` 。 +- ``0x0000000000000000000000000000000000000000000000000000000000000001``: 第二个å‚数:boolean çš„ true。 +- ``0x00000000000000000000000000000000000000000000000000000000000000a0``: 第三个å‚数(动æ€ç±»åž‹ï¼‰çš„æ•°æ®éƒ¨åˆ†çš„ä½ç½®ï¼Œç”±å­—节数计é‡ã€‚在这里,是 ``0xa0``。 +- ``0x0000000000000000000000000000000000000000000000000000000000000004``: 第一个å‚æ•°çš„æ•°æ®éƒ¨åˆ†ï¼Œä»¥å­—节数组的元素个数作为开始,在这里,是 4。 +- ``0x6461766500000000000000000000000000000000000000000000000000000000``: 第一个å‚数的内容: ``"dave"`` çš„ UTF-8 ç¼–ç ï¼ˆåœ¨è¿™é‡Œç­‰åŒäºŽ ASCII ç¼–ç ï¼‰ï¼Œå¹¶åœ¨å³ä¾§ï¼ˆä½Žä½ï¼‰ç”¨ 0 值字节补充到 32 字节。 +- ``0x0000000000000000000000000000000000000000000000000000000000000003``: 第三个å‚æ•°çš„æ•°æ®éƒ¨åˆ†ï¼Œä»¥æ•°ç»„的元素个数作为开始,在这里,是 3。 +- ``0x0000000000000000000000000000000000000000000000000000000000000001``: 第三个å‚数的第一个数组元素。 +- ``0x0000000000000000000000000000000000000000000000000000000000000002``: 第三个å‚数的第二个数组元素。 +- ``0x0000000000000000000000000000000000000000000000000000000000000003``: 第三个å‚数的第三个数组元素。 -In total: +åˆèµ·æ¥å°±æ˜¯: .. code-block:: none 0xa5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003 -Use of Dynamic Types +动æ€ç±»åž‹çš„使用 ==================== -A call to a function with the signature ``f(uint256,uint32[],bytes10,bytes)`` with values -``(0x123, [0x456, 0x789], "1234567890", "Hello, world!")`` is encoded in the following way: +用值为 ``(0x123, [0x456, 0x789], "1234567890", "Hello, world!")`` çš„ç­¾åå‚数调用 +函数 ``f(uint256,uint32[],bytes10,bytes)``,其的编ç æ–¹å¼å¦‚下: -We take the first four bytes of ``keccak("f(uint256,uint32[],bytes10,bytes)")``, i.e. ``0x8be65246``. -Then we encode the head parts of all four arguments. For the static types ``uint256`` and ``bytes10``, -these are directly the values we want to pass, whereas for the dynamic types ``uint32[]`` and ``bytes``, -we use the offset in bytes to the start of their data area, measured from the start of the value -encoding (i.e. not counting the first four bytes containing the hash of the function signature). These are: +æˆ‘ä»¬å– ``keccak("f(uint256,uint32[],bytes10,bytes)")`` çš„å‰å››ä¸ªå­—èŠ‚ï¼Œå³ ``0x8be65246``。 +然åŽæˆ‘们对所有四个å‚数的头部部分进行编ç ã€‚对é™æ€ç±»åž‹ ``uint256`` å’Œ ``bytes10``, +这些是我们è¦ç›´æŽ¥ä¼ é€’的值,而对于动æ€ç±»åž‹ ``uint32[]`` å’Œ ``bytes``, +我们使用其数æ®åŒºå¼€å§‹çš„å移é‡ï¼Œä»Žéœ€ç¼–ç çš„值的开始ä½ç½®ç®—èµ· +(å³ä¸è®¡ç®—包å«å‡½æ•°ç­¾å哈希值的å‰å››ä¸ªå­—节)。也就是: -- ``0x0000000000000000000000000000000000000000000000000000000000000123`` (``0x123`` padded to 32 bytes) -- ``0x0000000000000000000000000000000000000000000000000000000000000080`` (offset to start of data part of second parameter, 4*32 bytes, exactly the size of the head part) -- ``0x3132333435363738393000000000000000000000000000000000000000000000`` (``"1234567890"`` padded to 32 bytes on the right) -- ``0x00000000000000000000000000000000000000000000000000000000000000e0`` (offset to start of data part of fourth parameter = offset to start of data part of first dynamic parameter + size of data part of first dynamic parameter = 4\*32 + 3\*32 (see below)) +- ``0x0000000000000000000000000000000000000000000000000000000000000123`` ( ``0x123`` 补充到 32 字节) +- ``0x0000000000000000000000000000000000000000000000000000000000000080`` (第二个å‚æ•°çš„æ•°æ®éƒ¨åˆ†èµ·å§‹ä½ç½®çš„å移é‡ï¼Œ4*32 字节,正好是头部的大å°ï¼‰ +- ``0x3132333435363738393000000000000000000000000000000000000000000000`` ( ``"1234567890"`` 从å³è¾¹è¡¥å……到 32 字节) +- ``0x00000000000000000000000000000000000000000000000000000000000000e0`` (第四个å‚æ•°çš„æ•°æ®éƒ¨åˆ†èµ·å§‹ä½ç½®çš„åç§»é‡ = 第一个动æ€å‚æ•°çš„æ•°æ®éƒ¨åˆ†èµ·å§‹ä½ç½®çš„åç§»é‡ + 第一个动æ€å‚æ•°çš„æ•°æ®éƒ¨åˆ†çš„长度 = 4\*32 + 3\*32,å‚考åŽæ–‡ï¼‰ -After this, the data part of the first dynamic argument, ``[0x456, 0x789]`` follows: +在此之åŽï¼Œè·Ÿç€ç¬¬ä¸€ä¸ªåŠ¨æ€å‚æ•°çš„æ•°æ®éƒ¨åˆ†ï¼Œ ``[0x456, 0x789]`` : -- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (number of elements of the array, 2) -- ``0x0000000000000000000000000000000000000000000000000000000000000456`` (first element) -- ``0x0000000000000000000000000000000000000000000000000000000000000789`` (second element) +- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (数组元素个数,2) +- ``0x0000000000000000000000000000000000000000000000000000000000000456`` (第一个数组元素) +- ``0x0000000000000000000000000000000000000000000000000000000000000789`` (第二个数组元素) -Finally, we encode the data part of the second dynamic argument, ``"Hello, world!"``: +最åŽï¼Œæˆ‘们将第二个动æ€å‚æ•°çš„æ•°æ®éƒ¨åˆ† ``"Hello, world!"`` 进行编ç ï¼š -- ``0x000000000000000000000000000000000000000000000000000000000000000d`` (number of elements (bytes in this case): 13) -- ``0x48656c6c6f2c20776f726c642100000000000000000000000000000000000000`` (``"Hello, world!"`` padded to 32 bytes on the right) +- ``0x000000000000000000000000000000000000000000000000000000000000000d`` (元素个数,在这里是字节数:13) +- ``0x48656c6c6f2c20776f726c642100000000000000000000000000000000000000`` ( ``"Hello, world!"`` 从å³è¾¹è¡¥å……到 32 字节) -All together, the encoding is (newline after function selector and each 32-bytes for clarity): +最åŽï¼Œåˆå¹¶åˆ°ä¸€èµ·çš„ç¼–ç å°±æ˜¯ï¼ˆä¸ºäº†æ¸…æ™°ï¼Œåœ¨å‡½æ•°é€‰æ‹©å™¨å’Œæ¯ 32 字节之åŽåŠ äº†æ¢è¡Œï¼‰ï¼š .. code-block:: none @@ -348,173 +358,163 @@ All together, the encoding is (newline after function selector and each 32-bytes 000000000000000000000000000000000000000000000000000000000000000d 48656c6c6f2c20776f726c642100000000000000000000000000000000000000 -Let us apply the same principle to encode the data for a function with a signature ``g(uint256[][],string[])`` -with values ``([[1, 2], [3]], ["one", "two", "three"])`` but start from the most atomic parts of the encoding: +让我们使用相åŒçš„原ç†æ¥å¯¹ä¸€ä¸ªç­¾å为 ``g(uint256[][],string[])`` ,å‚数值为 +``([[1, 2], [3]], ["one", "two", "three"])`` 的函数æ¥è¿›è¡Œç¼–ç ï¼›ä½†ä»Žæœ€åŽŸå­çš„部分开始: -First we encode the length and data of the first embedded dynamic array ``[1, 2]`` of the first root array ``[[1, 2], [3]]``: +首先我们将第一个根数组 ``[[1, 2], [3]]`` 的第一个嵌入的动æ€æ•°ç»„ ``[1, 2]`` 的长度和数æ®è¿›è¡Œç¼–ç ï¼š -- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (number of elements in the first array, 2; the elements themselves are ``1`` and ``2``) -- ``0x0000000000000000000000000000000000000000000000000000000000000001`` (first element) -- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (second element) +- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (ç¬¬ä¸€ä¸ªæ•°ç»„ä¸­çš„å…ƒç´ æ•°é‡ 2;元素本身是 ``1`` å’Œ ``2``) +- ``0x0000000000000000000000000000000000000000000000000000000000000001`` (第一个元素) +- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (第二个元素) -Then we encode the length and data of the second embedded dynamic array ``[3]`` of the first root array ``[[1, 2], [3]]``: +然åŽæˆ‘们对第一个根数组 ``[[1, 2], [3]]`` 的第二个嵌入å¼åŠ¨æ€æ•°ç»„ ``[3]`` 的长度和数æ®è¿›è¡Œç¼–ç ï¼š -- ``0x0000000000000000000000000000000000000000000000000000000000000001`` (number of elements in the second array, 1; the element is ``3``) -- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (first element) +- ``0x0000000000000000000000000000000000000000000000000000000000000001`` (ç¬¬äºŒä¸ªæ•°ç»„ä¸­çš„å…ƒç´ æ•°é‡ 1;元素数æ®æ˜¯ ``3``) +- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (第一个元素) -Then we need to find the offsets ``a`` and ``b`` for their respective dynamic arrays ``[1, 2]`` and ``[3]``. -To calculate the offsets we can take a look at the encoded data of the first root array ``[[1, 2], [3]]`` -enumerating each line in the encoding: +然åŽæˆ‘们需è¦ä¸ºå„自的动æ€æ•°ç»„ ``[1, 2]`` å’Œ ``[3]`` 找到åç§»é‡ ``a`` å’Œ ``b``。 +为了计算å移é‡ï¼Œæˆ‘们å¯ä»¥çœ‹ä¸€ä¸‹ç¬¬ä¸€ä¸ªæ ¹æ•°ç»„çš„ç¼–ç æ•°æ® ``[[1, 2], [3]]`` 在编ç ä¸­æžšä¸¾æ¯ä¸€è¡Œã€‚ .. code-block:: none - 0 - a - offset of [1, 2] - 1 - b - offset of [3] - 2 - 0000000000000000000000000000000000000000000000000000000000000002 - count for [1, 2] - 3 - 0000000000000000000000000000000000000000000000000000000000000001 - encoding of 1 - 4 - 0000000000000000000000000000000000000000000000000000000000000002 - encoding of 2 - 5 - 0000000000000000000000000000000000000000000000000000000000000001 - count for [3] - 6 - 0000000000000000000000000000000000000000000000000000000000000003 - encoding of 3 + 0 - a - [1, 2] çš„åç§»é‡ + 1 - b - [3] çš„åç§»é‡ + 2 - 0000000000000000000000000000000000000000000000000000000000000002 - [1, 2] 数组的计数 + 3 - 0000000000000000000000000000000000000000000000000000000000000001 - 1 çš„ç¼–ç  + 4 - 0000000000000000000000000000000000000000000000000000000000000002 - 2 çš„ç¼–ç  + 5 - 0000000000000000000000000000000000000000000000000000000000000001 - [3] 数组的计数 + 6 - 0000000000000000000000000000000000000000000000000000000000000003 - 3 çš„ç¼–ç  + +åç§»é‡ ``a`` 指å‘数组 ``[1, 2]`` 内容的开始ä½ç½®ï¼Œå³ç¬¬ 2 行的开始(64 字节); +所以 ``a = 0x0000000000000000000000000000000000000000000000000000000000000040``。 -Offset ``a`` points to the start of the content of the array ``[1, 2]`` which is line -2 (64 bytes); thus ``a = 0x0000000000000000000000000000000000000000000000000000000000000040``. +åç§»é‡ ``b`` 指å‘数组 ``[3]`` 内容的开始ä½ç½®ï¼Œå³ç¬¬ 5 行的开始(160 字节); +所以 ``b = 0x00000000000000000000000000000000000000000000000000000000000000a0``。 -Offset ``b`` points to the start of the content of the array ``[3]`` which is line 5 (160 bytes); -thus ``b = 0x00000000000000000000000000000000000000000000000000000000000000a0``. +然åŽæˆ‘们对第二个根数组的嵌入字符串进行编ç ï¼š -Then we encode the embedded strings of the second root array: +- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (å•è¯ ``"one"`` 中的字符个数) +- ``0x6f6e650000000000000000000000000000000000000000000000000000000000`` (å•è¯ ``"one"`` çš„ utf8 ç¼–ç ) +- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (å•è¯ ``"two"`` 中的字符个数) +- ``0x74776f0000000000000000000000000000000000000000000000000000000000`` (å•è¯ ``"two"`` çš„ utf8 ç¼–ç ) +- ``0x0000000000000000000000000000000000000000000000000000000000000005`` (å•è¯ ``"three"`` 中的字符个数) +- ``0x7468726565000000000000000000000000000000000000000000000000000000`` (å•è¯ ``"three"`` çš„ utf8 ç¼–ç ) -- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of characters in word ``"one"``) -- ``0x6f6e650000000000000000000000000000000000000000000000000000000000`` (utf8 representation of word ``"one"``) -- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of characters in word ``"two"``) -- ``0x74776f0000000000000000000000000000000000000000000000000000000000`` (utf8 representation of word ``"two"``) -- ``0x0000000000000000000000000000000000000000000000000000000000000005`` (number of characters in word ``"three"``) -- ``0x7468726565000000000000000000000000000000000000000000000000000000`` (utf8 representation of word ``"three"``) +作为与第一个根数组的并列,因为字符串也属于动æ€å…ƒç´ ï¼Œæˆ‘们也需è¦æ‰¾åˆ°å®ƒä»¬çš„åç§»é‡ ``c``, ``d`` å’Œ ``e``: -In parallel to the first root array, since strings are dynamic elements we need to find their offsets ``c``, ``d`` and ``e``: .. code-block:: none - 0 - c - offset for "one" - 1 - d - offset for "two" - 2 - e - offset for "three" - 3 - 0000000000000000000000000000000000000000000000000000000000000003 - count for "one" - 4 - 6f6e650000000000000000000000000000000000000000000000000000000000 - encoding of "one" - 5 - 0000000000000000000000000000000000000000000000000000000000000003 - count for "two" - 6 - 74776f0000000000000000000000000000000000000000000000000000000000 - encoding of "two" - 7 - 0000000000000000000000000000000000000000000000000000000000000005 - count for "three" - 8 - 7468726565000000000000000000000000000000000000000000000000000000 - encoding of "three" + 0 - c - "one" çš„åç§»é‡ + 1 - d - "two" çš„åç§»é‡ + 2 - e - "three" çš„åç§»é‡ + 3 - 0000000000000000000000000000000000000000000000000000000000000003 - "one" 的字符计数 + 4 - 6f6e650000000000000000000000000000000000000000000000000000000000 - "one" çš„ç¼–ç  + 5 - 0000000000000000000000000000000000000000000000000000000000000003 - "two" 的字符计数 + 6 - 74776f0000000000000000000000000000000000000000000000000000000000 - "two" çš„ç¼–ç  + 7 - 0000000000000000000000000000000000000000000000000000000000000005 - "three" 的字符计数 + 8 - 7468726565000000000000000000000000000000000000000000000000000000 - "three" çš„ç¼–ç  -Offset ``c`` points to the start of the content of the string ``"one"`` which is line 3 (96 bytes); -thus ``c = 0x0000000000000000000000000000000000000000000000000000000000000060``. +åç§»é‡ ``c`` 指å‘字符串 ``"one"`` 内容的开始ä½ç½®ï¼Œå³ç¬¬ 3 行的开始(96 字节); +所以 ``c = 0x0000000000000000000000000000000000000000000000000000000000000060``。 -Offset ``d`` points to the start of the content of the string ``"two"`` which is line 5 (160 bytes); -thus ``d = 0x00000000000000000000000000000000000000000000000000000000000000a0``. +åç§»é‡ ``d`` 指å‘字符串 ``"two"`` 内容的开始ä½ç½®ï¼Œå³ç¬¬ 5 行的开始(160 字节); +所以 ``d = 0x00000000000000000000000000000000000000000000000000000000000000a0``。 -Offset ``e`` points to the start of the content of the string ``"three"`` which is line 7 (224 bytes); -thus ``e = 0x00000000000000000000000000000000000000000000000000000000000000e0``. +åç§»é‡ ``e`` 指å‘字符串 ``"three"`` 内容的开始ä½ç½®ï¼Œå³ç¬¬ 7 行的开始(224 字节); +所以 ``e = 0x00000000000000000000000000000000000000000000000000000000000000e0``。 -Note that the encodings of the embedded elements of the root arrays are not dependent on each other -and have the same encodings for a function with a signature ``g(string[],uint256[][])``. +注æ„,根数组的嵌入元素的编ç å¹¶ä¸äº’相ä¾èµ–,且具有对于函数签å ``g(string[],uint256[][])`` 所相åŒçš„ç¼–ç ã€‚ -Then we encode the length of the first root array: +然åŽæˆ‘们对第一个根数组的长度进行编ç ï¼š -- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (number of elements in the first root array, 2; the elements themselves are ``[1, 2]`` and ``[3]``) +- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (ç¬¬ä¸€ä¸ªæ ¹æ•°ç»„çš„å…ƒç´ æ•°é‡ 2;这些元素本身是 ``[1, 2]`` å’Œ ``[3]``) -Then we encode the length of the second root array: +而åŽæˆ‘们对第二个根数组的长度进行编ç ï¼š -- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of strings in the second root array, 3; the strings themselves are ``"one"``, ``"two"`` and ``"three"``) +- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (ç¬¬äºŒä¸ªæ ¹æ•°ç»„çš„å…ƒç´ æ•°é‡ 3;这些字符串本身是 ``"one"``, ``"two"`` å’Œ ``"three"``) -Finally we find the offsets ``f`` and ``g`` for their respective root dynamic arrays ``[[1, 2], [3]]`` and -``["one", "two", "three"]``, and assemble parts in the correct order: +最åŽï¼Œæˆ‘们找到根动æ€æ•°ç»„元素 ``[[1, 2], [3]]`` å’Œ ``["one", "two", "three"]`` çš„åç§»é‡ ``f`` å’Œ ``g``。 +汇编数æ®çš„正确顺åºå¦‚下: .. code-block:: none - 0x2289b18c - function signature - 0 - f - offset of [[1, 2], [3]] - 1 - g - offset of ["one", "two", "three"] - 2 - 0000000000000000000000000000000000000000000000000000000000000002 - count for [[1, 2], [3]] - 3 - 0000000000000000000000000000000000000000000000000000000000000040 - offset of [1, 2] - 4 - 00000000000000000000000000000000000000000000000000000000000000a0 - offset of [3] - 5 - 0000000000000000000000000000000000000000000000000000000000000002 - count for [1, 2] - 6 - 0000000000000000000000000000000000000000000000000000000000000001 - encoding of 1 - 7 - 0000000000000000000000000000000000000000000000000000000000000002 - encoding of 2 - 8 - 0000000000000000000000000000000000000000000000000000000000000001 - count for [3] - 9 - 0000000000000000000000000000000000000000000000000000000000000003 - encoding of 3 - 10 - 0000000000000000000000000000000000000000000000000000000000000003 - count for ["one", "two", "three"] - 11 - 0000000000000000000000000000000000000000000000000000000000000060 - offset for "one" - 12 - 00000000000000000000000000000000000000000000000000000000000000a0 - offset for "two" - 13 - 00000000000000000000000000000000000000000000000000000000000000e0 - offset for "three" - 14 - 0000000000000000000000000000000000000000000000000000000000000003 - count for "one" - 15 - 6f6e650000000000000000000000000000000000000000000000000000000000 - encoding of "one" - 16 - 0000000000000000000000000000000000000000000000000000000000000003 - count for "two" - 17 - 74776f0000000000000000000000000000000000000000000000000000000000 - encoding of "two" - 18 - 0000000000000000000000000000000000000000000000000000000000000005 - count for "three" - 19 - 7468726565000000000000000000000000000000000000000000000000000000 - encoding of "three" - -Offset ``f`` points to the start of the content of the array ``[[1, 2], [3]]`` which is line 2 (64 bytes); -thus ``f = 0x0000000000000000000000000000000000000000000000000000000000000040``. - -Offset ``g`` points to the start of the content of the array ``["one", "two", "three"]`` which is line 10 (320 bytes); -thus ``g = 0x0000000000000000000000000000000000000000000000000000000000000140``. + 0x2289b18c - 函数签å + 0 - f - [[1, 2], [3]] çš„åç§»é‡ + 1 - g - ["one", "two", "three"] çš„åç§»é‡ + 2 - 0000000000000000000000000000000000000000000000000000000000000002 - [[1, 2], [3]] 的元素计数 + 3 - 0000000000000000000000000000000000000000000000000000000000000040 - [1, 2] çš„åç§»é‡ + 4 - 00000000000000000000000000000000000000000000000000000000000000a0 - [3] çš„åç§»é‡ + 5 - 0000000000000000000000000000000000000000000000000000000000000002 - [1, 2] 的元素计数 + 6 - 0000000000000000000000000000000000000000000000000000000000000001 - 1 çš„ç¼–ç  + 7 - 0000000000000000000000000000000000000000000000000000000000000002 - 2 çš„ç¼–ç  + 8 - 0000000000000000000000000000000000000000000000000000000000000001 - [3] 的元素计数 + 9 - 0000000000000000000000000000000000000000000000000000000000000003 - 3 çš„ç¼–ç  + 10 - 0000000000000000000000000000000000000000000000000000000000000003 - ["one", "two", "three"] 的元素计数 + 11 - 0000000000000000000000000000000000000000000000000000000000000060 - çš„å移é‡"one" + 12 - 00000000000000000000000000000000000000000000000000000000000000a0 - çš„å移é‡"two" + 13 - 00000000000000000000000000000000000000000000000000000000000000e0 - çš„å移é‡"three" + 14 - 0000000000000000000000000000000000000000000000000000000000000003 - "one" 的字符计数 + 15 - 6f6e650000000000000000000000000000000000000000000000000000000000 - "one" çš„ç¼–ç  + 16 - 0000000000000000000000000000000000000000000000000000000000000003 - "two" 的字符计数 + 17 - 74776f0000000000000000000000000000000000000000000000000000000000 - "two" çš„ç¼–ç  + 18 - 0000000000000000000000000000000000000000000000000000000000000005 - "three" 的字符计数 + 19 - 7468726565000000000000000000000000000000000000000000000000000000 - "three" çš„ç¼–ç  + +åç§»é‡ ``f`` 指å‘数组 ``[[1, 2], [3]]`` 内容的开始ä½ç½®ï¼Œå³ç¬¬ 2 行的开始(64 字节); +所以 ``f = 0x0000000000000000000000000000000000000000000000000000000000000040``。 + +åç§»é‡ ``g`` 指å‘数组 ``["one", "two", "three"]`` 内容的开始ä½ç½®ï¼Œå³ç¬¬ 10 行的开始(320 字节); +所以 ``g = 0x0000000000000000000000000000000000000000000000000000000000000140``。 .. _abi_events: -Events +事件 ====== -Events are an abstraction of the Ethereum logging/event-watching protocol. Log entries provide the contract's -address, a series of up to four topics and some arbitrary length binary data. Events leverage the existing function -ABI in order to interpret this (together with an interface spec) as a properly typed structure. - -Given an event name and series of event parameters, we split them into two sub-series: those which are indexed and -those which are not. -Those which are indexed, which may number up to 3 (for non-anonymous events) or 4 (for anonymous ones), are used -alongside the Keccak hash of the event signature to form the topics of the log entry. -Those which are not indexed form the byte array of the event. - -In effect, a log entry using this ABI is described as: - -- ``address``: the address of the contract (intrinsically provided by Ethereum); -- ``topics[0]``: ``keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")")`` (``canonical_type_of`` - is a function that simply returns the canonical type of a given argument, e.g. for ``uint indexed foo``, it would - return ``uint256``). This value is only present in ``topics[0]`` if the event is not declared as ``anonymous``; -- ``topics[n]``: ``abi_encode(EVENT_INDEXED_ARGS[n - 1])`` if the event is not declared as ``anonymous`` - or ``abi_encode(EVENT_INDEXED_ARGS[n])`` if it is (``EVENT_INDEXED_ARGS`` is the series of ``EVENT_ARGS`` that - are indexed); -- ``data``: ABI encoding of ``EVENT_NON_INDEXED_ARGS`` (``EVENT_NON_INDEXED_ARGS`` is the series of ``EVENT_ARGS`` - that are not indexed, ``abi_encode`` is the ABI encoding function used for returning a series of typed values - from a function, as described above). - -For all types of length at most 32 bytes, the ``EVENT_INDEXED_ARGS`` array contains -the value directly, padded or sign-extended (for signed integers) to 32 bytes, just as for regular ABI encoding. -However, for all "complex" types or types of dynamic length, including all arrays, ``string``, ``bytes`` and structs, -``EVENT_INDEXED_ARGS`` will contain the *Keccak hash* of a special in-place encoded value -(see :ref:`indexed_event_encoding`), rather than the encoded value directly. -This allows applications to efficiently query for values of dynamic-length types -(by setting the hash of the encoded value as the topic), but leaves applications unable -to decode indexed values they have not queried for. For dynamic-length types, -application developers face a trade-off between fast search for predetermined values -(if the argument is indexed) and legibility of arbitrary values (which requires that -the arguments not be indexed). Developers may overcome this tradeoff and achieve both -efficient search and arbitrary legibility by defining events with two arguments — one -indexed, one not — intended to hold the same value. +事件是Ethereum日志/事件观察å议的一个抽象。日志æ¡ç›®æ供了åˆçº¦çš„地å€ï¼Œ +一系列最多四个主题和一些任æ„长度的二进制数æ®ã€‚ +事件利用现有的函数ABI,以便将其(连åŒæŽ¥å£è§„范)解释为一个正确的类型化结构。 + +给定一个事件å称和一系列的事件å‚数,我们把它们分æˆä¸¤ä¸ªå­ç³»åˆ—:那些有索引的和那些没有索引的。 +那些被索引的å‚数,å¯èƒ½å¤šè¾¾3个(对于éžåŒ¿å事件)或4个(对于匿å事件), +与事件签åçš„Keccak散列一起使用,形æˆæ—¥å¿—æ¡ç›®çš„主题。 +那些没有索引的则构æˆäº‹ä»¶çš„字节数组。 + +实际上,使用该ABI的日志æ¡ç›®è¢«æ述为: + +- ``address``: åˆçº¦çš„地å€ï¼ˆç”±ä»¥å¤ªåŠçœŸæ­£æ供); +- ``topics[0]``: ``keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")")`` + ``canonical_type_of`` 是一个å¯ä»¥è¿”回给定å‚æ•°çš„æƒå¨ç±»åž‹çš„函数,例如,对 ``uint indexed foo`` 它会返回 ``uint256``)。 + 如果事件被声明为 ``anonymous``,那么 ``topics[0]`` ä¸ä¼šè¢«ç”Ÿæˆï¼› +- ``topics[n]``: 如果事件没有被声明为 ``anonymous``, 则为 ``abi_encode(EVENT_INDEXED_ARGS[n - 1])`` + 或者如果它被声明为该类型,则为 ``abi_encode(EVENT_INDEXED_ARGS[n])`` + ( ``EVENT_INDEXED_ARGS`` 是被索引的 ``EVENT_ARGS`` 的系列); +- ``data``: ``EVENT_NON_INDEXED_ARGS`` çš„ABIç¼–ç  + ( ``EVENT_NON_INDEXED_ARGS`` 是一系列没有索引的 ``EVENT_ARGS``, ``abi_encode`` 是ABIç¼–ç å‡½æ•°ï¼Œ + 用于从一个函数返回一系列类型的值,如上所述)。 + +对于所有长度ä¸è¶…过32字节的类型, ``EVENT_INDEXED_ARGS`` 数组直接包å«æ•°å€¼ï¼Œå¡«å……或符å·æ‰©å±•ï¼ˆå¯¹äºŽæœ‰ç¬¦å·æ•´æ•°ï¼‰åˆ°32字节, +å°±åƒå¸¸è§„ABIç¼–ç ä¸€æ ·ã€‚然而,对于所有 “å¤æ‚†类型或动æ€é•¿åº¦çš„类型,包括所有数组, ``string``, ``bytes`` 和结构, +``EVENT_INDEXED_ARGS`` å°†åŒ…å« *Keccak散列* 的特殊就地编ç å€¼ï¼ˆè§ :ref:`indexed_event_encoding`), +而ä¸æ˜¯ç›´æŽ¥ç¼–ç çš„值。这å…许应用程åºæœ‰æ•ˆåœ°æŸ¥è¯¢åŠ¨æ€é•¿åº¦ç±»åž‹çš„值(通过设置编ç å€¼çš„哈希值作为主题), +但使应用程åºæ— æ³•è§£ç ä»–们没有查询到的索引值。对于动æ€é•¿åº¦ç±»åž‹ï¼Œ +应用程åºå¼€å‘人员é¢ä¸´ç€å¯¹é¢„定值的快速æœç´¢ï¼ˆå¦‚æžœå‚数有索引)和任æ„值的å¯è¯»æ€§ä¹‹é—´çš„æƒè¡¡ï¼ˆè¿™è¦æ±‚å‚æ•°ä¸è¢«ç´¢å¼•ï¼‰ã€‚ +å¼€å‘者å¯ä»¥é€šè¿‡å®šä¹‰å…·æœ‰ä¸¤ä¸ªå‚数的事件 -- 一个是索引的,一个是ä¸ç´¢å¼•çš„ -- æ¥å…‹æœè¿™ç§æƒè¡¡ï¼Œå®žçŽ°é«˜æ•ˆæœç´¢å’Œä»»æ„å¯è¯»æ€§ã€‚ .. _abi_errors: .. index:: error, selector; of an error -Errors +错误 ====== -In case of a failure inside a contract, the contract can use a special opcode to abort execution and revert -all state changes. In addition to these effects, descriptive data can be returned to the caller. -This descriptive data is the encoding of an error and its arguments in the same way as data for a function -call. +在åˆçº¦å†…部å‘生故障的情况下,åˆçº¦å¯ä»¥ä½¿ç”¨ä¸€ä¸ªç‰¹æ®Šçš„æ“作ç æ¥ä¸­æ­¢æ‰§è¡Œï¼Œå¹¶æ¢å¤æ‰€æœ‰çš„状æ€å˜åŒ–。 +除了这些效果之外,æ述性数æ®å¯ä»¥è¿”回给调用者。 +è¿™ç§æ述性数æ®æ˜¯å¯¹ä¸€ä¸ªé”™è¯¯åŠå…¶å‚æ•°çš„ç¼–ç ï¼Œå…¶æ–¹å¼ä¸Žå‡½æ•°è°ƒç”¨çš„æ•°æ®ç›¸åŒã€‚ -As an example, let us consider the following contract whose ``transfer`` function always -reverts with a custom error of "insufficient balance": +作为一个例å­ï¼Œè®©æˆ‘们考虑以下åˆçº¦ï¼Œå®ƒçš„ ``transfer`` 函数总是以 "ä½™é¢ä¸è¶³" 的自定义错误返回。 .. code-block:: solidity @@ -528,82 +528,82 @@ reverts with a custom error of "insufficient balance": } } -The return data would be encoded in the same way as the function call -``InsufficientBalance(0, amount)`` to the function ``InsufficientBalance(uint256,uint256)``, -i.e. ``0xcf479181``, ``uint256(0)``, ``uint256(amount)``. +返回数æ®çš„ç¼–ç æ–¹å¼ä¸Žå‡½æ•° ``InsufficientBalance(0, amount)`` +对函数 ``InsufficientBalance(uint256,uint256)`` 的调用方å¼ç›¸åŒã€‚ +å³ ``0xcf479181``, ``uint256(0)``, ``uint256(amount)``。 -The error selectors ``0x00000000`` and ``0xffffffff`` are reserved for future use. +错误选择器 ``0x00000000`` å’Œ ``0xffffffff`` 是ä¿ç•™ç»™å°†æ¥ä½¿ç”¨çš„。 .. warning:: - Never trust error data. - The error data by default bubbles up through the chain of external calls, which - means that a contract may receive an error not defined in any of the contracts - it calls directly. - Furthermore, any contract can fake any error by returning data that matches - an error signature, even if the error is not defined anywhere. + 永远ä¸è¦ç›¸ä¿¡é”™è¯¯æ•°æ®ã€‚ + 默认情况下,错误数æ®é€šè¿‡å¤–部调用在链å‘上冒泡产生, + è¿™æ„味ç€ä¸€ä¸ªåˆçº¦å¯èƒ½ä¼šæ”¶åˆ°ä¸€ä¸ªå®ƒç›´æŽ¥è°ƒç”¨çš„任何åˆçº¦ä¸­æ²¡æœ‰å®šä¹‰çš„错误。 + 此外,任何åˆçº¦éƒ½å¯ä»¥é€šè¿‡è¿”回与错误签å相匹é…çš„æ•°æ®æ¥ä¼ªé€ ä»»ä½•é”™è¯¯ï¼Œå³ä½¿è¯¥é”™è¯¯æ²¡æœ‰åœ¨ä»»ä½•åœ°æ–¹å®šä¹‰ã€‚ .. _abi_json: JSON ==== -The JSON format for a contract's interface is given by an array of function, event and error descriptions. -A function description is a JSON object with the fields: +åˆçº¦æŽ¥å£çš„JSONæ ¼å¼æ˜¯ç”±ä¸€ä¸ªå‡½æ•°ï¼Œäº‹ä»¶å’Œé”™è¯¯æ述的数组给出的。 +一个函数æ述是一个带有字段的JSON对象: -- ``type``: ``"function"``, ``"constructor"``, ``"receive"`` (the :ref:`"receive Ether" function `) or ``"fallback"`` (the :ref:`"default" function `); -- ``name``: the name of the function; -- ``inputs``: an array of objects, each of which contains: +- ``type``: ``"function"``, ``"constructor"``, ``"receive"`` ( :ref:`"接收以太å¸" 函数 ` ) 或者 ``"fallback"`` ( :ref:`"默认" 函数 `); +- ``name``: 函数å称; +- ``inputs``: 数组对象,æ¯ä¸ªæ•°ç»„对象会包å«ï¼š - * ``name``: the name of the parameter. - * ``type``: the canonical type of the parameter (more below). - * ``components``: used for tuple types (more below). + * ``name``: å‚æ•°å称; + * ``type``: å‚æ•°çš„æƒå¨ç±»åž‹ï¼ˆè¯¦è§ä¸‹æ–‡ï¼‰ + * ``components``: 供元组(tuple) 类型使用(详è§ä¸‹æ–‡ï¼‰ -- ``outputs``: an array of objects similar to ``inputs``. -- ``stateMutability``: a string with one of the following values: ``pure`` (:ref:`specified to not read - blockchain state `), ``view`` (:ref:`specified to not modify the blockchain - state `), ``nonpayable`` (function does not accept Ether - the default) and ``payable`` (function accepts Ether). +- ``outputs``: 一个类似于 ``inputs`` 的数组对象。 +- ``stateMutability``: 为下列值之一: ``pure`` (:ref:`指定为ä¸è¯»å–区å—é“¾çŠ¶æ€ `), + ``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:: - Sending non-zero Ether to non-payable function will revert the transaction. + å‘ä¸æŽ¥æ”¶ä»¥å¤ªå¸å‡½æ•°å‘é€éžé›¶çš„以太å¸å°†ä½¿äº¤æ˜“回滚。 .. note:: - The state mutability ``nonpayable`` is reflected in Solidity by not specifying - a state mutability modifier at all. + 在Solidity中,状æ€å¯å˜æ€§ ``ä¸å¯æ”¯ä»˜`` 是完全ä¸æŒ‡å®šçŠ¶æ€å¯å˜æ€§æ—¶çš„修饰语。 -An event description is a JSON object with fairly similar fields: +一个事件æ述是一个有æžå…¶ç›¸ä¼¼å­—段的 JSON 对象: -- ``type``: always ``"event"`` -- ``name``: the name of the event. -- ``inputs``: an array of objects, each of which contains: +- ``type``: 总是 ``"event"`` +- ``name``: 事件å称; +- ``inputs``: 对象数组,æ¯ä¸ªæ•°ç»„对象会包å«ï¼š - * ``name``: the name of the parameter. - * ``type``: the canonical type of the parameter (more below). - * ``components``: used for tuple types (more below). - * ``indexed``: ``true`` if the field is part of the log's topics, ``false`` if it is one of the log's data segments. + * ``name``: å‚æ•°å称。 + * ``type``: å‚数的规范类型(详è§ä¸‹æ–‡ï¼‰ã€‚ + * ``components``: 供元组(tuple) 类型使用(详è§ä¸‹æ–‡ï¼‰ + * ``indexed``: 如果该字段是日志主题的一部分,则为 ``true``,如果它是日志数æ®æ®µä¹‹ä¸€ï¼Œåˆ™ä¸º ``false``。 -- ``anonymous``: ``true`` if the event was declared as ``anonymous``. +- ``anonymous``: 如果事件被声明为 ``anonymous``,则为 ``true``。 -Errors look as follows: +错误消æ¯å¦‚下: -- ``type``: always ``"error"`` -- ``name``: the name of the error. -- ``inputs``: an array of objects, each of which contains: +- ``type``: 总是 ``"error"`` +- ``name``: 错误å称; +- ``inputs``: 对象数组,æ¯ä¸ªæ•°ç»„对象会包å«ï¼š - * ``name``: the name of the parameter. - * ``type``: the canonical type of the parameter (more below). - * ``components``: used for tuple types (more below). + * ``name``: å‚æ•°å称。 + * ``type``: å‚æ•°çš„æƒå¨ç±»åž‹ï¼ˆç›¸è§ä¸‹æ–‡ï¼‰ã€‚ + * ``components``: 供元组(tuple) 类型使用(详è§ä¸‹æ–‡ï¼‰ã€‚ .. note:: - There can be multiple errors with the same name and even with identical signature - in the JSON array; for example, if the errors originate from different - files in the smart contract or are referenced from another smart contract. - For the ABI, only the name of the error itself is relevant and not where it is - defined. + 在 JSON 数组中å¯èƒ½æœ‰å¤šä¸ªå…·æœ‰ç›¸åŒå称的错误,甚至具有相åŒçš„ç­¾åï¼› + 例如,如果错误æºè‡ªåˆçº¦ä¸­çš„ä¸åŒæ–‡ä»¶æˆ–从å¦ä¸€ä¸ªåˆçº¦å¼•ç”¨ã€‚ + 对于ABIæ¥è¯´ï¼Œåªæœ‰é”™è¯¯æœ¬èº«çš„å称是相关的,而ä¸æ˜¯å®ƒçš„定义ä½ç½®ã€‚ -For example, +例如, .. code-block:: solidity @@ -620,7 +620,7 @@ For example, bytes32 b; } -would result in the JSON: +å¯ç”±å¦‚下 JSON æ¥è¡¨ç¤ºï¼š .. code-block:: json @@ -643,21 +643,19 @@ would result in the JSON: "outputs": [] }] -Handling tuple types +处ç†å…ƒç»„类型 -------------------- -Despite the fact that names are intentionally not part of the ABI encoding, they do make a lot of sense to be included -in the JSON to enable displaying it to the end user. The structure is nested in the following way: +尽管å称被有æ„地ä¸ä½œä¸º ABI ç¼–ç çš„一部分,但将它们包å«è¿› JSON æ¥æ˜¾ç¤ºç»™æœ€ç»ˆç”¨æˆ·æ˜¯éžå¸¸åˆç†çš„。 +其结构会按下列方å¼è¿›è¡ŒåµŒå¥—: -An object with members ``name``, ``type`` and potentially ``components`` describes a typed variable. -The canonical type is determined until a tuple type is reached and the string description up -to that point is stored in ``type`` prefix with the word ``tuple``, i.e. it will be ``tuple`` followed by -a sequence of ``[]`` and ``[k]`` with -integers ``k``. The components of the tuple are then stored in the member ``components``, -which is of an array type and has the same structure as the top-level object except that -``indexed`` is not allowed there. +一个拥有 ``name``, ``type`` 和潜在的 ``components`` æˆå‘˜çš„对象æ述了æŸç§ç±»åž‹çš„å˜é‡ã€‚ +直至到达一个元组(tuple) 类型且到那点的存储在 ``type`` 属性中的字符串以 ``tuple`` 为å‰ç¼€ï¼Œ +也就是说,在 ``tuple`` 之åŽç´§è·Ÿä¸€ä¸ª ``[]`` 或有整数 ``k`` çš„ ``[k]``ï¼Œæ‰ +能确定一个元组。 元组的组件元素会被存储在æˆå‘˜ ``components`` 中, +它是一个数组类型,且与顶级对象具有åŒæ ·çš„结构,åªæ˜¯åœ¨è¿™é‡Œä¸å…许 ``已索引的(indexed)`` 数组元素。 -As an example, the code +示例代ç ï¼š .. code-block:: solidity @@ -672,7 +670,7 @@ As an example, the code function g() public pure returns (S memory, T memory, uint) {} } -would result in the JSON: +å¯ç”±å¦‚下 JSON æ¥è¡¨ç¤ºï¼š .. code-block:: json @@ -734,29 +732,29 @@ would result in the JSON: .. _abi_packed_mode: -Strict Encoding Mode +严格的编ç æ¨¡å¼ ==================== -Strict encoding mode is the mode that leads to exactly the same encoding as defined in the formal specification above. -This means that offsets have to be as small as possible while still not creating overlaps in the data areas, and thus no gaps are -allowed. +严格的编ç æ¨¡å¼æ˜¯æŒ‡å¯¼è‡´ä¸Žä¸Šè¿°æ­£å¼è§„范中定义的编ç å®Œå…¨ç›¸åŒçš„模å¼ã€‚ +è¿™æ„味ç€å移é‡å¿…须尽å¯èƒ½å°ï¼ŒåŒæ—¶è¿˜ä¸èƒ½åœ¨æ•°æ®åŒºåŸŸäº§ç”Ÿé‡å ï¼Œ +å› æ­¤ä¸å…许有间隙。 -Usually, ABI decoders are written in a straightforward way by just following offset pointers, but some decoders -might enforce strict mode. The Solidity ABI decoder currently does not enforce strict mode, but the encoder -always creates data in strict mode. +通常,ABI 解ç å™¨æ˜¯é€šè¿‡éµå¾ªå移指针以简å•çš„æ–¹å¼ç¼–写的, +但有些解ç å™¨å¯èƒ½ä¼šå¼ºåˆ¶æ‰§è¡Œä¸¥æ ¼æ¨¡å¼ã€‚ +Solidity ABI 解ç å™¨ç›®å‰å¹¶ä¸å¼ºåˆ¶æ‰§è¡Œä¸¥æ ¼æ¨¡å¼ï¼Œä½†ç¼–ç å™¨æ€»æ˜¯ä»¥ä¸¥æ ¼æ¨¡å¼åˆ›å»ºæ•°æ®ã€‚ -Non-standard Packed Mode +éžæ ‡å‡†æ‰“åŒ…æ¨¡å¼ ======================== -Through ``abi.encodePacked()``, Solidity supports a non-standard packed mode where: +通过 ``abi.encodePacked()``,Solidity支æŒä¸€ç§éžæ ‡å‡†çš„打包模å¼ï¼Œå…¶ä¸­ï¼š -- types shorter than 32 bytes are concatenated directly, without padding or sign extension -- dynamic types are encoded in-place and without the length. -- array elements are padded, but still encoded in-place +- 短于32字节的类型直接连接,没有填充或符å·æ‰©å±•ã€‚ +- 动æ€ç±»åž‹æ˜¯ç›´æŽ¥ç¼–ç çš„,没有长度。 +- 数组元素被填充,但ä»è¢«æ˜¯ç›´æŽ¥ç¼–ç  -Furthermore, structs as well as nested arrays are not supported. +此外,ä¸æ”¯æŒç»“构以åŠåµŒå¥—数组。 -As an example, the encoding of ``int16(-1), bytes1(0x42), uint16(0x03), string("Hello, world!")`` results in: +例如,对 ``int16(-1), bytes1(0x42), uint16(0x03), string("Hello, world!")`` 进行编ç å°†ç”Ÿæˆå¦‚下结果 .. code-block:: none @@ -764,63 +762,51 @@ As an example, the encoding of ``int16(-1), bytes1(0x42), uint16(0x03), string(" ^^^^ int16(-1) ^^ bytes1(0x42) ^^^^ uint16(0x03) - ^^^^^^^^^^^^^^^^^^^^^^^^^^ string("Hello, world!") without a length field + ^^^^^^^^^^^^^^^^^^^^^^^^^^ 字符串("Hello, world!") 没有长度字段 -More specifically: +更具体地说: -- During the encoding, everything is encoded in-place. This means that there is - no distinction between head and tail, as in the ABI encoding, and the length - of an array is not encoded. -- The direct arguments of ``abi.encodePacked`` are encoded without padding, - as long as they are not arrays (or ``string`` or ``bytes``). -- The encoding of an array is the concatenation of the - encoding of its elements **with** padding. -- Dynamically-sized types like ``string``, ``bytes`` or ``uint[]`` are encoded - without their length field. -- The encoding of ``string`` or ``bytes`` does not apply padding at the end, - unless it is part of an array or struct (then it is padded to a multiple of - 32 bytes). +- 在编ç è¿‡ç¨‹ä¸­ï¼Œæ‰€æœ‰ä¸œè¥¿éƒ½æ˜¯ç›´æŽ¥ç¼–ç çš„。这æ„味ç€æ²¡æœ‰åƒABIç¼–ç é‚£æ ·åŒºåˆ†å¤´å’Œå°¾ï¼Œä¹Ÿæ²¡æœ‰å¯¹æ•°ç»„的长度进行编ç ã€‚ +- ``abi.encodePacked`` 的直接å‚数被编ç ï¼Œ + åªè¦ä¸æ˜¯æ•°ç»„(或 ``string`` 或 ``bytes`` ),就ä¸éœ€è¦å¡«å……。 +- 一个数组的编ç æ˜¯å…¶å…ƒç´ çš„ç¼–ç  **与** 填充的连接。 +- 动æ€å¤§å°çš„类型,如 ``string``, ``bytes`` 或 ``uint[]``,在编ç æ—¶æ²¡æœ‰é•¿åº¦å­—段。 +- ``string`` 或 ``bytes`` çš„ç¼–ç ä¸ä¼šåœ¨æœ«å°¾åº”用填充, + 除éžå®ƒæ˜¯æ•°ç»„或结构体的一部分(然åŽå®ƒè¢«å¡«å……为32字节的å€æ•°ï¼‰ã€‚ -In general, the encoding is ambiguous as soon as there are two dynamically-sized elements, -because of the missing length field. +一般æ¥è¯´ï¼Œåªè¦æœ‰ä¸¤ä¸ªåŠ¨æ€å¤§å°çš„元素,编ç å°±ä¼šæ¨¡ç³Šä¸æ¸…,因为缺少长度字段。 -If padding is needed, explicit type conversions can be used: ``abi.encodePacked(uint16(0x12)) == hex"0012"``. +如果需è¦å¡«å……,å¯ä»¥ä½¿ç”¨æ˜Žç¡®çš„类型转æ¢ï¼š ``abi.encodePacked(uint16(0x12)) == hex"0012"``。 -Since packed encoding is not used when calling functions, there is no special support -for prepending a function selector. Since the encoding is ambiguous, there is no decoding function. +由于在调用函数时ä¸ä½¿ç”¨æ‰“包编ç ï¼Œæ‰€ä»¥æ²¡æœ‰ç‰¹åˆ«æ”¯æŒé¢„留函数选择器。 +由于编ç æ˜¯æ¨¡ç³Šçš„,所以没有解ç åŠŸèƒ½ã€‚ .. warning:: - If you use ``keccak256(abi.encodePacked(a, b))`` and both ``a`` and ``b`` are dynamic types, - it is easy to craft collisions in the hash value by moving parts of ``a`` into ``b`` and - vice-versa. More specifically, ``abi.encodePacked("a", "bc") == abi.encodePacked("ab", "c")``. - If you use ``abi.encodePacked`` for signatures, authentication or data integrity, make - sure to always use the same types and check that at most one of them is dynamic. - Unless there is a compelling reason, ``abi.encode`` should be preferred. + 如果使用 ``keccak256(abi.encodePacked(a,b))`` 并且 ``a`` å’Œ ``b`` 都是动æ€ç±»åž‹ï¼Œ + 那么通过将 ``a`` 的部分移动到 ``b`` 中,很容易在哈希值中产生冲çªï¼Œå之亦然。 + 更具体地说, ``abi.encodePacked("a", "bc") == abi.encodePacked("ab", "c")``。 + 如果你使用 ``abi.encodePacked`` 进行签åã€è®¤è¯æˆ–æ•°æ®å®Œæ•´æ€§ï¼Œç¡®ä¿æ€»æ˜¯ä½¿ç”¨ç›¸åŒçš„类型, + 并检查其中最多一个是动æ€çš„。除éžæœ‰ä»¤äººä¿¡æœçš„ç†ç”±ï¼Œå¦åˆ™åº”首选 ``abi.encode``。 .. _indexed_event_encoding: -Encoding of Indexed Event Parameters +索引事件å‚æ•°çš„ç¼–ç  ==================================== -Indexed event parameters that are not value types, i.e. arrays and structs are not -stored directly but instead a Keccak-256 hash of an encoding is stored. This encoding -is defined as follows: +ä¸å±žäºŽå€¼ç±»åž‹çš„索引事件å‚数,å³æ•°ç»„和结构,ä¸ç›´æŽ¥å­˜å‚¨ï¼Œ +而是存储一个编ç çš„ Keccak-256 哈希值。这个编ç çš„定义如下: -- the encoding of a ``bytes`` and ``string`` value is just the string contents - without any padding or length prefix. -- the encoding of a struct is the concatenation of the encoding of its members, - always padded to a multiple of 32 bytes (even ``bytes`` and ``string``). -- the encoding of an array (both dynamically- and statically-sized) is - the concatenation of the encoding of its elements, always padded to a multiple - of 32 bytes (even ``bytes`` and ``string``) and without any length prefix +- ``bytes`` å’Œ ``string`` 值的编ç åªæ˜¯å­—符串的内容,没有任何填充或长度å‰ç¼€ã€‚ +- 结构的编ç æ˜¯å…¶æˆå‘˜ç¼–ç çš„串è”,总是填充为32字节的å€æ•°ï¼ˆç”šè‡³æ˜¯ ``bytes`` å’Œ ``string``)。 +- 数组的编ç ï¼ˆåŒ…括动æ€å’Œé™æ€å¤§å°ï¼‰æ˜¯å…¶å…ƒç´ ç¼–ç çš„连接, + 总是填充为32字节的å€æ•°ï¼ˆç”šè‡³æ˜¯ ``bytes`` å’Œ ``string``),没有任何长度å‰ç¼€ã€‚ -In the above, as usual, a negative number is padded by sign extension and not zero padded. -``bytesNN`` types are padded on the right while ``uintNN`` / ``intNN`` are padded on the left. +在上é¢ï¼Œåƒå¾€å¸¸ä¸€æ ·ï¼Œä¸€ä¸ªè´Ÿæ•°è¢«å¡«å……符å·æ‰©å±•ï¼Œè€Œä¸æ˜¯é›¶å¡«å……。 +``bytesNN`` 类型被填充在å³è¾¹ï¼Œè€Œ ``uintNN`` / ``intNN`` 被填充在左边。 .. warning:: - The encoding of a struct is ambiguous if it contains more than one dynamically-sized - array. Because of that, always re-check the event data and do not rely on the search result - based on the indexed parameters alone. + 如果一个结构包å«ä¸€ä¸ªä»¥ä¸Šçš„动æ€å¤§å°çš„数组,那么它的编ç æ˜¯ä¸æ˜Žç¡®çš„。 + 正因为如此,è¦ç»å¸¸é‡æ–°æ£€æŸ¥äº‹ä»¶æ•°æ®ï¼Œä¸è¦åªä¾èµ–基于索引å‚æ•°çš„æœç´¢ç»“果。 diff --git a/docs/analysing-compilation-output.rst b/docs/analysing-compilation-output.rst index 183f773223d5..c8212210b38c 100644 --- a/docs/analysing-compilation-output.rst +++ b/docs/analysing-compilation-output.rst @@ -1,15 +1,15 @@ .. index:: analyse, asm ############################# -Analysing the Compiler Output +分æžç¼–译器的输出结果 ############################# -It is often useful to look at the assembly code generated by the compiler. The generated binary, -i.e., the output of ``solc --bin contract.sol``, is generally difficult to read. It is recommended -to use the flag ``--asm`` to analyse the assembly output. Even for large contracts, looking at a -visual diff of the assembly before and after a change is often very enlightening. +看一下编译器生æˆçš„汇编代ç å¾€å¾€æ˜¯æœ‰ç”¨çš„。生æˆçš„二进制文件, +å³ ``solc --bin contract.sol`` 的输出,通常很难阅读。 +建议使用标志 ``--asm`` æ¥åˆ†æžæ±‡ç¼–输出。 +å³ä½¿æ˜¯å¾ˆå¤§çš„åˆçº¦ï¼Œçœ‹ä¸€ä¸‹æ”¹å˜å‰åŽçš„汇编结果的差异,往往是很有å¯å‘的。 -Consider the following contract (named, say ``contract.sol``): +以下åˆçº¦ï¼ˆå‘½å为 ``contract.sol`` )为例: .. code-block:: solidity @@ -21,7 +21,7 @@ Consider the following contract (named, say ``contract.sol``): } } -The following would be the output of ``solc --asm contract.sol`` +以下是 ``solc --asm contract.sol`` 的输出 .. code-block:: none @@ -169,24 +169,20 @@ The following would be the output of ``solc --asm contract.sol`` auxdata: 0xa2646970667358221220a5874f19737ddd4c5d77ace1619e5160c67b3d4bedac75fce908fed32d98899864736f6c637827302e382e342d646576656c6f702e323032312e332e33302b636f6d6d69742e65613065363933380058 } -Alternatively, the above output can also be obtained from `Remix `_, -under the option "Compilation Details" after compiling a contract. +å¦å¤–,上述输出也å¯ä»¥ä»Ž `Remix `_ , +在编译åˆçº¦åŽçš„ "编译细节" 选项下获得。 -Notice that the ``asm`` output starts with the creation / constructor code. The deploy code is -provided as part of the sub object (in the above example, it is part of the sub-object ``sub_0``). -The ``auxdata`` field corresponds to the contract :ref:`metadata -`. The comments in the assembly output point to the -source location. Note that ``#utility.yul`` is an internally generated file of utility functions -that can be obtained using the flags ``--combined-json -generated-sources,generated-sources-runtime``. +请注æ„, ``asm`` 输出以创建/构造器代ç å¼€å§‹ã€‚ +部署代ç æ˜¯ä½œä¸ºå­å¯¹è±¡çš„一部分æ供的(在上é¢çš„例å­ä¸­ï¼Œå®ƒæ˜¯å­å¯¹è±¡ ``sub_0`` 的一部分)。 +``auxdata`` 字段对应于åˆçº¦ :ref:`å…ƒæ•°æ® ` 。 +汇编输出中的注释指å‘æºæ–‡ä»¶çš„ä½ç½®ã€‚æ³¨æ„ ``#utility.yul`` 是一个内部生æˆçš„实用函数文件, +å¯ä»¥ä½¿ç”¨æ ‡å¿— ``--combined-json generated-sources,generated-sources-runtime`` 获得。 -Similarly, the optimized assembly can be obtained with the command: ``solc --optimize --asm -contract.sol``. Often times, it is interesting to see if two different sources in Solidity result in -the same optimized code. For example, to see if the expressions ``(a * b) / c``, ``a * b / c`` -generates the same bytecode. This can be easily done by taking a ``diff`` of the corresponding -assembly output, after potentially stripping comments that reference the source locations. +类似地,å¯ä»¥é€šè¿‡ ``solc --optimize --asm contract.sol`` 命令获得优化åŽçš„程åºé›†ã€‚ +通常情况下,观察两个ä¸åŒçš„Solidityæºæ˜¯å¦ä¼šäº§ç”Ÿç›¸åŒçš„优化代ç æ˜¯å¾ˆæœ‰è¶£çš„。 +ä¾‹å¦‚ï¼ŒæŸ¥çœ‹è¡¨è¾¾å¼ ``(a * b) / c``, ``a * b / c`` 是å¦ç”Ÿæˆç›¸åŒçš„字节ç ã€‚ +在å¯èƒ½çš„è¯ï¼Œåœ¨å‰¥ç¦»å¼•ç”¨æºä½ç½®çš„注释之åŽï¼Œé€šè¿‡èŽ·å–相应程åºé›†è¾“出的 ``diff`` 很容易åšåˆ°è¿™ä¸€ç‚¹ã€‚ .. note:: - The ``--asm`` output is not designed to be machine readable. Therefore, there may be breaking - changes on the output between minor versions of solc. + ``--asm`` 的输出ä¸æ˜¯è®¾è®¡æˆæœºå™¨å¯è¯»çš„。因此,在solcçš„å„个å°ç‰ˆæœ¬ä¹‹é—´ï¼Œè¾“出å¯èƒ½ä¼šæœ‰é‡å¤§çš„å˜åŒ–。 diff --git a/docs/assembly.rst b/docs/assembly.rst index e08ff9f627c8..480f539f375b 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -1,43 +1,39 @@ .. _inline-assembly: ############### -Inline Assembly +内è”汇编 ############### .. index:: ! assembly, ! asm, ! evmasm -You can interleave Solidity statements with inline assembly in a language close -to the one of the Ethereum Virtual Machine. This gives you more fine-grained control, -which is especially useful when you are enhancing the language by writing libraries. +您å¯ä»¥ç”¨æŽ¥è¿‘Ethereum虚拟机的语言,将Solidity语å¥ä¸Žå†…è”汇编交错使用。 +这给了您更精细的控制,这在您通过编写库æ¥å¢žå¼ºè¯­è¨€æ—¶ç‰¹åˆ«æœ‰ç”¨ã€‚ -The language used for inline assembly in Solidity is called :ref:`Yul ` -and it is documented in its own section. This section will only cover -how the inline assembly code can interface with the surrounding Solidity code. +在 Solidity 中用于内è”汇编的语言被称为 :ref:`Yul `,它在自己的章节中被记录。 +本节将åªæ¶‰åŠå†…è”汇编代ç å¦‚何在 Solidity 代ç å†…交互。 .. warning:: - Inline assembly is a way to access the Ethereum Virtual Machine - at a low level. This bypasses several important safety - features and checks of Solidity. You should only use it for - tasks that need it, and only if you are confident with using it. + 内è”汇编是一ç§åœ¨ä½Žç­‰çº§ä¸Šè®¿é—®Ethereum虚拟机的方å¼ã€‚ + 这绕过了Solidity的几个é‡è¦å®‰å…¨åŠŸèƒ½å’Œæ£€æŸ¥ã€‚ + 您应该åªåœ¨éœ€è¦å®ƒçš„任务中使用它,而且åªæœ‰åœ¨æ‚¨å¯¹ä½¿ç”¨å®ƒæœ‰ä¿¡å¿ƒçš„情况下。 -An inline assembly block is marked by ``assembly { ... }``, where the code inside -the curly braces is code in the :ref:`Yul ` language. +一个内è”汇编å—ç”± ``assembly { ... }`` 标记的,其中大括å·å†…的代ç æ˜¯ :ref:`Yul ` 语言中的代ç ã€‚ -The inline assembly code can access local Solidity variables as explained below. +内è”汇编代ç å¯ä»¥è®¿é—®æœ¬åœ° Solidity å˜é‡ï¼Œå¦‚下所述。 -Different inline assembly blocks share no namespace, i.e. it is not possible -to call a Yul function or access a Yul variable defined in a different inline assembly block. +ä¸åŒçš„内è”汇编å—ä¸å…±äº«å称空间, +å³ä¸èƒ½è°ƒç”¨æˆ–访问一个在ä¸åŒå†…è”汇编å—中定义的Yul函数或å˜é‡ã€‚ -Example +ä¾‹å­ ------- -The following example provides library code to access the code of another contract and -load it into a ``bytes`` variable. This is possible with "plain Solidity" too, by using -``
.code``. But the point here is that reusable assembly libraries can enhance the -Solidity language without a compiler change. +下é¢ä¾‹å­å±•ç¤ºäº†ä¸€ä¸ªåº“åˆçº¦çš„代ç ï¼Œå®ƒå¯ä»¥å–å¾—å¦ä¸€ä¸ªåˆçº¦çš„代ç ï¼Œ +并将其加载到一个 ``bytes`` å˜é‡ä¸­ã€‚ 通过使用 ``
.code``, +这在 "普通Solidity" 中也是å¯èƒ½çš„。但这里的é‡ç‚¹æ˜¯ï¼Œå¯é‡ç”¨çš„汇编库å¯ä»¥å¢žå¼º Solidity 语言, +而ä¸éœ€è¦æ”¹å˜ç¼–译器。 .. code-block:: solidity @@ -47,23 +43,22 @@ Solidity language without a compiler change. library GetCode { function at(address addr) public view returns (bytes memory code) { assembly { - // retrieve the size of the code, this needs assembly + // 获å–代ç å¤§å°ï¼Œè¿™éœ€è¦æ±‡ç¼–语言 let size := extcodesize(addr) - // allocate output byte array - this could also be done without assembly - // by using code = new bytes(size) + // 分é…输出字节数组 – 这也å¯ä»¥ä¸ç”¨æ±‡ç¼–语言æ¥å®žçŽ° + // 通过使用 code = new bytes(size) code := mload(0x40) - // new "memory end" including padding + // 包括补ä½åœ¨å†…æ–°çš„ “memory end†mstore(0x40, add(code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - // store length in memory + // 把长度ä¿å­˜åˆ°å†…存中 mstore(code, size) - // actually retrieve the code, this needs assembly + // 实际获å–代ç ï¼Œè¿™éœ€è¦æ±‡ç¼–语言 extcodecopy(addr, add(code, 0x20), 0, size) } } } -Inline assembly is also beneficial in cases where the optimizer fails to produce -efficient code, for example: +在优化器ä¸èƒ½äº§ç”Ÿé«˜æ•ˆä»£ç çš„情况下,内è”汇编也是有益的,例如: .. code-block:: solidity @@ -72,16 +67,16 @@ efficient code, for example: library VectorSum { - // This function is less efficient because the optimizer currently fails to - // remove the bounds checks in array access. + // 这个函数的执行效率比较低, + // 因为优化器当å‰æ— æ³•åˆ é™¤æ•°ç»„访问中的边界检查。 function sumSolidity(uint[] memory data) public pure returns (uint sum) { for (uint i = 0; i < data.length; ++i) sum += data[i]; } - // We know that we only access the array in bounds, so we can avoid the check. - // 0x20 needs to be added to an array because the first slot contains the - // array length. + // 我们知é“我们åªèƒ½åœ¨æ•°ç»„范围内访问数组元素,所以我们å¯ä»¥é¿å…检查。 + // 由于 ABI ç¼–ç ä¸­æ•°ç»„æ•°æ®çš„第一个字(32 字节)的ä½ç½®ä¿å­˜çš„是数组长度, + // 所以我们在访问数组元素时需è¦åŠ å…¥ 0x20 作为å移é‡ã€‚ function sumAsm(uint[] memory data) public pure returns (uint sum) { for (uint i = 0; i < data.length; ++i) { assembly { @@ -90,21 +85,20 @@ efficient code, for example: } } - // Same as above, but accomplish the entire code within inline assembly. + // 和上é¢ä¸€æ ·ï¼Œä½†åœ¨å†…è”汇编内完æˆæ•´ä¸ªä»£ç ã€‚ function sumPureAsm(uint[] memory data) public pure returns (uint sum) { assembly { - // Load the length (first 32 bytes) + // åŠ è½½æ•°ç»„é•¿åº¦ï¼ˆå‰ 32 字节) let len := mload(data) - // Skip over the length field. + // 略过长度字段。 // - // Keep temporary variable so it can be incremented in place. + // ä¿æŒä¸´æ—¶å˜é‡ä»¥ä¾¿å®ƒå¯ä»¥åœ¨åŽŸåœ°å¢žåŠ ã€‚ // - // NOTE: incrementing data would result in an unusable - // data variable after this assembly block + // 注æ„:递增data会导致在这个汇编å—之åŽå‡ºçŽ°ä¸€ä¸ªæ— æ³•ä½¿ç”¨çš„dataå˜é‡ã€‚ let dataElementLocation := add(data, 0x20) - // Iterate until the bound is not met. + // 迭代到数组数æ®ç»“æŸã€‚ for { let end := add(dataElementLocation, mul(len, 0x20)) } lt(dataElementLocation, end) @@ -118,28 +112,24 @@ efficient code, for example: .. index:: selector; of a function -Access to External Variables, Functions and Libraries +访问外部å˜é‡ã€å‡½æ•°å’Œåº“ ----------------------------------------------------- -You can access Solidity variables and other identifiers by using their name. +您å¯ä»¥é€šè¿‡ä½¿ç”¨å…¶å称æ¥è®¿é—® Solidity å˜é‡å’Œå…¶ä»–标识符。 -Local variables of value type are directly usable in inline assembly. -They can both be read and assigned to. +值类型的局部å˜é‡å¯ä»¥ç›´æŽ¥ç”¨äºŽå†…è”汇编。它们既å¯ä»¥è¢«è¯»å–也å¯ä»¥è¢«èµ‹å€¼ã€‚ -Local variables that refer to memory evaluate to the address of the variable in memory, not the value itself. -Such variables can also be assigned to, but note that an assignment will only change the pointer and not the data -and that it is your responsibility to respect Solidity's memory management. -See :ref:`Conventions in Solidity `. +指å‘内存的局部å˜é‡æ˜¯æŒ‡å†…存中å˜é‡çš„地å€ï¼Œè€Œä¸æ˜¯å€¼æœ¬èº«ã€‚ +这样的å˜é‡ä¹Ÿå¯ä»¥è¢«èµ‹å€¼ï¼Œä½†è¯·æ³¨æ„,赋值åªä¼šæ”¹å˜æŒ‡é’ˆè€Œä¸æ˜¯æ•°æ®ï¼Œ +å°Šé‡ Solidity 的内存管ç†æ˜¯æ‚¨çš„责任。 +å‚è§ :ref:`Solidity的惯例 `。 -Similarly, local variables that refer to statically-sized calldata arrays or calldata structs -evaluate to the address of the variable in calldata, not the value itself. -The variable can also be assigned a new offset, but note that no validation is performed to ensure that -the variable will not point beyond ``calldatasize()``. +åŒæ ·åœ°ï¼Œå¼•ç”¨é™æ€å¤§å°çš„calldata数组或calldata结构的局部å˜é‡ä¼šæŒ‡å‘calldata中å˜é‡çš„地å€ï¼Œ +而ä¸æ˜¯å€¼æœ¬èº«ã€‚å˜é‡ä¹Ÿå¯ä»¥è¢«åˆ†é…一个新的å移é‡ï¼Œä½†æ˜¯è¯·æ³¨æ„, +没有进行验è¯ä»¥ç¡®ä¿å˜é‡ä¸ä¼šæŒ‡å‘超过 ``calldatasize()`` 的地方。 -For external function pointers the address and the function selector can be -accessed using ``x.address`` and ``x.selector``. -The selector consists of four right-aligned bytes. -Both values can be assigned to. For example: +对于外部函数指针,地å€å’Œå‡½æ•°é€‰æ‹©å™¨å¯ä»¥ç”¨ ``x.address`` å’Œ ``x.selector`` æ¥è®¿é—®ã€‚ +选择器由四个å³å¯¹é½çš„字节组æˆã€‚两个值都å¯ä»¥è¢«èµ‹å€¼ã€‚比如说: .. code-block:: solidity :force: @@ -148,7 +138,7 @@ Both values can be assigned to. For example: pragma solidity >=0.8.10 <0.9.0; contract C { - // Assigns a new selector and address to the return variable @fun + // 将一个新的选择器和地å€åˆ†é…给返回å˜é‡ @fun function combineToFunctionPointer(address newAddress, uint newSelector) public pure returns (function() external fun) { assembly { fun.selector := newSelector @@ -157,24 +147,20 @@ Both values can be assigned to. For example: } } -For dynamic calldata arrays, you can access -their calldata offset (in bytes) and length (number of elements) using ``x.offset`` and ``x.length``. -Both expressions can also be assigned to, but as for the static case, no validation will be performed -to ensure that the resulting data area is within the bounds of ``calldatasize()``. +对于动æ€çš„calldata数组,您å¯ä»¥ä½¿ç”¨ ``x.offset`` å’Œ ``x.length`` 访问它们的calldataå移é‡ï¼ˆå­—节)和长度(元素数)。 +这两个表达å¼ä¹Ÿå¯ä»¥è¢«èµ‹å€¼ï¼Œä½†æ˜¯å’Œé™æ€æƒ…况一样,ä¸ä¼šè¿›è¡ŒéªŒè¯ä»¥ç¡®ä¿äº§ç”Ÿçš„æ•°æ®åŒºåŸŸåœ¨ ``calldatasize()`` 的范围内。 -For local storage variables or state variables, a single Yul identifier -is not sufficient, since they do not necessarily occupy a single full storage slot. -Therefore, their "address" is composed of a slot and a byte-offset -inside that slot. To retrieve the slot pointed to by the variable ``x``, you -use ``x.slot``, and to retrieve the byte-offset you use ``x.offset``. -Using ``x`` itself will result in an error. -You can also assign to the ``.slot`` part of a local storage variable pointer. -For these (structs, arrays or mappings), the ``.offset`` part is always zero. -It is not possible to assign to the ``.slot`` or ``.offset`` part of a state variable, -though. +对于本地存储å˜é‡æˆ–状æ€å˜é‡ï¼Œä¸€ä¸ªYul标识符是ä¸å¤Ÿçš„,因为它们ä¸ä¸€å®šå æ®ä¸€ä¸ªå®Œæ•´çš„存储槽。 +因此,它们的 "地å€" 是由一个槽和槽内的字节å移é‡ç»„æˆã€‚è¦æ£€ç´¢å˜é‡ ``x`` 所指å‘的槽, +您å¯ä»¥ä½¿ç”¨ ``x.slot``,è¦æ£€ç´¢å­—节å移é‡ï¼Œæ‚¨å¯ä»¥ä½¿ç”¨ ``x.offset`` 。 +使用 ``x`` 本身会导致错误。 -Local Solidity variables are available for assignments, for example: +您也å¯ä»¥åˆ†é…给本地存储å˜é‡æŒ‡é’ˆçš„ ``.slot`` 部分。 +对于这些(结构ã€æ•°ç»„或映射), ``.offset`` 部分总是零。 +但ä¸å¯èƒ½åˆ†é…给状æ€å˜é‡çš„ ``.slot`` 或 ``.offset`` 部分。 + +本地 Solidity å˜é‡å¯ç”¨äºŽèµ‹å€¼ï¼Œä¾‹å¦‚: .. code-block:: solidity :force: @@ -186,74 +172,60 @@ Local Solidity variables are available for assignments, for example: uint b; function f(uint x) public view returns (uint r) { assembly { - // We ignore the storage slot offset, we know it is zero - // in this special case. + // 我们忽略了存储槽的å移é‡ï¼Œæˆ‘们知é“在这ç§ç‰¹æ®Šæƒ…况下它是零。 r := mul(x, sload(b.slot)) } } } .. warning:: - If you access variables of a type that spans less than 256 bits - (for example ``uint64``, ``address``, or ``bytes16``), - you cannot make any assumptions about bits not part of the - encoding of the type. Especially, do not assume them to be zero. - To be safe, always clear the data properly before you use it - in a context where this is important: - ``uint32 x = f(); assembly { x := and(x, 0xffffffff) /* now use x */ }`` - To clean signed types, you can use the ``signextend`` opcode: + 如果您访问一个跨度å°äºŽ256ä½çš„类型的å˜é‡ï¼ˆä¾‹å¦‚ ``uint64``, ``address``,或 ``bytes16``), + 您ä¸èƒ½å¯¹ä¸å±žäºŽè¯¥ç±»åž‹çš„ç¼–ç çš„ä½åšä»»ä½•å‡è®¾ã€‚特别是,ä¸è¦å‡è®¾å®ƒä»¬æ˜¯é›¶ã€‚ + 为了安全起è§ï¼Œåœ¨ä½¿ç”¨å‰ä¸€å®šè¦é€‚当清除数æ®ï¼Œå› ä¸ºè¿™ä¸€ç‚¹å¾ˆé‡è¦ï¼š + ``uint32 x = f(); assembly { x := and(x, 0xffffff) /* 现在使用 x */ }`` + 为了清除有符å·çš„类型,您å¯ä»¥ä½¿ç”¨ ``signextend`` æ“作ç ã€‚ ``assembly { signextend(, x) }`` -Since Solidity 0.6.0, the name of a inline assembly variable may not -shadow any declaration visible in the scope of the inline assembly block -(including variable, contract and function declarations). +自Solidity 0.6.0以æ¥ï¼Œå†…è”汇编å˜é‡çš„å称ä¸èƒ½å½±å°„内è”汇编å—范围内å¯è§çš„任何声明 +(包括å˜é‡ã€åˆçº¦å’Œå‡½æ•°å£°æ˜Žï¼‰ã€‚ -Since Solidity 0.7.0, variables and functions declared inside the -inline assembly block may not contain ``.``, but using ``.`` is -valid to access Solidity variables from outside the inline assembly block. +自Solidity 0.7.0以æ¥ï¼Œåœ¨å†…è”程åºå—内声明的å˜é‡å’Œå‡½æ•°ä¸èƒ½åŒ…å« ``.``, +但使用 ``.`` å¯ä»¥æœ‰æ•ˆåœ°ä»Žå†…è”程åºå—外访问Solidityå˜é‡ã€‚ -Things to Avoid +需è¦é¿å…的事情 --------------- -Inline assembly might have a quite high-level look, but it actually is extremely -low-level. Function calls, loops, ifs and switches are converted by simple -rewriting rules and after that, the only thing the assembler does for you is re-arranging -functional-style opcodes, counting stack height for -variable access and removing stack slots for assembly-local variables when the end -of their block is reached. +内è”汇编å¯èƒ½æœ‰ä¸€ä¸ªç›¸å½“高级的外观,但它实际上是éžå¸¸ä½Žçº§çš„。 +函数调用ã€å¾ªçŽ¯ã€ifæ¡ä»¶å’Œswitchæ¡ä»¶éƒ½å¯ä»¥é€šè¿‡ç®€å•çš„改写规则进行转æ¢ï¼Œ +之åŽï¼Œæ±‡ç¼–器为您åšçš„唯一事情就是é‡æ–°å®‰æŽ’函数å¼çš„æ“作ç ï¼Œ +为å˜é‡è®¿é—®è®¡ç®—堆栈高度,并在达到汇编局部å˜é‡å—的末端时移除堆栈槽。 .. _conventions-in-solidity: -Conventions in Solidity +Solidity的的惯例 ----------------------- .. _assembly-typed-variables: -Values of Typed Variables +类型化å˜é‡çš„值 ========================= -In contrast to EVM assembly, Solidity has types which are narrower than 256 bits, -e.g. ``uint24``. For efficiency, most arithmetic operations ignore the fact that -types can be shorter than 256 -bits, and the higher-order bits are cleaned when necessary, -i.e., shortly before they are written to memory or before comparisons are performed. -This means that if you access such a variable -from within inline assembly, you might have to manually clean the higher-order bits -first. +与EVM汇编相å,Solidity有比256ä½æ›´çª„的类型,例如: ``uint24``。 +为了æ高效率,大多数算术è¿ç®—忽略了类型å¯ä»¥çŸ­äºŽ256ä½çš„事实,高阶ä½åœ¨å¿…è¦æ—¶è¢«æ¸…ç†ï¼Œ +例如,在它们被写入内存å‰ä¸ä¹…或在执行比较之å‰ã€‚ +è¿™æ„味ç€ï¼Œå¦‚果您从内è”汇编中访问这样的å˜é‡ï¼Œæ‚¨å¯èƒ½ä¸å¾—ä¸å…ˆæ‰‹åŠ¨æ¸…ç†é«˜é˜¶ä½ã€‚ .. _assembly-memory-management: -Memory Management +å†…å­˜ç®¡ç† ================= -Solidity manages memory in the following way. There is a "free memory pointer" -at position ``0x40`` in memory. If you want to allocate memory, use the memory -starting from where this pointer points at and update it. -There is no guarantee that the memory has not been used before and thus -you cannot assume that its contents are zero bytes. -There is no built-in mechanism to release or free allocated memory. -Here is an assembly snippet you can use for allocating memory that follows the process outlined above: +Solidity以下列方å¼ç®¡ç†å†…存。在内存中 ``0x40`` çš„ä½ç½®æœ‰ä¸€ä¸ª "空闲内存指针"。 +如果您想分é…内存,从这个指针指å‘的地方开始使用内存,并更新它。 +ä¸èƒ½ä¿è¯è¯¥å†…存以å‰æ²¡æœ‰è¢«ä½¿ç”¨è¿‡ï¼Œå› æ­¤æ‚¨ä¸èƒ½å‡è®¾å…¶å†…容为零字节。 +没有内置的机制æ¥é‡Šæ”¾æˆ–释放分é…的内存。下é¢æ˜¯ä¸€æ®µæ±‡ç¼–代ç ï¼Œ +您å¯ä»¥ç”¨å®ƒæ¥åˆ†é…内存,它éµå¾ªä¸Šè¿°çš„过程: .. code-block:: yul @@ -262,38 +234,34 @@ Here is an assembly snippet you can use for allocating memory that follows the p mstore(0x40, add(pos, length)) } -The first 64 bytes of memory can be used as "scratch space" for short-term -allocation. The 32 bytes after the free memory pointer (i.e., starting at ``0x60``) -are meant to be zero permanently and is used as the initial value for -empty dynamic memory arrays. -This means that the allocatable memory starts at ``0x80``, which is the initial value -of the free memory pointer. +å‰64字节的内存å¯ä»¥ä½œä¸ºçŸ­æœŸåˆ†é…çš„ "划痕空间(scratch space)"。 +空闲内存指针之åŽçš„32字节(å³ä»Ž ``0x60`` 开始)是指永久为零, +并作为空的动æ€å†…存数组的åˆå§‹å€¼ä½¿ç”¨ã€‚ +è¿™æ„味ç€å¯åˆ†é…的内存从 ``0x80`` 开始,也就是空闲内存指针的åˆå§‹å€¼ã€‚ + +Solidity中内存数组中的元素总是å æ®32字节的å€æ•° +(对于 ``bytes1[]`` æ¥è¯´ä¹Ÿæ˜¯å¦‚此,但对于 ``bytes`` å’Œ ``string`` æ¥è¯´ä¸æ˜¯è¿™æ ·ï¼‰ã€‚ +多维内存数组是指å‘内存数组的指针。一个动æ€æ•°ç»„的长度被存储在数组的第一个槽里,åŽé¢æ˜¯æ•°ç»„元素。 -Elements in memory arrays in Solidity always occupy multiples of 32 bytes (this is -even true for ``bytes1[]``, but not for ``bytes`` and ``string``). Multi-dimensional memory -arrays are pointers to memory arrays. The length of a dynamic array is stored at the -first slot of the array and followed by the array elements. .. warning:: - Statically-sized memory arrays do not have a length field, but it might be added later - to allow better convertibility between statically and dynamically-sized arrays; so, - do not rely on this. -Memory Safety + é™æ€å¤§å°çš„内存数组没有长度字段,但以åŽå¯èƒ½ä¼šåŠ å…¥é•¿åº¦å­—段, + 以便在é™æ€å¤§å°çš„数组和动æ€å¤§å°çš„数组之间有更好的转æ¢æ€§ï¼›æ‰€ä»¥ï¼Œä¸è¦ä¾èµ–这个特性。 + +内存安全 ============= -Without the use of inline assembly, the compiler can rely on memory to remain in a well-defined -state at all times. This is especially relevant for :ref:`the new code generation pipeline via Yul IR `: -this code generation path can move local variables from stack to memory to avoid stack-too-deep errors and -perform additional memory optimizations, if it can rely on certain assumptions about memory use. +在ä¸ä½¿ç”¨å†…è”汇编的情况下,编译器å¯ä»¥ä¾é å†…存在任何时候都ä¿æŒä¸€ä¸ªè‰¯å¥½çš„定义状æ€ã€‚ +这对于 :ref:`通过 Yul IR 的新代ç ç”Ÿæˆç®¡é“ ` æ¥è¯´å°¤å…¶é‡è¦ï¼š +这个代ç ç”Ÿæˆè·¯å¾„å¯ä»¥å°†å±€éƒ¨å˜é‡ä»Žå †æ ˆè½¬ç§»åˆ°å†…存,以é¿å…堆栈过深的错误,并执行é¢å¤–的内存优化, +如果它å¯ä»¥ä¾èµ–于对内存使用的æŸäº›å‡è®¾çš„è¯ã€‚ -While we recommend to always respect Solidity's memory model, inline assembly allows you to use memory -in an incompatible way. Therefore, moving stack variables to memory and additional memory optimizations are, -by default, globally disabled in the presence of any inline assembly block that contains a memory operation -or assigns to Solidity variables in memory. +è™½ç„¶æˆ‘ä»¬å»ºè®®å§‹ç»ˆå°Šé‡ Solidity 的内存模型,但内è”汇编å…许您以ä¸å…¼å®¹çš„æ–¹å¼ä½¿ç”¨å†…存。 +因此,在任何包å«å†…å­˜æ“作或在内存中分é…ç»™ Solidity å˜é‡çš„内è”汇编å—存在的情况下, +将堆栈å˜é‡ç§»åŠ¨åˆ°å†…存和é¢å¤–的内存优化默认为全局ç¦ç”¨ã€‚ -However, you can specifically annotate an assembly block to indicate that it in fact respects Solidity's memory -model as follows: +然而,您å¯ä»¥ç‰¹åˆ«æ³¨é‡Šä¸€ä¸ªæ±‡ç¼–å—,以表明它实际上是éµå¾ª Solidity 内存模型的,如下所示: .. code-block:: solidity @@ -301,20 +269,19 @@ model as follows: ... } -In particular, a memory-safe assembly block may only access the following memory ranges: +特别的是,一个内存安全的汇编å—åªèƒ½è®¿é—®ä»¥ä¸‹å†…存范围: -- Memory allocated by yourself using a mechanism like the ``allocate`` function described above. -- Memory allocated by Solidity, e.g. memory within the bounds of a memory array you reference. -- The scratch space between memory offset 0 and 64 mentioned above. -- Temporary memory that is located *after* the value of the free memory pointer at the beginning of the assembly block, - i.e. memory that is "allocated" at the free memory pointer without updating the free memory pointer. +- 通过上述 ``allocate`` 函数这样的机制由自己分é…的内存。 +- ç”± Solidity 分é…的内存,例如,在您引用的内存数组的范围内的内存。 +- 上é¢æ到的内存å移é‡0å’Œ64之间的划痕空间。 +- ä½äºŽæ±‡ç¼–å—开始时的空闲内存指针值 *之åŽ* 的临时内存, + å³åœ¨ç©ºé—²å†…存指针上 “分é…†而ä¸æ›´æ–°ç©ºé—²å†…存指针的内存。 -Furthermore, if the assembly block assigns to Solidity variables in memory, you need to assure that accesses to -the Solidity variables only access these memory ranges. +此外,如果汇编å—分é…给内存中的 Solidity å˜é‡ï¼Œåˆ™éœ€è¦ç¡®ä¿å¯¹ Solidity å˜é‡çš„访问åªè®¿é—®è¿™äº›å†…存范围。 -Since this is mainly about the optimizer, these restrictions still need to be followed, even if the assembly block -reverts or terminates. As an example, the following assembly snippet is not memory safe, because the value of -``returndatasize()`` may exceed the 64 byte scratch space: +由于这主è¦æ˜¯å…³äºŽä¼˜åŒ–器的,所以这些é™åˆ¶ä»ç„¶éœ€è¦è¢«éµå®ˆï¼Œå³ä½¿æ±‡ç¼–å—回退或终止。 +举个例å­ï¼Œä¸‹é¢çš„汇编片段ä¸æ˜¯å†…存安全的, +因为 ``returndatasize()`` 的值å¯èƒ½ä¼šè¶…过64字节的划痕空间。 .. code-block:: solidity @@ -323,8 +290,8 @@ reverts or terminates. As an example, the following assembly snippet is not memo revert(0, returndatasize()) } -On the other hand, the following code *is* memory safe, because memory beyond the location pointed to by the -free memory pointer can safely be used as temporary scratch space: +å¦ä¸€æ–¹é¢ï¼Œä¸‹é¢çš„ä»£ç  *是* 内存安全的, +因为超出空闲内存指针所指å‘çš„ä½ç½®çš„内存å¯ä»¥å®‰å…¨åœ°ç”¨ä½œä¸´æ—¶åˆ’痕空间: .. code-block:: solidity @@ -334,10 +301,10 @@ free memory pointer can safely be used as temporary scratch space: revert(p, returndatasize()) } -Note that you do not need to update the free memory pointer if there is no following allocation, -but you can only use memory starting from the current offset given by the free memory pointer. +注æ„,如果没有åŽç»­åˆ†é…,则ä¸éœ€è¦æ›´æ–°ç©ºé—²å†…存指针, +但åªèƒ½ä½¿ç”¨ä»Žç©ºé—²å†…存指针给出的当å‰å移é‡å¼€å§‹çš„内存。 -If the memory operations use a length of zero, it is also fine to just use any offset (not only if it falls into the scratch space): +如果内存æ“作使用的长度为0,那么也å¯ä»¥ä½¿ç”¨ä»»æ„å移é‡ï¼ˆä¸ä»…仅是è½åœ¨äº†åˆ’痕空间中); .. code-block:: solidity @@ -345,8 +312,8 @@ If the memory operations use a length of zero, it is also fine to just use any o revert(0, 0) } -Note that not only memory operations in inline assembly itself can be memory-unsafe, but also assignments to -Solidity variables of reference type in memory. For example the following is not memory-safe: +请注æ„,ä¸ä»…内è”汇编中的内存æ“作本身å¯ä»¥æ˜¯å†…å­˜ä¸å®‰å…¨çš„, +而且对内存中引用类型的 Solidity å˜é‡çš„赋值也是如此。例如,以下内容就ä¸æ˜¯å†…存安全的: .. code-block:: solidity @@ -356,16 +323,22 @@ Solidity variables of reference type in memory. For example the following is not } x[0x20] = 0x42; -Inline assembly that neither involves any operations that access memory nor assigns to any Solidity variables -in memory is automatically considered memory-safe and does not need to be annotated. +æ—¢ä¸æ¶‰åŠè®¿é—®å†…存的任何æ“作,也ä¸å¯¹å†…存中的任何 Solidity å˜é‡è¿›è¡Œèµ‹å€¼çš„内è”汇编, +自动被认为是内存安全的,ä¸éœ€è¦è¢«æ³¨é‡Šã€‚ .. 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 -In case you are developing a library that is meant to be compatible across multiple versions -of Solidity, you can use a special comment to annotate an assembly block as memory-safe: +如果您正在开å‘一个è¦åœ¨å¤šä¸ª Solidity 版本之间兼容的库, +您å¯ä»¥ä½¿ç”¨ä¸€ä¸ªç‰¹æ®Šçš„注释将一个汇编å—注释为内存安全的: .. code-block:: solidity @@ -374,5 +347,10 @@ of Solidity, you can use a special comment to annotate an assembly block as memo ... } +<<<<<<< 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 cf471c5e3c5c..8628265f7d46 100644 --- a/docs/brand-guide.rst +++ b/docs/brand-guide.rst @@ -1,86 +1,75 @@ #################### -Solidity Brand Guide +Solidity å“ç‰ŒæŒ‡å— #################### -This brand guide features information on Solidity's brand policy and -logo usage guidelines. +该å“牌指å—的特点是关于Solidityçš„å“牌政策和标志使用指å—çš„ä¿¡æ¯ã€‚ -The Solidity Brand +Solidityå“牌 ================== -The Solidity programming language is an open-source, community project -governed by a core team. The core team is sponsored by the `Ethereum -Foundation `_. +Solidity编程语言是一个开æºçš„社区项目,由一个核心团队管ç†ã€‚ +该核心团队由 `以太åŠåŸºé‡‘会 `_ 赞助。 -This document aims to provide information about how to best use the -Solidity brand name and logo. +本文件旨在æ供有关如何最好地使用 Solidity å“牌å称和标识的信æ¯ã€‚ -We encourage you to read this document carefully before using the -brand name or the logo. Your cooperation is highly appreciated! +我们鼓励您在使用该å“牌å称或标志之å‰ä»”细阅读本文件。我们éžå¸¸æ„Ÿè°¢æ‚¨çš„åˆä½œ! -Solidity Brand Name +Solidity å“牌å称 =================== -"Solidity" should be used to refer to the Solidity programming language -solely. +“Solidity†应该åªç”¨æ¥æŒ‡Solidity编程语言。 -Please do not use "Solidity": +请ä¸è¦æŒ‰ä»¥ä¸‹æ–¹å¼ä½¿ç”¨ “Solidityâ€ï¼š -- To refer to any other programming language. +- 指的是任何其他编程语言。 -- In a way that is misleading or may imply association of unrelated - modules, tools, documentation, or other resources with the Solidity - programming language. +- 以一ç§è¯¯å¯¼æ€§çš„æ–¹å¼ï¼Œæˆ–å¯èƒ½æš—示ä¸ç›¸å…³çš„模å—,工具,文档 + 或其他资æºä¸Ž Solidity 编程语言的关è”。 -- In ways that confuse the community as to whether the Solidity - programming language is open-source and free to use. +- 在方å¼ä¸Šï¼Œæ··æ·†äº†ç¤¾åŒºå¯¹Solidity编程语言是å¦å¼€æºå’Œå…费使用的看法。 -Solidity Logo License +Solidityæ ‡å¿—è®¸å¯ ===================== .. image:: https://i.creativecommons.org/l/by/4.0/88x31.png :width: 88 :alt: Creative Commons License -The Solidity logo is distributed and licensed under a `Creative Commons -Attribution 4.0 International License `_. +Solidity标志是在 +`创æ„共享署å4.0国际许å¯åè®® `_ 下å‘布和许å¯çš„。 -This is the most permissive Creative Commons license and allows reuse -and modifications for any purpose. +这是最宽æ¾çš„知识共享å议,å…许为任何目的进行å†åˆ©ç”¨å’Œä¿®æ”¹ã€‚ -You are free to: +您å¯ä»¥è‡ªç”±é€‰æ‹©ä»¥ä¸‹æ–¹å¼ï¼š -- **Share** — Copy and redistribute the material in any medium or format. +- **分享** - 以任何媒介或形å¼å¤åˆ¶å’Œé‡æ–°åˆ†å‘æ料。 -- **Adapt** — Remix, transform, and build upon the material for any - purpose, even commercially. +- **修改** - 为任何目的,甚至为商业目的,对æ料进行混音,改造和构建。 -Under the following terms: +æ ¹æ®ä»¥ä¸‹æ¡æ¬¾ï¼š -- **Attribution** — You must give appropriate credit, provide a link to - the license, and indicate if changes were made. You may do so in any - reasonable manner, but not in any way that suggests that the Solidity - core team endorses you or your use. +- **ç½²å** - 您必须给予适当的信用,æ供到许å¯è¯çš„链接,并说明是å¦è¿›è¡Œäº†ä¿®æ”¹ã€‚ + 您å¯ä»¥ä»¥ä»»ä½•åˆç†çš„æ–¹å¼è¿™æ ·åšï¼Œä½†ä¸èƒ½ä»¥ä»»ä½•æ–¹å¼æš—示 Solidity 核心团队认å¯æ‚¨æˆ–您的使用。 -When using the Solidity logo, please respect the Solidity logo guidelines. +在使用Solidity标识时,请尊é‡Solidity标识指å—。 -Solidity Logo Guidelines +Solidityæ ‡å¿—æŒ‡å— ======================== .. image:: solidity_logo.svg :width: 256 -*(Right click on the logo to download it.)* +*(å³é”®ç‚¹å‡»æ ‡è¯†å³å¯ä¸‹è½½ã€‚)* -Please do not: +请ä¸è¦è¿™æ ·åšï¼š -- Change the ratio of the logo (do not stretch it or cut it). +- 改å˜æ ‡å¿—的比例(ä¸è¦æ‹‰ä¼¸æˆ–切割)。 -- Change the colors of the logo, unless it is absolutely necessary. +- 改å˜æ ‡å¿—的颜色,除éžæ˜¯ç»å¯¹å¿…è¦ã€‚ -Credits +信用 ======= -This document was, in parts, derived from the `Python Software -Foundation Trademark Usage Policy `_ -and the `Rust Media Guide `_. +本文件部分内容æ¥è‡ªäºŽ +`Python软件基金会商标使用政策 `_ +å’Œ `Ruståª’ä»‹æŒ‡å— `_ 。 diff --git a/docs/bugs.json b/docs/bugs.json index 6245bdeda5af..c853f95eddea 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -1,4 +1,14 @@ [ + { + "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", diff --git a/docs/bugs.rst b/docs/bugs.rst index 350b1e7a48e8..75c527de4401 100644 --- a/docs/bugs.rst +++ b/docs/bugs.rst @@ -3,82 +3,72 @@ .. _known_bugs: ################## -List of Known Bugs +已知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 +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 -There is another file called `bugs_by_version.json -`_, -which can be used to check which bugs affect a specific version of the compiler. +è¿˜æœ‰ä¸€ä¸ªæ–‡ä»¶å« +`bugs_by_version.json `_, +它å¯ä»¥ç”¨æ¥æ£€æŸ¥å“ªäº›bugå½±å“到特定版本的编译器。 -Contract source verification tools and also other tools interacting with -contracts should consult this list according to the following criteria: +åˆçº¦æºç éªŒè¯å·¥å…·ä»¥åŠå…¶ä»–与åˆçº¦äº¤äº’的工具应根æ®ä»¥ä¸‹æ ‡å‡†æŸ¥é˜…此列表: -- It is mildly suspicious if a contract was compiled with a nightly - compiler version instead of a released version. This list does not keep - track of unreleased or nightly versions. -- It is also mildly suspicious if a contract was compiled with a version that was - not the most recent at the time the contract was created. For contracts - created from other contracts, you have to follow the creation chain - back to a transaction and use the date of that transaction as creation date. -- It is highly suspicious if a contract was compiled with a compiler that - contains a known bug and the contract was created at a time where a newer - compiler version containing a fix was already released. +- 如果åˆçº¦æ˜¯ç”¨å¤œé—´ç¼–译器版本而ä¸æ˜¯å‘布版本编译的,那就有点å¯ç–‘了。 + 此列表ä¸è·Ÿè¸ªæœªå‘布或夜间版本。 +- 如果åˆçº¦çš„编译版本ä¸æ˜¯åˆçº¦åˆ›å»ºæ—¶çš„最新版本,则也有点å¯ç–‘。 + 对于从其他åˆçº¦åˆ›å»ºçš„åˆçº¦ï¼Œæ‚¨å¿…须按照创建链返回到事务,并使用该事务的日期作为创建日期。 +- 如果åˆçº¦æ˜¯ç”¨åŒ…å«å·²çŸ¥bug的编译器编译的,并且åˆçº¦æ˜¯åœ¨å·²å‘布包å«ä¿®å¤ç¨‹åºçš„较新编译器版本时创建的, + 则这是高度å¯ç–‘的。 -The JSON file of known bugs below is an array of objects, one for each bug, -with the following keys: +下é¢çš„已知错误的JSON文件是一个对象数组,æ¯ä¸ªé”™è¯¯éƒ½æœ‰ä¸€ä¸ªå¯¹è±¡ï¼Œå…¶é”®å€¼å¦‚下: uid - Unique identifier given to the bug in the form of ``SOL--``. - It is possible that multiple entries exists with the same uid. This means - multiple version ranges are affected by the same bug. + 以 ``SOL--`` çš„å½¢å¼ç»™äºˆè¯¥é”™è¯¯çš„唯一标识符。 + 有å¯èƒ½å­˜åœ¨å¤šä¸ªå…·æœ‰ç›¸åŒuidçš„æ¡ç›®ã€‚ + è¿™æ„味ç€å¤šä¸ªç‰ˆæœ¬èŒƒå›´å—到åŒä¸€é”™è¯¯çš„å½±å“。 name - Unique name given to the bug + 给予该错误的唯一å称 summary - Short description of the bug + 对该错误的简短æè¿° description - Detailed description of the bug + 该错误的详细æè¿° link - URL of a website with more detailed information, optional + 有更多详细信æ¯çš„网站的URL,å¯é€‰ introduced - The first published compiler version that contained the bug, optional + 第一个包å«è¯¥é”™è¯¯çš„å‘布的编译器版本,å¯é€‰ fixed - The first published compiler version that did not contain the bug anymore + 第一个ä¸å†åŒ…å«è¯¥é”™è¯¯çš„å‘布的编译器版本 publish - The date at which the bug became known publicly, optional + bug公开的日期,å¯é€‰ severity - Severity of the bug: very low, low, medium, high. Takes into account - discoverability in contract tests, likelihood of occurrence and - potential damage by exploits. + bug的严é‡ç¨‹åº¦ï¼šéžå¸¸ä½Žï¼Œä½Žï¼Œä¸­ï¼Œé«˜ã€‚ + 考虑åˆçº¦æµ‹è¯•ä¸­çš„å¯å‘现性,å‘生的å¯èƒ½æ€§å’Œé”™è¯¯é€ æˆçš„潜在æŸå®³ã€‚ conditions - Conditions that have to be met to trigger the bug. The following - keys can be used: - ``optimizer``, Boolean value which - means that the optimizer has to be switched on to enable the bug. - ``evmVersion``, a string that indicates which EVM version compiler - settings trigger the bug. The string can contain comparison - operators. For example, ``">=constantinople"`` means that the bug - is present when the EVM version is set to ``constantinople`` or - later. - If no conditions are given, assume that the bug is present. + 必须满足的æ¡ä»¶æ‰èƒ½è§¦å‘该错误。å¯ä»¥ä½¿ç”¨ä»¥ä¸‹é”®ï¼š + ``optimizer``, 布尔值,表示优化器必须打开æ‰ä¼šå‡ºçŽ°è¯¥é”™è¯¯ã€‚ + ``evmVersion``, 一个字符串,表示哪个EVM版本的编译器设置触å‘了该错误。 + 这个字符串å¯ä»¥åŒ…å«æ¯”较è¿ç®—符。例如, ``">=constantinople"`` 表示 + 当EVM版本设置为 ``constantinople`` 或更高时,该错误就会出现。 + 如果没有给出æ¡ä»¶ï¼Œåˆ™å‡å®šè¯¥é”™è¯¯å­˜åœ¨ã€‚ check - This field contains different checks that report whether the smart contract - contains the bug or not. The first type of check are JavaScript regular - expressions that are to be matched against the source code ("source-regex") - if the bug is present. If there is no match, then the bug is very likely - not present. If there is a match, the bug might be present. For improved - accuracy, the checks should be applied to the source code after stripping - comments. - The second type of check are patterns to be checked on the compact AST of - the Solidity program ("ast-compact-json-path"). The specified search query - is a `JsonPath `_ expression. - If at least one path of the Solidity AST matches the query, the bug is - likely present. + 这个字段包å«ä¸åŒçš„检查,报告智能åˆçº¦æ˜¯å¦åŒ…å«é”™è¯¯ã€‚ + 第一ç§ç±»åž‹çš„检查是JavaScript正则表达å¼ï¼Œå¦‚果存在该错误,将与æºä»£ç ï¼ˆâ€œsource-regexâ€ï¼‰è¿›è¡ŒåŒ¹é…。 + 如果没有匹é…,那么该æ¼æ´žå¾ˆå¯èƒ½ä¸å­˜åœ¨ã€‚如果有一个匹é…,则该错误å¯èƒ½å­˜åœ¨ã€‚ + 为了æ高准确性,检查应该在剥离注释åŽåº”用于æºä»£ç ã€‚ + 第二ç§ç±»åž‹çš„检查是在Solidity程åºçš„紧凑AST上检查的模å¼ï¼ˆâ€œast-compact-json pathâ€ï¼‰ã€‚ + 指定的æœç´¢æŸ¥è¯¢æ˜¯ä¸€ä¸ª `JsonPath `_ 表达å¼ã€‚ + 如果Solidity AST中至少有一个路径与该查询相匹é…,则å¯èƒ½å­˜åœ¨é”™è¯¯ã€‚ .. literalinclude:: bugs.json :language: js diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index d15c72a65424..676fe6c9665e 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1743,6 +1743,7 @@ }, "0.8.10": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1754,6 +1755,7 @@ }, "0.8.11": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1766,6 +1768,7 @@ }, "0.8.12": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1778,6 +1781,7 @@ }, "0.8.13": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "StorageWriteRemovalBeforeConditionalTermination", @@ -1791,6 +1795,7 @@ }, "0.8.14": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "StorageWriteRemovalBeforeConditionalTermination", @@ -1802,6 +1807,7 @@ }, "0.8.15": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "StorageWriteRemovalBeforeConditionalTermination", @@ -1811,6 +1817,7 @@ }, "0.8.16": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "StorageWriteRemovalBeforeConditionalTermination" @@ -1819,6 +1826,7 @@ }, "0.8.17": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" ], @@ -1826,6 +1834,7 @@ }, "0.8.18": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" ], @@ -1833,6 +1842,7 @@ }, "0.8.19": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" ], @@ -1854,15 +1864,32 @@ }, "0.8.20": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" ], "released": "2023-05-10" }, "0.8.21": { - "bugs": [], + "bugs": [ + "VerbatimInvalidDeduplication" + ], "released": "2023-07-19" }, + "0.8.22": { + "bugs": [ + "VerbatimInvalidDeduplication" + ], + "released": "2023-10-25" + }, + "0.8.23": { + "bugs": [], + "released": "2023-11-08" + }, + "0.8.24": { + "bugs": [], + "released": "2024-01-25" + }, "0.8.3": { "bugs": [ "FullInlinerNonExpressionSplitArgumentEvaluationOrder", @@ -1890,6 +1917,7 @@ }, "0.8.5": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1902,6 +1930,7 @@ }, "0.8.6": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1914,6 +1943,7 @@ }, "0.8.7": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1926,6 +1956,7 @@ }, "0.8.8": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1939,6 +1970,7 @@ }, "0.8.9": { "bugs": [ + "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1948,4 +1980,4 @@ ], "released": "2021-09-29" } -} \ No newline at end of file +} diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index a60d3b50f526..3eaca0508b55 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -1,63 +1,97 @@ ********** -Cheatsheet +速查表 ********** .. index:: operator;precedence -Order of Precedence of Operators +æ“ä½œç¬¦çš„ä¼˜å…ˆé¡ºåº ================================ .. include:: types/operator-precedence-table.rst .. index:: abi;decode, abi;encode, abi;encodePacked, abi;encodeWithSelector, abi;encodeCall, abi;encodeWithSignature -ABI Encoding and Decoding Functions -=================================== - -- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: :ref:`ABI `-decodes - the provided data. The types are given in parentheses as second argument. - Example: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))`` -- ``abi.encode(...) returns (bytes memory)``: :ref:`ABI `-encodes the given arguments -- ``abi.encodePacked(...) returns (bytes memory)``: Performs :ref:`packed encoding ` of - the given arguments. Note that this encoding can be ambiguous! -- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: :ref:`ABI `-encodes - the given arguments starting from the second and prepends the given four-byte selector -- ``abi.encodeCall(function functionPointer, (...)) returns (bytes memory)``: ABI-encodes a call to ``functionPointer`` with the arguments found in the - tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, (...))`` -- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent - to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`` +ABI ç¼–ç å’Œè§£ç å‡½æ•° +=================== + +- ``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 ` - 对给定的å‚数进行编ç ã€‚ +- ``abi.encodePacked(...) returns (bytes memory)``: 对给定的å‚数执行 :ref:`紧密打包 `。 + 请注æ„,这ç§ç¼–ç å¯èƒ½æ˜¯ä¸æ˜Žç¡®çš„! +- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: :ref:`ABI ` - 对给定å‚数进行编ç ï¼Œ + 并以给定的函数选择器作为起始的 4 字节数æ®ä¸€èµ·è¿”回 +- ``abi.encodeCall(function functionPointer, (...)) returns (bytes memory)``: 对 ``functionPointer`` 的调用进行ABIç¼–ç ï¼Œ + å‚数在元组中找到。执行全é¢çš„类型检查,确ä¿ç±»åž‹ä¸Žå‡½æ•°ç­¾å相符。结果等于 ``abi.encodeWithSelector(functionPointer.selector(..))``。 +- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: 等价于 + ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`` .. index:: bytes;concat, string;concat -Members of ``bytes`` and ``string`` +``bytes`` å’Œ ``string`` 类型的属性 ==================================== -- ``bytes.concat(...) returns (bytes memory)``: :ref:`Concatenates variable number of - arguments to one byte array` +- ``bytes.concat(...) returns (bytes memory)``: :ref:`å°†å¯å˜æ•°é‡çš„å‚数连接æˆä¸€ä¸ªå­—节数组 ` -- ``string.concat(...) returns (string memory)``: :ref:`Concatenates variable number of - arguments to one string array` +- ``string.concat(...) returns (string memory)``: :ref:`å°†å¯å˜æ•°é‡çš„å‚数连接æˆä¸€ä¸ªå­—符串数组 ` .. index:: address;balance, address;codehash, address;send, address;code, address;transfer -Members of ``address`` +``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,失败时会抛出错误 +======= - ``
.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, block, block;basefree, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp +.. index:: blockhash, blobhash, block, block;basefee, block;blobbasefee, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp .. index:: gasleft, msg;data, msg;sender, msg;sig, msg;value, tx;gasprice, tx;origin -Block and Transaction Properties -================================ - +区å—和交易属性 +==================== + +<<<<<<< HEAD +- ``blockhash(uint blockNumber) returns (bytes32)``: 给定区å—的哈希值 - åªå¯¹æœ€è¿‘çš„256个区å—有效 +- ``block.basefee`` (``uint``): 当å‰åŒºå—的基本费用 ( `EIP-3198 `_ å’Œ `EIP-1559 `_ ) +- ``block.chainid`` (``uint``): 当å‰é“¾çš„ID +- ``block.coinbase`` (``address payable``): 当å‰åŒºå—çŸ¿å·¥çš„åœ°å€ +- ``block.difficulty`` (``uint``): 当å‰åŒºå—的难度值( ``EVM < Paris`` )。对于其他EVM版本,它是 ``block.prevrandao`` 的一个废弃的别å,将在下一个é‡å¤§æ”¹å˜ç‰ˆæœ¬ä¸­è¢«åˆ é™¤ã€‚ +- ``block.gaslimit`` (``uint``): 当å‰åŒºå—çš„ gas ä¸Šé™ +- ``block.number`` (``uint``): 当å‰åŒºå—的区å—å· +- ``block.prevrandao`` (``uint``): 由信标链æ供的éšæœºæ•°ï¼ˆ ``EVM >= Paris`` ï¼‰ï¼ˆè§ `EIP-4399 `_ )。 +- ``block.timestamp`` (``uint``): 当å‰åŒºå—的时间戳,自Unix epoch以æ¥çš„秒数 +- ``gasleft() returns (uint256)``: 剩余gas +- ``msg.data`` (``bytes``): å®Œæ•´çš„è°ƒç”¨æ•°æ® +- ``msg.sender`` (``address``): 消æ¯å‘é€æ–¹ï¼ˆå½“å‰è°ƒç”¨ï¼‰ +- ``msg.sig`` (``bytes4``): Calldataçš„å‰å››ä¸ªå­—节(å³å‡½æ•°æ ‡è¯†ç¬¦ï¼‰ã€‚ +- ``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 @@ -72,60 +106,66 @@ Block and Transaction Properties - ``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 -Validations and Assertions -========================== +验è¯å’Œæ–­è¨€ +=========== -- ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error) -- ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use - for malformed input or error in external component) -- ``require(bool condition, string memory message)``: abort execution and revert state changes if - condition is ``false`` (use for malformed input or error in external component). Also provide error message. -- ``revert()``: abort execution and revert state changes -- ``revert(string memory message)``: abort execution and revert state changes providing an explanatory string +- ``assert(bool condition)``: 如果æ¡ä»¶ä¸º ``false``,则中止执行并æ¢å¤çŠ¶æ€å˜åŒ–(用于内部错误) +- ``require(bool condition)``: 如果æ¡ä»¶ä¸º ``false``,则中止执行并æ¢å¤çŠ¶æ€å˜åŒ–(用于错误的输入或外部组件的错误) +- ``require(bool condition, string memory message)``: 如果æ¡ä»¶ä¸º ``false``, + 则中止执行并æ¢å¤çŠ¶æ€å˜åŒ–(用于错误的输入或外部组件的错误)。åŒæ—¶æ供错误信æ¯ã€‚ +- ``revert()``: 中止执行并æ¢å¤çŠ¶æ€å˜åŒ– +- ``revert(string memory message)``: 中止执行并æ¢å¤çŠ¶æ€å˜åŒ–,æ供一个解释性的字符串 .. index:: cryptography, keccak256, sha256, ripemd160, ecrecover, addmod, mulmod -Mathematical and Cryptographic Functions -======================================== +数学和加密函数 +=============== -- ``keccak256(bytes memory) returns (bytes32)``: compute the Keccak-256 hash of the input -- ``sha256(bytes memory) returns (bytes32)``: compute the SHA-256 hash of the input -- ``ripemd160(bytes memory) returns (bytes20)``: compute the RIPEMD-160 hash of the input -- ``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``: recover address associated with - the public key from elliptic curve signature, return zero on error -- ``addmod(uint x, uint y, uint k) returns (uint)``: compute ``(x + y) % k`` where the addition is performed with - arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0. -- ``mulmod(uint x, uint y, uint k) returns (uint)``: compute ``(x * y) % k`` where the multiplication is performed - with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0. +- ``keccak256(bytes memory) returns (bytes32)``: 计算输入的Keccak-256哈希值 +- ``sha256(bytes memory) returns (bytes32)``: 计算输入的SHA-256哈希值 +- ``ripemd160(bytes memory) returns (bytes20)``: 计算输入的RIPEMD-160的哈希值 +- ``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``: 从椭圆曲线签å中æ¢å¤ä¸Žå…¬é’¥ç›¸å…³çš„地å€ï¼Œ + 错误时返回0 +- ``addmod(uint x, uint y, uint k) returns (uint)``: 计算 ``(x + y) % k`` 的值, + 其中加法的结果å³ä½¿è¶…过 ``2**256`` 也ä¸ä¼šè¢«æˆªå–。从 0.5.0 版本开始会加入对 ``k != 0`` çš„ assert(å³ä¼šåœ¨æ­¤å‡½æ•°å¼€å¤´æ‰§è¡Œ ``assert(k != 0);`` 作为å‚数检查,译者注)。 +- ``mulmod(uint x, uint y, uint k) returns (uint)``: 计算 ``(x * y) % k`` 的值, + 其中乘法的结果å³ä½¿è¶…过 ``2**256`` 也ä¸ä¼šè¢«æˆªå–。从 0.5.0 版本开始会加入对 ``k != 0`` çš„ assert(å³ä¼šåœ¨æ­¤å‡½æ•°å¼€å¤´æ‰§è¡Œ ``assert(k != 0);`` 作为å‚数检查,译者注)。 .. index:: this, super, selfdestruct -Contract-related +åˆçº¦ç›¸å…³å‡½æ•° ================ +<<<<<<< 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)``: destroy the current contract, sending its funds to the given address +- ``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 -Type Information +类型属性 ================ -- ``type(C).name`` (``string``): the name of the contract -- ``type(C).creationCode`` (``bytes memory``): creation bytecode of the given contract, see :ref:`Type Information`. -- ``type(C).runtimeCode`` (``bytes memory``): runtime bytecode of the given contract, see :ref:`Type Information`. -- ``type(I).interfaceId`` (``bytes4``): value containing the EIP-165 interface identifier of the given interface, see :ref:`Type Information`. -- ``type(T).min`` (``T``): the minimum value representable by the integer type ``T``, see :ref:`Type Information`. -- ``type(T).max`` (``T``): the maximum value representable by the integer type ``T``, see :ref:`Type Information`. +- ``type(C).name`` (``string``): åˆçº¦çš„å称 +- ``type(C).creationCode`` (``bytes memory``): 给定åˆçº¦çš„创建字节ç ï¼Œå‚è§ :ref:`ç±»åž‹ä¿¡æ¯ `。 +- ``type(C).runtimeCode`` (``bytes memory``): 给定åˆçº¦çš„è¿è¡Œæ—¶å­—节ç ï¼Œå‚è§ :ref:`ç±»åž‹ä¿¡æ¯ `。 +- ``type(I).interfaceId`` (``bytes4``): 包å«ç»™å®šæŽ¥å£çš„EIP-165接å£æ ‡è¯†ç¬¦çš„值,å‚è§ :ref:`ç±»åž‹ä¿¡æ¯ `。 +- ``type(T).min`` (``T``): 整数类型 ``T`` 所能代表的最å°å€¼ï¼Œå‚è§ :ref:`ç±»åž‹ä¿¡æ¯ `。 +- ``type(T).max`` (``T``): 整数类型 ``T`` 所能代表的最大值,å‚è§ :ref:`ç±»åž‹ä¿¡æ¯ `。 .. index:: visibility, public, private, external, internal -Function Visibility Specifiers +函数å¯è§æ€§è¯´æ˜Žç¬¦ ============================== .. code-block:: solidity @@ -135,21 +175,32 @@ Function Visibility Specifiers return true; } -- ``public``: visible externally and internally (creates a :ref:`getter function` for storage/state variables) -- ``private``: only visible in the current contract -- ``external``: only visible externally (only for functions) - i.e. can only be message-called (via ``this.func``) -- ``internal``: only visible internally +- ``public``: 内部ã€å¤–部å‡å¯è§ï¼ˆå‚考为存储/状æ€å˜é‡åˆ›å»º :ref:`getter function` 函数) +- ``private``: 仅在当å‰åˆçº¦å†…å¯è§ +- ``external``: 仅在外部å¯è§ï¼ˆä»…å¯ä¿®é¥°å‡½æ•°ï¼‰â€”—就是说,仅å¯ç”¨äºŽæ¶ˆæ¯è°ƒç”¨ï¼ˆå³ä½¿åœ¨åˆçº¦å†…调用,也åªèƒ½é€šè¿‡ ``this.func`` çš„æ–¹å¼ï¼‰ +- ``internal``: 仅在内部å¯è§ï¼ˆä¹Ÿå°±æ˜¯åœ¨å½“å‰ Solidity æºä»£ç æ–‡ä»¶å†…å‡å¯è§ï¼Œä¸ä»…é™äºŽå½“å‰åˆçº¦å†…,译者注) .. index:: modifiers, pure, view, payable, constant, anonymous, indexed -Modifiers +修改器 ========= +<<<<<<< HEAD +- ``pure`` 修饰函数时:ä¸å…许修改或访问状æ€ã€‚ +- ``view`` 修饰函数时:ä¸å…许修改状æ€ã€‚ +- ``payable`` 修饰函数时:å…许从调用中接收以太å¸ã€‚ +- ``constant`` 修饰状æ€å˜é‡æ—¶ï¼šä¸å…许赋值(除åˆå§‹åŒ–以外),ä¸ä¼šå æ® 存储æ’槽(storage slot)。 +- ``immutable`` 修饰状æ€å˜é‡æ—¶ï¼šåœ¨æž„造时å…许有一个确切的赋值,之åŽæ˜¯æ’定的。被存储在代ç ä¸­ã€‚ +- ``anonymous`` 修饰事件时:ä¸æŠŠäº‹ä»¶ç­¾å作为 topic 存储。 +- ``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 initialisation), does not occupy storage slot. +- ``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. @@ -157,4 +208,5 @@ Modifiers 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 cbc219b53b5a..2aabed6ad232 100644 --- a/docs/common-patterns.rst +++ b/docs/common-patterns.rst @@ -1,5 +1,5 @@ ############### -Common Patterns +é€šç”¨æ¨¡å¼ ############### .. index:: withdrawal @@ -7,23 +7,25 @@ Common Patterns .. _withdrawal_pattern: ************************* -Withdrawal from Contracts +从åˆçº¦ä¸­æ款 ************************* -The recommended method of sending funds after an effect -is using the withdrawal pattern. Although the most intuitive -method of sending Ether, as a result of an effect, is a -direct ``transfer`` call, this is not recommended as it -introduces a potential security risk. You may read -more about this on the :ref:`security_considerations` page. +在æŸä¸ªæ“作之åŽå‘é€èµ„金的推èæ–¹å¼æ˜¯ä½¿ç”¨å–回(withdrawal)模å¼ã€‚ +尽管在æŸä¸ªæ“作之åŽï¼Œæœ€ç›´æŽ¥åœ°å‘é€ä»¥å¤ªå¸æ–¹æ³•æ˜¯ä¸€ä¸ª ``transfer`` 调用, +但这并ä¸æŽ¨è,因为这会引入一个潜在的安全风险。 +您å¯èƒ½éœ€è¦å‚考 :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 -In the following contract, if you are no longer the richest, -you receive the funds of the person who is now the richest. +在下é¢çš„åˆçº¦ä¸­ï¼Œå¦‚果您ä¸å†æ˜¯æœ€å¯Œæœ‰çš„人,您将收到å–代您æˆä¸ºâ€œæœ€å¯Œæœ‰â€çš„人å‘é€åˆ°åˆçº¦çš„资金。 .. code-block:: solidity @@ -36,8 +38,7 @@ you receive the funds of the person who is now the richest. mapping(address => uint) pendingWithdrawals; - /// The amount of Ether sent was not higher than - /// the currently highest amount. + /// å‘é€çš„以太数é‡ä¸é«˜äºŽç›®å‰çš„最高é‡ã€‚ error NotEnoughEther(); constructor() payable { @@ -54,14 +55,14 @@ you receive the funds of the person who is now the richest. function withdraw() public { uint amount = pendingWithdrawals[msg.sender]; - // Remember to zero the pending refund before - // sending to prevent reentrancy attacks + // 记得在å‘é€å‰å°†å¾…处ç†çš„退款归零, + // 以防止é‡å…¥æ”»å‡» pendingWithdrawals[msg.sender] = 0; payable(msg.sender).transfer(amount); } } -This is as opposed to the more intuitive sending pattern: +下é¢æ˜¯ä¸€ä¸ªç›¸å的直接使用å‘é€æ¨¡å¼çš„例å­ï¼š .. code-block:: solidity @@ -72,8 +73,7 @@ This is as opposed to the more intuitive sending pattern: address payable public richest; uint public mostSent; - /// The amount of Ether sent was not higher than - /// the currently highest amount. + /// å‘é€çš„以太数é‡ä¸é«˜äºŽç›®å‰çš„最高é‡ã€‚ error NotEnoughEther(); constructor() payable { @@ -83,51 +83,41 @@ This is as opposed to the more intuitive sending pattern: function becomeRichest() public payable { if (msg.value <= mostSent) revert NotEnoughEther(); - // This line can cause problems (explained below). + // 这一行会导致问题(详è§ä¸‹æ–‡ï¼‰ richest.transfer(msg.value); richest = payable(msg.sender); mostSent = msg.value; } } -Notice that, in this example, an attacker could trap the -contract into an unusable state by causing ``richest`` to be -the address of a contract that has a receive or fallback function -which fails (e.g. by using ``revert()`` or by just -consuming more than the 2300 gas stipend transferred to them). That way, -whenever ``transfer`` is called to deliver funds to the -"poisoned" contract, it will fail and thus also ``becomeRichest`` -will fail, with the contract being stuck forever. +请注æ„,在这个例å­ä¸­ï¼Œæ”»å‡»è€…å¯ä»¥é€šè¿‡ä½¿ ``richest`` æˆä¸ºä¸€ä¸ªæœ‰ receive 或 fallback 函数的åˆçº¦çš„åœ°å€ +而使åˆçº¦é™·å…¥æ— æ³•ä½¿ç”¨çš„状æ€ï¼ˆä¾‹å¦‚,通过使用 ``revert()`` 或åªæ˜¯æ¶ˆè€—超过转给他们的2300 gas 津贴)。 +这样,æ¯å½“调用 ``transfer`` å‘ â€œä¸­æ¯’â€ çš„åˆçº¦äº¤ä»˜èµ„金时,它就会失败, +å› æ­¤ ``becomeRichest`` 也会失败,åˆçº¦ä¼šæ°¸è¿œè¢«å¡ä½ã€‚ -In contrast, if you use the "withdraw" pattern from the first example, -the attacker can only cause his or her own withdraw to fail and not the -rest of the contract's workings. +相å,如果您使用第一个例å­ä¸­çš„ “å–回(withdraw)â€æ¨¡å¼ï¼Œ +那么攻击者åªèƒ½ä½¿ä»–/她自己的“å–回â€å¤±è´¥ï¼Œå¹¶ä¸ä¼šå¯¼è‡´æ•´ä¸ªåˆçº¦æ— æ³•è¿ä½œã€‚ .. index:: access;restricting ****************** -Restricting Access +é™åˆ¶è®¿é—® ****************** -Restricting access is a common pattern for contracts. -Note that you can never restrict any human or computer -from reading the content of your transactions or -your contract's state. You can make it a bit harder -by using encryption, but if your contract is supposed -to read the data, so will everyone else. +é™åˆ¶è®¿é—®æ˜¯åˆçº¦çš„一个常è§æ¨¡å¼ã€‚ +请注æ„,您永远无法é™åˆ¶ä»»ä½•äººç±»æˆ–机器阅读您的交易内容或您的åˆçº¦çŠ¶æ€ã€‚ +您å¯ä»¥é€šè¿‡ä½¿ç”¨åŠ å¯†æ¥å¢žåŠ ä¸€ç‚¹éš¾åº¦ï¼Œ +但如果您想让您的åˆçº¦è¯»å–这些数æ®ï¼Œé‚£ä¹ˆå…¶ä»–人也将å¯ä»¥åšåˆ°ã€‚ -You can restrict read access to your contract's state -by **other contracts**. That is actually the default -unless you declare your state variables ``public``. +您å¯ä»¥é™åˆ¶ **其他åˆçº¦** 对您的åˆçº¦çŠ¶æ€çš„读å–æƒé™ã€‚ +这实际上是默认的,除éžæ‚¨å£°æ˜Žæ‚¨çš„状æ€å˜é‡ä¸º ``public``。 -Furthermore, you can restrict who can make modifications -to your contract's state or call your contract's -functions and this is what this section is about. +此外,您å¯ä»¥é™åˆ¶è°å¯ä»¥å¯¹æ‚¨çš„åˆçº¦çš„状æ€è¿›è¡Œä¿®æ”¹æˆ–调用您的åˆçº¦çš„功能, +这就是本节的内容。 .. index:: function;modifier -The use of **function modifiers** makes these -restrictions highly readable. +使用 **函数修饰符** 使这些é™åˆ¶å˜å¾—éžå¸¸æ˜Žç¡®ã€‚ .. code-block:: solidity :force: @@ -136,45 +126,41 @@ restrictions highly readable. pragma solidity ^0.8.4; contract AccessRestriction { - // These will be assigned at the construction - // phase, where `msg.sender` is the account - // creating this contract. + // 这些将在构造阶段被赋值 + // 其中,`msg.sender` 是 + // 创建这个åˆçº¦çš„账户。 address public owner = msg.sender; uint public creationTime = block.timestamp; - // Now follows a list of errors that - // this contract can generate together - // with a textual explanation in special - // comments. + // 现在列出了该åˆçº¦å¯èƒ½äº§ç”Ÿçš„错误, + // 并在特别注释中作了文字解释。 - /// Sender not authorized for this - /// operation. + /// 调用者未被授æƒè¿›è¡Œæ­¤æ“作。 error Unauthorized(); - /// Function called too early. + /// 函数调用过早。 error TooEarly(); - /// Not enough Ether sent with function call. + /// 函数调用时没有å‘é€è¶³å¤Ÿçš„以太。 error NotEnoughEther(); - // Modifiers can be used to change - // the body of a function. - // If this modifier is used, it will - // prepend a check that only passes - // if the function is called from - // a certain address. + // 修饰器å¯ä»¥ç”¨æ¥æ›´æ”¹ + // 一个函数的函数体。 + // 如果使用这个修饰器, + // 它会预置一个检查,仅å…许 + // æ¥è‡ªç‰¹å®šåœ°å€çš„ + // 函数调用。 modifier onlyBy(address account) { if (msg.sender != account) revert Unauthorized(); - // Do not forget the "_;"! It will - // be replaced by the actual function - // body when the modifier is used. + // ä¸è¦å¿˜è®°å†™ “_;â€ï¼ + // 它会被实际使用这个修饰器的 + // 函数体所替代。 _; } - /// Make `newOwner` the new owner of this - /// contract. + /// 使 `newOwner` æˆä¸ºè¿™ä¸ªåˆçº¦çš„新所有者。 function changeOwner(address newOwner) public onlyBy(owner) @@ -188,9 +174,9 @@ restrictions highly readable. _; } - /// Erase ownership information. - /// May only be called 6 weeks after - /// the contract has been created. + /// 抹掉所有者信æ¯ã€‚ + /// ä»…å…许在åˆçº¦åˆ›å»ºæˆåŠŸ 6 å‘¨ä»¥åŽ + /// 的时间被调用。 function disown() public onlyBy(owner) @@ -199,12 +185,12 @@ restrictions highly readable. delete owner; } - // This modifier requires a certain - // fee being associated with a function call. - // If the caller sent too much, he or she is - // refunded, but only after the function body. - // This was dangerous before Solidity version 0.4.0, - // where it was possible to skip the part after `_;`. + // 这个修饰器è¦æ±‚对函数调用 + // 绑定一定的费用。 + // 如果调用方å‘é€äº†è¿‡å¤šçš„费用, + // ä»–/她会得到退款,但需è¦å…ˆæ‰§è¡Œå‡½æ•°ä½“。 + // 这在 0.4.0 版本以å‰çš„ Solidity 中很å±é™©ï¼Œ + // 因为很å¯èƒ½ä¼šè·³è¿‡ `_;` 之åŽçš„代ç ã€‚ modifier costs(uint amount) { if (msg.value < amount) revert NotEnoughEther(); @@ -220,78 +206,61 @@ restrictions highly readable. costs(200 ether) { owner = newOwner; - // just some example condition + // è¿™åªæ˜¯ç¤ºä¾‹æ¡ä»¶ if (uint160(owner) & 0 == 1) - // This did not refund for Solidity - // before version 0.4.0. + // 这无法在 0.4.0 版本之å‰çš„ + // Solidity 上进行退还。 return; - // refund overpaid fees + // 退还多付的费用 } } -A more specialised way in which access to function -calls can be restricted will be discussed -in the next example. +在下一个例å­ä¸­ï¼Œå°†è®¨è®ºä¸€ç§æ›´ä¸“业的é™åˆ¶å‡½æ•°è°ƒç”¨è®¿é—®çš„æ–¹å¼ã€‚ .. index:: state machine ************* -State Machine +状æ€æœº ************* -Contracts often act as a state machine, which means -that they have certain **stages** in which they behave -differently or in which different functions can -be called. A function call often ends a stage -and transitions the contract into the next stage -(especially if the contract models **interaction**). -It is also common that some stages are automatically -reached at a certain point in **time**. +åˆçº¦é€šå¸¸ä¼šåƒçŠ¶æ€æœºé‚£æ ·è¿ä½œï¼Œè¿™æ„味ç€å®ƒä»¬æœ‰ç‰¹å®šçš„ **阶段**, +使它们有ä¸åŒçš„表现或者仅å…许特定的ä¸åŒå‡½æ•°è¢«è°ƒç”¨ã€‚ +一个函数调用通常会结æŸä¸€ä¸ªé˜¶æ®µï¼Œ +并将åˆçº¦è½¬æ¢åˆ°ä¸‹ä¸€ä¸ªé˜¶æ®µï¼ˆç‰¹åˆ«æ˜¯å¦‚果一个åˆçº¦æ˜¯ä»¥ **交互** æ¥å»ºæ¨¡çš„时候)。 +通过达到特定的 **时间** 点æ¥è¾¾åˆ°æŸäº›é˜¶æ®µä¹Ÿæ˜¯å¾ˆå¸¸è§çš„。 -An example for this is a blind auction contract which -starts in the stage "accepting blinded bids", then -transitions to "revealing bids" which is ended by -"determine auction outcome". +一个典型的例å­æ˜¯ç›²æ‹ï¼ˆblind auction)åˆçº¦ï¼Œ +它起始于“接å—盲目出价â€ï¼Œ +然åŽè½¬æ¢åˆ°â€œå…¬ç¤ºå‡ºä»·â€ï¼Œ +最åŽç»“æŸäºŽâ€œç¡®å®šæ‹å–结果â€ã€‚ .. index:: function;modifier -Function modifiers can be used in this situation -to model the states and guard against -incorrect usage of the contract. +函数修饰器å¯ä»¥ç”¨åœ¨è¿™ç§æƒ…况下æ¥å¯¹çŠ¶æ€è¿›è¡Œå»ºæ¨¡ï¼Œ +并确ä¿åˆçº¦è¢«æ­£å¸¸çš„使用。 -Example +示例 ======= -In the following example, -the modifier ``atStage`` ensures that the function can -only be called at a certain stage. +在下边的示例中, 修饰器 ``atStage`` ç¡®ä¿äº†å‡½æ•°ä»…在特定的阶段æ‰å¯ä»¥è¢«è°ƒç”¨ã€‚ -Automatic timed transitions -are handled by the modifier ``timedTransitions``, which -should be used for all functions. +自动定时过渡是由修饰器 ``timedTransitions`` 处ç†çš„,它应该用于所有函数。 .. note:: - **Modifier Order Matters**. - If atStage is combined - with timedTransitions, make sure that you mention - it after the latter, so that the new stage is - taken into account. + **修饰器的顺åºéžå¸¸é‡è¦**. + 如果 atStage å’Œ timedTransitions è¦ä¸€èµ·ä½¿ç”¨ï¼Œ + 请确ä¿åœ¨ timedTransitions 之åŽå£°æ˜Ž atStage, + 以便新的状æ€å¯ä»¥ 首先被å映到账户中。 -Finally, the modifier ``transitionNext`` can be used -to automatically go to the next stage when the -function finishes. +最åŽï¼Œ 修饰器 ``transitionNext`` 能够用æ¥åœ¨å‡½æ•°æ‰§è¡Œç»“æŸæ—¶è‡ªåŠ¨è½¬æ¢åˆ°ä¸‹ä¸€ä¸ªé˜¶æ®µã€‚ .. note:: - **Modifier May be Skipped**. - This only applies to Solidity before version 0.4.0: - Since modifiers are applied by simply replacing - code and not by using a function call, - the code in the transitionNext modifier - can be skipped if the function itself uses - return. If you want to do that, make sure - to call nextStage manually from those functions. - Starting with version 0.4.0, modifier code - will run even if the function explicitly returns. + **修饰器å¯ä»¥è¢«å¿½ç•¥**. + è¿™åªé€‚用于0.4.0版本之å‰çš„Solidity: + 由于修饰器是通过简å•åœ°æ›¿æ¢ä»£ç è€Œä¸æ˜¯ä½¿ç”¨å‡½æ•°è°ƒç”¨æ¥åº”用的, + 如果函数本身使用 return,å¯ä»¥è·³è¿‡ transitionNext 修饰器中的代ç ã€‚ + 如果您想这样åšï¼Œè¯·ç¡®ä¿ä»Žè¿™äº›å‡½æ•°ä¸­æ‰‹åŠ¨è°ƒç”¨ nextStage。 + 从0.4.0版本开始,å³ä½¿å‡½æ•°æ˜Žç¡®è¿”回,修饰器代ç ä¹Ÿä¼šè¿è¡Œã€‚ .. code-block:: solidity :force: @@ -307,10 +276,10 @@ function finishes. AreWeDoneYet, Finished } - /// Function cannot be called at this time. + /// 此阶段ä¸èƒ½è°ƒç”¨è¯¥å‡½æ•°ã€‚ error FunctionInvalidAtThisStage(); - // This is the current stage. + // 这是当å‰é˜¶æ®µã€‚ Stages public stage = Stages.AcceptingBlindedBids; uint public creationTime = block.timestamp; @@ -325,9 +294,9 @@ function finishes. stage = Stages(uint(stage) + 1); } - // Perform timed transitions. Be sure to mention - // this modifier first, otherwise the guards - // will not take the new stage into account. + // 执行基于时间的阶段转æ¢ã€‚ + // 请确ä¿é¦–先声明这个修饰器, + // å¦åˆ™æ–°é˜¶æ®µä¸ä¼šè¢«å¸¦å…¥è´¦æˆ·ã€‚ modifier timedTransitions() { if (stage == Stages.AcceptingBlindedBids && block.timestamp >= creationTime + 10 days) @@ -335,18 +304,18 @@ function finishes. if (stage == Stages.RevealBids && block.timestamp >= creationTime + 12 days) nextStage(); - // The other stages transition by transaction + // 由交易触å‘çš„å…¶ä»–é˜¶æ®µè½¬æ¢ _; } - // Order of the modifiers matters here! + // 这里的修饰器顺åºéžå¸¸é‡è¦ï¼ function bid() public payable timedTransitions atStage(Stages.AcceptingBlindedBids) { - // We will not implement that here + // 我们ä¸ä¼šåœ¨è¿™é‡Œå®žçŽ°å®žé™…功能(因为这仅是个代ç ç¤ºä¾‹ï¼Œè¯‘者注) } function reveal() @@ -356,8 +325,8 @@ function finishes. { } - // This modifier goes to the next stage - // after the function is done. + // 这个修饰器在函数执行结æŸä¹‹åŽ + // 使åˆçº¦è¿›å…¥ä¸‹ä¸€ä¸ªé˜¶æ®µã€‚ modifier transitionNext() { _; diff --git a/docs/conf.py b/docs/conf.py index ddc3ee81bbdc..5f096a97eab6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -85,7 +85,7 @@ def setup(sphinx): # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +language = "zh_CN" # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: diff --git a/docs/contracts.rst b/docs/contracts.rst index aee26c95afd8..e40856c8cc01 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -3,16 +3,15 @@ .. _contracts: ########## -Contracts +åˆçº¦ ########## -Contracts in Solidity are similar to classes in object-oriented languages. They -contain persistent data in state variables, and functions that can modify these -variables. Calling a function on a different contract (instance) will perform -an EVM function call and thus switch the context such that state variables -in the calling contract are -inaccessible. A contract and its functions need to be called for anything to happen. -There is no "cron" concept in Ethereum to call a function at a particular event automatically. +Solidity中的åˆçº¦ç±»ä¼¼äºŽé¢å‘对象语言中的类。 +它们在状æ€å˜é‡ä¸­åŒ…å«æŒä¹…çš„æ•°æ®ï¼Œä»¥åŠå¯ä»¥ä¿®æ”¹è¿™äº›å˜é‡çš„函数。 +在ä¸åŒçš„åˆçº¦ï¼ˆå®žä¾‹ï¼‰ä¸Šè°ƒç”¨ä¸€ä¸ªå‡½æ•°å°†æ‰§è¡Œä¸€ä¸ªEVM函数调用, +从而切æ¢ä¸Šä¸‹æ–‡ï¼Œä½¿è°ƒç”¨åˆçº¦ä¸­çš„状æ€å˜é‡æ— æ³•è®¿é—®ã€‚ +一个åˆçº¦å’Œå®ƒçš„函数需è¦è¢«è°ƒç”¨æ‰ä¼šå‘生。 +在以太åŠä¸­æ²¡æœ‰ "cron" 的概念,在特定的事件中自动调用一个函数。 .. include:: contracts/creating-contracts.rst @@ -33,4 +32,4 @@ There is no "cron" concept in Ethereum to call a function at a particular event .. include:: contracts/libraries.rst -.. include:: contracts/using-for.rst \ No newline at end of file +.. include:: contracts/using-for.rst diff --git a/docs/contracts/abstract-contracts.rst b/docs/contracts/abstract-contracts.rst index fb1beb2dab5f..13b42265f054 100644 --- a/docs/contracts/abstract-contracts.rst +++ b/docs/contracts/abstract-contracts.rst @@ -3,18 +3,19 @@ .. _abstract-contract: ****************** -Abstract Contracts +抽象åˆçº¦ ****************** -Contracts must be marked as abstract when at least one of their functions is not implemented or when -they do not provide arguments for all of their base contract constructors. -Even if this is not the case, a contract may still be marked abstract, such as when you do not intend -for the contract to be created directly. Abstract contracts are similar to :ref:`interfaces` but an -interface is more limited in what it can declare. +当åˆçº¦ä¸­è‡³å°‘有一个函数没有被实现,或者åˆçº¦æ²¡æœ‰ä¸ºå…¶æ‰€æœ‰çš„基本åˆçº¦æž„造函数æä¾›å‚数时, +åˆçº¦å¿…须被标记为 abstract。 +å³ä½¿ä¸æ˜¯è¿™ç§æƒ…况,åˆçº¦ä»ç„¶å¯ä»¥è¢«æ ‡è®°ä¸º abstract, +例如,当您ä¸æ‰“算直接创建åˆçº¦æ—¶ã€‚ +抽象(abstract)åˆçº¦ç±»ä¼¼äºŽ :ref:`interfaces`, +但是接å£ï¼ˆinterface)åˆçº¦å¯ä»¥å£°æ˜Žçš„内容更加有é™ã€‚ -An abstract contract is declared using the ``abstract`` keyword as shown in the following example. -Note that this contract needs to be defined as abstract, because the function ``utterance()`` is declared, -but no implementation was provided (no implementation body ``{ }`` was given). +如下例所示,使用 ``abstract`` 关键字æ¥å£°æ˜Žä¸€ä¸ªæŠ½è±¡åˆçº¦ã€‚ +注æ„,这个åˆçº¦éœ€è¦è¢«å®šä¹‰ä¸º abstract,因为函数 ``utterance()`` 被声明了, +但没有æ供实现(没有给出实现体 ``{ }``)。 .. code-block:: solidity @@ -25,8 +26,8 @@ but no implementation was provided (no implementation body ``{ }`` was given). function utterance() public virtual returns (bytes32); } -Such abstract contracts can not be instantiated directly. This is also true, if an abstract contract itself does implement -all defined functions. The usage of an abstract contract as a base class is shown in the following example: +这样的抽象åˆçº¦ä¸èƒ½è¢«ç›´æŽ¥å®žä¾‹åŒ–。如果一个抽象åˆçº¦æœ¬èº«å®žçŽ°äº†æ‰€æœ‰å®šä¹‰çš„功能,这也是å¯ä»¥çš„。 +抽象åˆçº¦ä½œä¸ºåŸºç±»çš„用法在下é¢çš„例å­ä¸­æ˜¾ç¤ºï¼š .. code-block:: solidity @@ -41,32 +42,28 @@ all defined functions. The usage of an abstract contract as a base class is show function utterance() public pure override returns (bytes32) { return "miaow"; } } -If a contract inherits from an abstract contract and does not implement all non-implemented -functions by overriding, it needs to be marked as abstract as well. +如果一个åˆçº¦ç»§æ‰¿è‡ªä¸€ä¸ªæŠ½è±¡åˆçº¦ï¼Œå¹¶ä¸”没有通过é‡å†™å®žçŽ°æ‰€æœ‰æœªå®žçŽ°çš„函数,那么它也需è¦è¢«æ ‡è®°ä¸ºæŠ½è±¡çš„。 -Note that a function without implementation is different from -a :ref:`Function Type ` even though their syntax looks very similar. +注æ„,没有实现的函数与 :ref:`函数类型 ` ä¸åŒï¼Œå°½ç®¡å®ƒä»¬çš„语法看起æ¥éžå¸¸ç›¸ä¼¼ã€‚ -Example of function without implementation (a function declaration): +没有实现内容的函数的例å­ï¼ˆä¸€ä¸ªå‡½æ•°å£°æ˜Žï¼‰ï¼š .. code-block:: solidity function foo(address) external returns (address); -Example of a declaration of a variable whose type is a function type: +类型为函数类型的å˜é‡çš„声明实例: .. code-block:: solidity function(address) external returns (address) foo; -Abstract contracts decouple the definition of a contract from its -implementation providing better extensibility and self-documentation and -facilitating patterns like the `Template method `_ and removing code duplication. -Abstract contracts are useful in the same way that defining methods -in an interface is useful. It is a way for the designer of the -abstract contract to say "any child of mine must implement this method". +抽象åˆçº¦å°†åˆçº¦çš„定义与它的实现解耦,æ供了更好的å¯æ‰©å±•æ€§å’Œè‡ªæˆ‘记录, +ä¿ƒè¿›äº†åƒ `模æ¿æ–¹æ³• `_ 这样的模å¼ï¼Œ +并消除了代ç çš„é‡å¤ã€‚抽象åˆçº¦çš„作用与在接å£ä¸­å®šä¹‰æ–¹æ³•çš„作用相åŒã€‚ +它是抽象åˆçº¦çš„设计者说 "我的任何孩å­éƒ½å¿…须实现这个方法" 的一ç§æ–¹å¼ã€‚ + .. note:: - Abstract contracts cannot override an implemented virtual function with an - unimplemented one. + 抽象åˆçº¦ä¸èƒ½ç”¨ä¸€ä¸ªæœªå®žçŽ°çš„virtual函数æ¥é‡è½½ä¸€ä¸ªå·²å®žçŽ°çš„virtual函数。 diff --git a/docs/contracts/constant-state-variables.rst b/docs/contracts/constant-state-variables.rst index a1bc24f50c64..dfbd2388c4c4 100644 --- a/docs/contracts/constant-state-variables.rst +++ b/docs/contracts/constant-state-variables.rst @@ -3,29 +3,25 @@ .. _constants: ************************************** -Constant and Immutable State Variables +Constant å’Œ Immutable 状æ€å˜é‡ ************************************** -State variables can be declared as ``constant`` or ``immutable``. -In both cases, the variables cannot be modified after the contract has been constructed. -For ``constant`` variables, the value has to be fixed at compile-time, while -for ``immutable``, it can still be assigned at construction time. +状æ€å˜é‡å¯ä»¥è¢«å£°æ˜Žä¸º ``constant`` 或 ``immutable``。 +在这两ç§æƒ…况下,å˜é‡åœ¨åˆçº¦æž„建完æˆåŽä¸èƒ½è¢«ä¿®æ”¹ã€‚ +对于 ``constant`` å˜é‡ï¼Œå…¶å€¼å¿…须在编译时固定, +而对于 ``immutable`` å˜é‡ï¼Œä»ç„¶å¯ä»¥åœ¨æž„造时分é…。 -It is also possible to define ``constant`` variables at the file level. +也å¯ä»¥åœ¨æ–‡ä»¶çº§åˆ«å®šä¹‰ ``constant`` å˜é‡ã€‚ -The compiler does not reserve a storage slot for these variables, and every occurrence is -replaced by the respective value. +编译器并没有为这些å˜é‡é¢„留存储,它们的æ¯æ¬¡å‡ºçŽ°éƒ½ä¼šè¢«æ›¿æ¢ä¸ºç›¸åº”的常é‡è¡¨è¾¾å¼ã€‚ -Compared to regular state variables, the gas costs of constant and immutable variables -are much lower. For a constant variable, the expression assigned to it is copied to -all the places where it is accessed and also re-evaluated each time. This allows for local -optimizations. Immutable variables are evaluated once at construction time and their value -is copied to all the places in the code where they are accessed. For these values, -32 bytes are reserved, even if they would fit in fewer bytes. Due to this, constant values -can sometimes be cheaper than immutable values. +与普通的状æ€å˜é‡ç›¸æ¯”,常é‡å˜é‡ï¼ˆconstant)和ä¸å¯æ”¹å˜çš„å˜é‡ï¼ˆimmutable)的气体æˆæœ¬è¦ä½Žå¾—多。 +对于常é‡å˜é‡ï¼Œåˆ†é…给它的表达å¼è¢«å¤åˆ¶åˆ°æ‰€æœ‰è®¿é—®å®ƒçš„地方,并且æ¯æ¬¡éƒ½è¦é‡æ–°è¯„估, +这使得局部优化æˆä¸ºå¯èƒ½ã€‚ä¸å¯å˜çš„å˜é‡åœ¨æž„造时被评估一次,其值被å¤åˆ¶åˆ°ä»£ç ä¸­æ‰€æœ‰è¢«è®¿é—®çš„地方。 +对于这些值,è¦ä¿ç•™32个字节,å³ä½¿å®ƒä»¬å¯ä»¥è£…入更少的字节。由于这个原因,常é‡å€¼æœ‰æ—¶ä¼šæ¯”ä¸å¯å˜çš„值更便宜。 -Not all types for constants and immutables are implemented at this time. The only supported types are -:ref:`strings ` (only for constants) and :ref:`value types `. +ç›®å‰ï¼Œå¹¶éžæ‰€æœ‰çš„常é‡å’Œä¸å¯å˜é‡çš„类型都已实现。 +唯一支æŒçš„类型是 :ref:`字符串类型 ` (仅用于常é‡ï¼‰å’Œ :ref:`值类型 `。 .. code-block:: solidity @@ -42,12 +38,17 @@ Not all types for constants and immutables are implemented at this time. The onl 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; } @@ -60,23 +61,36 @@ Not all types for constants and immutables are implemented at this time. The onl Constant ======== -For ``constant`` variables, the value has to be a constant at compile time and it has to be -assigned where the variable is declared. Any expression -that accesses storage, blockchain data (e.g. ``block.timestamp``, ``address(this).balance`` or -``block.number``) or -execution data (``msg.value`` or ``gasleft()``) or makes calls to external contracts is disallowed. Expressions -that might have a side-effect on memory allocation are allowed, but those that -might have a side-effect on other memory objects are not. The built-in functions -``keccak256``, ``sha256``, ``ripemd160``, ``ecrecover``, ``addmod`` and ``mulmod`` -are allowed (even though, with the exception of ``keccak256``, they do call external contracts). +对于 ``constant`` å˜é‡ï¼Œå…¶å€¼åœ¨ç¼–译时必须是一个常é‡ï¼Œå¹¶ä¸”必须在å˜é‡å£°æ˜Žçš„地方分é…。 +任何访问存储ã€åŒºå—链数æ®ï¼ˆä¾‹å¦‚: ``block.timestamp``, ``address(this).balance`` 或 ``block.number``) +或执行数æ®ï¼ˆ ``msg.value`` 或 ``gasleft()``)或者调用外部åˆçº¦çš„表达å¼éƒ½æ˜¯ä¸å…许的。 +但å¯èƒ½å¯¹å†…存分é…产生副作用的表达å¼æ˜¯å…许的,但那些å¯èƒ½å¯¹å…¶ä»–内存对象产生副作用的表达å¼æ˜¯ä¸å…许的。 +内置函数 ``keccak256``, ``sha256``, ``ripemd160``, ``ecrecover``, ``addmod`` å’Œ ``mulmod`` +是å…许的(尽管除了 ``keccak256``,它们确实调用了外部åˆçº¦ï¼‰ã€‚ -The reason behind allowing side-effects on the memory allocator is that it -should be possible to construct complex objects like e.g. lookup-tables. -This feature is not yet fully usable. +å…许在内存分é…器上产生副作用的原因是, +它应该å¯ä»¥æž„建å¤æ‚的对象,比如说查找表。 +这个功能现在还ä¸èƒ½å®Œå…¨ä½¿ç”¨ã€‚ Immutable ========= +<<<<<<< HEAD +声明为 ``immutable`` çš„å˜é‡æ¯”声明为 ``constant`` çš„å˜é‡å—到的é™åˆ¶è¦å°‘一些。 +ä¸å¯å˜çš„å˜é‡å¯ä»¥åœ¨åˆçº¦çš„构造函数中或在声明时被分é…一个任æ„的值。 +它们åªèƒ½è¢«åˆ†é…一次,并且从那时起,å³ä½¿åœ¨æž„造时间内也å¯ä»¥è¢«è¯»å–。 + +编译器生æˆçš„åˆçº¦åˆ›å»ºä»£ç å°†åœ¨å…¶è¿”回之å‰ä¿®æ”¹åˆçº¦çš„è¿è¡Œæ—¶ä»£ç ï¼Œ +用分é…给它们的值替æ¢æ‰€æœ‰å¯¹ä¸å¯å˜é‡çš„引用。 +当您将编译器生æˆçš„è¿è¡Œæ—¶ä»£ç ä¸Žå®žé™…存储在区å—链中的代ç è¿›è¡Œæ¯”较时,这一点很é‡è¦ã€‚ + +.. note:: + 在声明时被分é…çš„ä¸å¯å˜é‡åªæœ‰åœ¨åˆçº¦çš„构造函数执行时æ‰ä¼šè¢«è§†ä¸ºåˆå§‹åŒ–。 + è¿™æ„味ç€æ‚¨ä¸èƒ½åœ¨å†…è”中用一个ä¾èµ–于å¦ä¸€ä¸ªä¸å¯å˜é‡çš„值æ¥åˆå§‹åŒ–ä¸å¯å˜é‡ã€‚ + 然而,您å¯ä»¥åœ¨åˆçº¦çš„构造函数中这样åšã€‚ + + 这是对状æ€å˜é‡åˆå§‹åŒ–和构造函数执行顺åºçš„ä¸åŒè§£é‡Šçš„一ç§ä¿éšœï¼Œç‰¹åˆ«æ˜¯åœ¨ç»§æ‰¿æ–¹é¢ã€‚ +======= Variables declared as ``immutable`` are a bit less restricted than those declared as ``constant``: Immutable variables can be assigned a value at construction time. @@ -109,3 +123,4 @@ you are comparing the runtime code generated by the compiler with the one actually stored in the blockchain. The compiler outputs where these immutables are located in the deployed bytecode in the ``immutableReferences`` field of the :ref:`compiler JSON standard output `. +>>>>>>> english/develop diff --git a/docs/contracts/creating-contracts.rst b/docs/contracts/creating-contracts.rst index 8eb4e5f56c28..4c7a69a82450 100644 --- a/docs/contracts/creating-contracts.rst +++ b/docs/contracts/creating-contracts.rst @@ -1,36 +1,33 @@ .. index:: ! contract;creation, constructor ****************** -Creating Contracts +创建åˆçº¦ ****************** -Contracts can be created "from outside" via Ethereum transactions or from within Solidity contracts. +å¯ä»¥é€šè¿‡ä»¥å¤ªåŠäº¤æ˜“ “从外部†或从 Solidity åˆçº¦å†…部创建åˆçº¦ã€‚ -IDEs, such as `Remix `_, make the creation process seamless using UI elements. +集æˆå¼€å‘环境,如 `Remix `_,使用UI元素使创建过程无ç¼åŒ–。 -One way to create contracts programmatically on Ethereum is via the JavaScript API `web3.js `_. -It has a function called `web3.eth.Contract `_ -to facilitate contract creation. +在以太åŠä¸Šä»¥ç¼–程方å¼åˆ›å»ºåˆçº¦çš„一ç§æ–¹æ³•æ˜¯é€šè¿‡JavaScript API `web3.js `_。 +它有一个å为 `web3.eth.Contract `_ 的函数, +以方便创建åˆçº¦ã€‚ -When a contract is created, its :ref:`constructor ` (a function declared with -the ``constructor`` keyword) is executed once. +当一个åˆçº¦è¢«åˆ›å»ºæ—¶ï¼Œå®ƒçš„ :ref:`构造函数(constructor) ` +(一个用 ``constructor`` 关键字声明的函数)被执行一次。 -A constructor is optional. Only one constructor is allowed, which means -overloading is not supported. +构造函数是å¯é€‰çš„。但是åªå…许有一个构造函数,这æ„味ç€ä¸æ”¯æŒé‡è½½ã€‚ -After the constructor has executed, the final code of the contract is stored on the -blockchain. This code includes all public and external functions and all functions -that are reachable from there through function calls. The deployed code does not -include the constructor code or internal functions only called from the constructor. +构造函数执行完毕åŽï¼Œåˆçº¦çš„最终代ç è¢«å­˜å‚¨åœ¨åŒºå—链上。 +这段代ç åŒ…括所有公开和外部函数,以åŠæ‰€æœ‰é€šè¿‡å‡½æ•°è°ƒç”¨å¯ä»Žé‚£é‡Œåˆ°è¾¾çš„函数。 +部署的代ç ä¸åŒ…括构造函数代ç æˆ–åªä»Žæž„造函数调用的内部函数。 .. index:: constructor;arguments -Internally, constructor arguments are passed :ref:`ABI encoded ` after the code of -the contract itself, but you do not have to care about this if you use ``web3.js``. +在内部,构造函数å‚数在åˆçº¦ä»£ç ä¹‹åŽé€šè¿‡ :ref:`ABIç¼–ç  ` 传递, +但是如果您使用 ``web3.js`` 则ä¸å¿…关心这个问题。 -If a contract wants to create another contract, the source code -(and the binary) of the created contract has to be known to the creator. -This means that cyclic creation dependencies are impossible. +如果一个åˆçº¦æƒ³åˆ›å»ºå¦ä¸€ä¸ªåˆçº¦ï¼Œåˆ›å»ºè€…必须知é“所创建åˆçº¦çš„æºä»£ç ï¼ˆå’ŒäºŒè¿›åˆ¶ï¼‰ã€‚ +è¿™æ„味ç€ï¼Œå¾ªçŽ¯çš„创建ä¾èµ–是ä¸å¯èƒ½çš„。 .. code-block:: solidity @@ -39,53 +36,47 @@ This means that cyclic creation dependencies are impossible. contract OwnedToken { - // `TokenCreator` is a contract type that is defined below. - // It is fine to reference it as long as it is not used - // to create a new contract. + // `TokenCreator` 是如下定义的åˆçº¦ç±»åž‹ã€‚ + // ä¸åˆ›å»ºæ–°åˆçº¦çš„è¯ï¼Œä¹Ÿå¯ä»¥å¼•ç”¨å®ƒã€‚ TokenCreator creator; address owner; bytes32 name; - // This is the constructor which registers the - // creator and the assigned name. + // 这是注册 creator 和设置å称的构造函数。 constructor(bytes32 name_) { - // State variables are accessed via their name - // and not via e.g. `this.owner`. Functions can - // be accessed directly or through `this.f`, - // but the latter provides an external view - // to the function. Especially in the constructor, - // you should not access functions externally, - // because the function does not exist yet. - // See the next section for details. + // 状æ€å˜é‡é€šè¿‡å…¶å称访问, + // 而ä¸æ˜¯é€šè¿‡ä¾‹å¦‚ `this.owner` çš„æ–¹å¼è®¿é—®ã€‚ + // 函数å¯ä»¥ç›´æŽ¥æˆ–通过 `this.f` 访问。 + // 但åŽè€…æ供了一个对函数的外部å¯è§†æ–¹æ³•ã€‚ + // 特别是在构造函数中,您ä¸åº”该从外部访问函数, + // 因为该函数还ä¸å­˜åœ¨ã€‚ + // 详è§ä¸‹ä¸€èŠ‚。 owner = msg.sender; - // We perform an explicit type conversion from `address` - // to `TokenCreator` and assume that the type of - // the calling contract is `TokenCreator`, there is - // no real way to verify that. - // This does not create a new contract. + // 我们进行了从 `address` 到 `TokenCreator` 的显å¼ç±»åž‹è½¬æ¢ï¼Œ + // 并å‡å®šè°ƒç”¨åˆçº¦çš„类型是 `TokenCreator`, + // 没有真正的方法æ¥éªŒè¯ï¼Œ + // 这并没有创建一个新的åˆçº¦ã€‚ creator = TokenCreator(msg.sender); name = name_; } function changeName(bytes32 newName) public { - // Only the creator can alter the name. - // We compare the contract based on its - // address which can be retrieved by - // explicit conversion to address. + // åªæœ‰åˆ›å»ºè€…å¯ä»¥æ”¹å˜å称。 + // 我们根æ®åˆçº¦çš„地å€è¿›è¡Œæ¯”较, + // 它å¯ä»¥é€šè¿‡æ˜¾å¼è½¬æ¢ä¸ºåœ°å€æ¥æ£€ç´¢ã€‚ if (msg.sender == address(creator)) name = newName; } function transfer(address newOwner) public { - // Only the current owner can transfer the token. + // åªæœ‰å½“å‰æ‰€æœ‰è€…æ‰èƒ½å‘é€ token。 if (msg.sender != owner) return; - // We ask the creator contract if the transfer - // should proceed by using a function of the - // `TokenCreator` contract defined below. If - // the call fails (e.g. due to out-of-gas), - // the execution also fails here. + // 我们通过使用下é¢å®šä¹‰çš„ `TokenCreator` åˆçº¦çš„一个函数 + // æ¥è¯¢é—®åˆ›å»ºè€…åˆçº¦æ˜¯å¦åº”该进行转移。 + // 如果调用失败(例如由于气体值耗尽), + // 这里的执行也会失败。 if (creator.isTokenTransferOK(owner, newOwner)) owner = newOwner; } @@ -97,27 +88,25 @@ This means that cyclic creation dependencies are impossible. public returns (OwnedToken tokenAddress) { - // Create a new `Token` contract and return its address. - // From the JavaScript side, the return type - // of this function is `address`, as this is - // the closest type available in the ABI. + // 创建一个新的 `Token` åˆçº¦å¹¶è¿”回其地å€ã€‚ + // 从JavaScriptæ–¹é¢æ¥çœ‹ï¼Œ + // 这个函数的返回类型是 `address`, + // 因为这是ABI中最接近的类型。 return new OwnedToken(name); } function changeName(OwnedToken tokenAddress, bytes32 name) public { - // Again, the external type of `tokenAddress` is - // simply `address`. + // åŒæ ·ï¼Œ`tokenAddress` 的外部类型是简å•çš„ `address`。 tokenAddress.changeName(name); } - // Perform checks to determine if transferring a token to the - // `OwnedToken` contract should proceed + // 执行检查,以确定是å¦åº”该将代å¸è½¬ç§»åˆ° `OwnedToken` åˆçº¦ä¸Šã€‚ function isTokenTransferOK(address currentOwner, address newOwner) public pure returns (bool ok) { - // Check an arbitrary condition to see if transfer should proceed + // 检查一个任æ„çš„æ¡ä»¶ï¼Œçœ‹æ˜¯å¦åº”该进行转移。 return keccak256(abi.encodePacked(currentOwner, newOwner))[0] == 0x7f; } } diff --git a/docs/contracts/errors.rst b/docs/contracts/errors.rst index 19577a3872ba..c7ba3355d2f1 100644 --- a/docs/contracts/errors.rst +++ b/docs/contracts/errors.rst @@ -2,26 +2,23 @@ .. _errors: ******************************* -Errors and the Revert Statement +错误和æ¢å¤è¯­å¥ ******************************* -Errors in Solidity provide a convenient and gas-efficient way to explain to the -user why an operation failed. They can be defined inside and outside of contracts (including interfaces and libraries). +Solidity 中的错误æ供了一ç§æ–¹ä¾¿ä¸”çœgasçš„æ–¹å¼æ¥å‘用户解释为什么一个æ“作会失败。 +它们å¯ä»¥è¢«å®šä¹‰åœ¨åˆçº¦å†…部和外部(包括接å£åˆçº¦å’Œåº“åˆçº¦ï¼‰ã€‚ -They have to be used together with the :ref:`revert statement ` -which causes -all changes in the current call to be reverted and passes the error data back to the -caller. +它们必须与 :ref:`æ¢å¤è¯­å¥ ` 一起使用, +它导致当å‰è°ƒç”¨ä¸­çš„所有å˜åŒ–被æ¢å¤ï¼Œå¹¶å°†é”™è¯¯æ•°æ®ä¼ å›žç»™è°ƒç”¨è€…。 .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.4; - /// Insufficient balance for transfer. Needed `required` but only - /// `available` available. - /// @param available balance available. - /// @param required requested amount to transfer. + /// 转账的余é¢ä¸è¶³ã€‚éœ€è¦ `required` æ•°é‡ä½†åªæœ‰ `available` æ•°é‡å¯ç”¨ã€‚ + /// @param å¯ç”¨çš„ä½™é¢ã€‚ + /// @param 需è¦è¦æ±‚的转å¸é‡‘é¢ã€‚ error InsufficientBalance(uint256 available, uint256 required); contract TestToken { @@ -38,49 +35,43 @@ caller. // ... } -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. +错误ä¸èƒ½è¢«é‡è½½æˆ–覆盖,但是å¯ä»¥è¢«ç»§æ‰¿ã€‚ +åªè¦ä½œç”¨åŸŸä¸åŒï¼ŒåŒä¸€ä¸ªé”™è¯¯å¯ä»¥åœ¨å¤šä¸ªåœ°æ–¹å®šä¹‰ã€‚ +错误的实例åªèƒ½ä½¿ç”¨ ``revert`` 语å¥åˆ›å»ºã€‚ -The error creates data that is then passed to the caller with the revert operation -to either return to the off-chain component or catch it in a :ref:`try/catch statement `. -Note that an error can only be caught when coming from an external call, -reverts happening in internal calls or inside the same function cannot be caught. +错误会创建数æ®ï¼Œç„¶åŽé€šè¿‡è¿˜åŽŸæ“作传递给调用者, +使其返回到链下组件或在 :ref:`try/catch è¯­å¥ ` 中æ•èŽ·å®ƒã€‚ +需è¦æ³¨æ„的是,一个错误åªèƒ½åœ¨æ¥è‡ªå¤–部调用时被æ•èŽ·ï¼Œ +å‘生在内部调用或åŒä¸€å‡½æ•°å†…的还原ä¸èƒ½è¢«æ•èŽ·ã€‚ -If you do not provide any parameters, the error only needs four bytes of -data and you can use :ref:`NatSpec ` as above -to further explain the reasons behind the error, which is not stored on chain. -This makes this a very cheap and convenient error-reporting feature at the same time. +如果您ä¸æ供任何å‚数,错误åªéœ€è¦å››ä¸ªå­—节的数æ®ï¼Œ +您å¯ä»¥åƒä¸Šé¢ä¸€æ ·ä½¿ç”¨ :ref:`NatSpec 语法 ` æ¥è¿›ä¸€æ­¥è§£é‡Šé”™è¯¯èƒŒåŽçš„原因, +这并ä¸å­˜å‚¨åœ¨é“¾ä¸Šã€‚这使得这åŒæ—¶ä¹Ÿæ˜¯ä¸€ä¸ªéžå¸¸ä¾¿å®œå’Œæ–¹ä¾¿çš„错误报告功能。 -More specifically, an error instance is ABI-encoded in the same way as -a function call to a function of the same name and types would be -and then used as the return data in the ``revert`` opcode. -This means that the data consists of a 4-byte selector followed by :ref:`ABI-encoded` data. -The selector consists of the first four bytes of the keccak256-hash of the signature of the error type. +更具体地说,一个错误实例在被ABIç¼–ç æ—¶ï¼Œ +其方å¼ä¸Žå¯¹ç›¸åŒå称和类型的函数的调用相åŒï¼Œ +然åŽä½œä¸º ``revert`` æ“作ç çš„返回数æ®ã€‚ +è¿™æ„味ç€æ•°æ®ç”±ä¸€ä¸ª4字节的选择器和 :ref:`ABIç¼–ç  ` æ•°æ®ç»„æˆã€‚ +选择器由错误类型的签åçš„keccak256-hashçš„å‰å››ä¸ªå­—节组æˆã€‚ .. note:: - It is possible for a contract to revert - with different errors of the same name or even with errors defined in different places - that are indistinguishable by the caller. For the outside, i.e. the ABI, - only the name of the error is relevant, not the contract or file where it is defined. + 一个åˆçº¦æœ‰å¯èƒ½å› ä¸ºåŒåçš„ä¸åŒé”™è¯¯è€Œæ¢å¤ï¼Œ + 甚至因为在ä¸åŒåœ°æ–¹å®šä¹‰çš„错误而使调用者无法区分。 + 对于外部æ¥è¯´ï¼Œå³ABI,åªæœ‰é”™è¯¯çš„å称是相关的,而ä¸æ˜¯å®šä¹‰å®ƒçš„åˆçº¦æˆ–文件。 -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. +如果您能定义 ``error Error(string)``, +é‚£ä¹ˆè¯­å¥ ``require(condition, "description");`` +将等åŒäºŽ ``if (!condition) revert Error("description")``。 +但是请注æ„, ``Error`` 是一个内置类型,ä¸èƒ½åœ¨ç”¨æˆ·æ供的代ç ä¸­å®šä¹‰ã€‚ -Similarly, a failing ``assert`` or similar conditions will revert with an error -of the built-in type ``Panic(uint256)``. +åŒæ ·ï¼Œä¸€ä¸ªå¤±è´¥çš„ ``assert`` 或类似的æ¡ä»¶å°†ä»¥ä¸€ä¸ªå†…置的 ``Panic(uint256)`` 类型的错误æ¥æ¢å¤ã€‚ .. note:: - Error data should only be used to give an indication of failure, but - not as a means for control-flow. The reason is that the revert data - of inner calls is propagated back through the chain of external calls - by default. This means that an inner call - can "forge" revert data that looks like it could have come from the - contract that called it. - -Members of Errors + 错误数æ®åº”该åªè¢«ç”¨æ¥æŒ‡ç¤ºå¤±è´¥ï¼Œè€Œä¸æ˜¯ä½œä¸ºæŽ§åˆ¶æµçš„手段。 + 原因是内部调用的æ¢å¤æ•°æ®é»˜è®¤æ˜¯é€šè¿‡å¤–部调用链传播回æ¥çš„。 + è¿™æ„味ç€å†…部调用å¯ä»¥ â€ä¼ªé€ â€ æ¢å¤æ•°æ®ï¼Œä½¿å®ƒçœ‹èµ·æ¥åƒæ˜¯æ¥è‡ªè°ƒç”¨å®ƒçš„åˆçº¦ã€‚ + +错误类型的æˆå‘˜ ================= -- ``error.selector``: A ``bytes4`` value containing the error selector. +- ``error.selector``: 一个包å«é”™è¯¯ç±»åž‹çš„选择器的 ``bytes4`` 值。 diff --git a/docs/contracts/events.rst b/docs/contracts/events.rst index 8c73c31603ae..690dafcf1fc9 100644 --- a/docs/contracts/events.rst +++ b/docs/contracts/events.rst @@ -3,12 +3,19 @@ .. _events: ****** -Events +事件 ****** -Solidity events give an abstraction on top of the EVM's logging functionality. -Applications can subscribe and listen to these events through the RPC interface of an Ethereum client. +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 @@ -17,29 +24,25 @@ 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 -It is possible to request a Merkle proof for logs, so if -an external entity supplies a contract with such a proof, it can check -that the log actually exists inside the blockchain. You have to supply block headers -because the contract can only see the last 256 block hashes. +有å¯èƒ½è¦æ±‚为日志æä¾›Merkleè¯æ˜Žï¼Œ +所以如果外部实体å‘åˆçº¦æ供这样的è¯æ˜Žï¼Œå®ƒå¯ä»¥æ£€æŸ¥æ—¥å¿—是å¦çœŸçš„存在于区å—链中。 +由于åˆçº¦ä¸­ä»…能访问最近的 256 个区å—哈希,所以还需è¦æ供区å—头信æ¯ã€‚ -You can add the attribute ``indexed`` to up to three parameters which adds them -to a special data structure known as :ref:`"topics" ` instead of -the data part of the log. -A topic can only hold a single word (32 bytes) so if you use a :ref:`reference type -` for an indexed argument, the Keccak-256 hash of the value is stored -as a topic instead. +您å¯ä»¥æœ€å¤šç»™ä¸‰ä¸ªå‚数添加 ``indexed`` 属性,将它们添加到一个特殊的数æ®ç»“构中, +称为 :ref:`"topics" `,而ä¸æ˜¯æ—¥å¿—çš„æ•°æ®éƒ¨åˆ†ã€‚ +一个topicåªèƒ½å®¹çº³ä¸€ä¸ªå­—(32字节),所以如果您为一个索引å‚数使用 :ref:`引用类型 `, +该值的Keccak-256哈希值将被存储为一个topic中。 -All parameters without the ``indexed`` attribute are :ref:`ABI-encoded ` -into the data part of the log. +所有没有 ``indexed`` 属性的å‚数都会被 :ref:`ABI ç¼–ç  ` 到日志的数æ®éƒ¨åˆ†ã€‚ -Topics allow you to search for events, for example when filtering a sequence of -blocks for certain events. You can also filter events by the address of the -contract that emitted the event. +Topicså…许您用æ¥æœç´¢äº‹ä»¶ï¼Œä¾‹å¦‚为特定的事件æ¥è¿‡æ»¤ä¸€ç³»åˆ—的区å—。 +您用æ¥ä¹Ÿå¯ä»¥é€šè¿‡å‘出事件的åˆçº¦çš„地å€æ¥è¿‡æ»¤äº‹ä»¶ã€‚ -For example, the code below uses the web3.js ``subscribe("logs")`` -`method `_ to filter -logs that match a topic with a certain address value: +例如,下é¢çš„代ç ä½¿ç”¨web3.js ``subscribe("logs")`` +`方法 `_ +æ¥è¿‡æ»¤ä¸ŽæŸä¸€åœ°å€å€¼ç›¸åŒ¹é…的日志: .. code-block:: javascript @@ -59,31 +62,26 @@ logs that match a topic with a certain address value: }); -The hash of the signature of the event is one of the topics, except if you -declared the event with the ``anonymous`` specifier. This means that it is -not possible to filter for specific anonymous events by name, you can -only filter by the contract address. The advantage of anonymous events -is that they are cheaper to deploy and call. It also allows you to declare -four indexed arguments rather than three. +除éžæ‚¨ç”¨ ``anonymous`` 指定符声明事件,å¦åˆ™äº‹ä»¶çš„ç­¾å的哈希值是topic之一。 +è¿™æ„味ç€ä¸å¯èƒ½é€šè¿‡åå­—æ¥è¿‡æ»¤ç‰¹å®šçš„匿å事件, +您åªèƒ½é€šè¿‡åˆçº¦åœ°å€æ¥è¿‡æ»¤ã€‚匿å事件的优点是,它们的部署和调用都比较便宜。 +它还å…许您声明四个索引å‚数,而ä¸æ˜¯ä¸‰ä¸ªã€‚ + .. note:: - Since the transaction log only stores the event data and not the type, - you have to know the type of the event, including which parameter is - indexed and if the event is anonymous in order to correctly interpret - the data. - In particular, it is possible to "fake" the signature of another event - using an anonymous event. + 由于交易日志åªå­˜å‚¨äº‹ä»¶æ•°æ®è€Œä¸å­˜å‚¨ç±»åž‹ï¼Œå› æ­¤æ‚¨å¿…须知é“事件的类型, + 包括哪个å‚数被索引以åŠäº‹ä»¶æ˜¯å¦æ˜¯åŒ¿å的,以便正确解æžæ•°æ®ã€‚ + 特别的是,有å¯èƒ½ç”¨ä¸€ä¸ªåŒ¿å事件 “伪造“ å¦ä¸€ä¸ªäº‹ä»¶çš„ç­¾å。 .. index:: ! selector; of an event -Members of Events -================= - -- ``event.selector``: For non-anonymous events, this is a ``bytes32`` value - containing the ``keccak256`` hash of the event signature, as used in the default topic. +事件类型的æˆå‘˜æ–¹æ³• +=================== +- ``event.selector``: 对于éžåŒ¿å事件,这是一个 ``bytes32`` 值, + 包å«äº‹ä»¶ç­¾åçš„ ``keccak256`` 哈希值,在默认topic中使用。 -Example +示例 ======= .. code-block:: solidity @@ -99,41 +97,38 @@ Example ); function deposit(bytes32 id) public payable { - // Events are emitted using `emit`, followed by - // the name of the event and the arguments - // (if any) in parentheses. Any such invocation - // (even deeply nested) can be detected from - // the JavaScript API by filtering for `Deposit`. + // 事件是用 `emit` å‘出的,åŽé¢æ˜¯äº‹ä»¶çš„å称和括å·é‡Œçš„å‚数(如果有)。 + // 任何这样的调用(甚至是深度嵌套)都å¯ä»¥é€šè¿‡è¿‡æ»¤ `Deposit` + // 从JavaScript API中检测出æ¥ã€‚ emit Deposit(msg.sender, id, msg.value); } } -The use in the JavaScript API is as follows: +在JavaScript API中的使用方å¼å¦‚下: .. code-block:: javascript - var abi = /* abi as generated by the compiler */; + var abi = /* 由编译器产生的abi */; var ClientReceipt = web3.eth.contract(abi); - var clientReceipt = ClientReceipt.at("0x1234...ab67" /* address */); + var clientReceipt = ClientReceipt.at("0x1234...ab67" /* åœ°å€ */); var depositEvent = clientReceipt.Deposit(); - // watch for changes + // 监视å˜åŒ– depositEvent.watch(function(error, result){ - // result contains non-indexed arguments and topics - // given to the `Deposit` call. + // 结果包å«éžç´¢å¼•çš„å‚数和给 `Deposit` 调用的 topics。 if (!error) console.log(result); }); - // Or pass a callback to start watching immediately + // 或者通过回调立å³å¼€å§‹ç›‘视 var depositEvent = clientReceipt.Deposit(function(error, result) { if (!error) console.log(result); }); -The output of the above looks like the following (trimmed): +上é¢çš„输出看起æ¥åƒä¸‹é¢è¿™æ ·ï¼ˆç»è¿‡ä¿®å‰ªï¼‰: .. code-block:: json @@ -149,9 +144,9 @@ The output of the above looks like the following (trimmed): } } -Additional Resources for Understanding Events -============================================= +了解事件类型的其他资料 +====================== -- `JavaScript documentation `_ -- `Example usage of events `_ -- `How to access them in js `_ +- `JavaScript 文档 `_ +- `事件的使用实例 `_ +- `如何在js中访问它们 `_ diff --git a/docs/contracts/function-modifiers.rst b/docs/contracts/function-modifiers.rst index 454e12ab65cf..ee400726f581 100644 --- a/docs/contracts/function-modifiers.rst +++ b/docs/contracts/function-modifiers.rst @@ -3,35 +3,40 @@ .. _modifiers: ****************** -Function Modifiers +函数修饰器 ****************** +<<<<<<< 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 -Modifiers are -inheritable properties of contracts and may be overridden by derived contracts, but only -if they are marked ``virtual``. For details, please see -:ref:`Modifier Overriding `. +修饰器是åˆçº¦çš„å¯ç»§æ‰¿å±žæ€§ï¼Œå¯ä»¥è¢«æ´¾ç”Ÿåˆçº¦é‡è½½ï¼Œ +但åªæœ‰å½“它们被标记为 ``virtual`` 时,æ‰èƒ½è¢«é‡è½½ã€‚ +è¯¦æƒ…è¯·è§ :ref:`修饰器é‡è½½ `。 .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.1 <0.9.0; - // This will report a warning due to deprecated selfdestruct +<<<<<<< HEAD + // 这将报告一个由于废弃的 selfdestruct 而产生的警告 +======= +>>>>>>> english/develop contract owned { constructor() { owner = payable(msg.sender); } address payable owner; - // This contract only defines a modifier but does not use - // it: it will be used in derived contracts. - // The function body is inserted where the special symbol - // `_;` in the definition of a modifier appears. - // This means that if the owner calls this function, the - // function is executed and otherwise, an exception is - // thrown. + // 这个åˆçº¦åªå®šä¹‰äº†ä¸€ä¸ªä¿®é¥°å™¨ï¼Œä½†æ²¡æœ‰ä½¿ç”¨å®ƒï¼š + // 它将在派生åˆçº¦ä¸­ä½¿ç”¨ã€‚ + // 修饰器所修饰的函数体会被æ’å…¥åˆ°ç‰¹æ®Šç¬¦å· `_;` çš„ä½ç½®ã€‚ + // è¿™æ„味ç€ï¼Œå¦‚果所有者调用这个函数,这个函数就会被执行, + // å¦åˆ™å°±ä¼šæŠ›å‡ºä¸€ä¸ªå¼‚常。 modifier onlyOwner { require( msg.sender == owner, @@ -41,18 +46,20 @@ if they are marked ``virtual``. For details, please see } } +<<<<<<< HEAD contract destructible is owned { - // This contract inherits the `onlyOwner` modifier from - // `owned` and applies it to the `destroy` function, which - // causes that calls to `destroy` only have an effect if - // they are made by the stored owner. + // 这个åˆçº¦ä»Ž `owned` åˆçº¦ç»§æ‰¿äº† `onlyOwner` 修饰器, + // 并将其应用于 `destroy` 函数, + // åªæœ‰åœ¨åˆçº¦é‡Œä¿å­˜çš„ owner 调用 `destroy` 函数,æ‰ä¼šç”Ÿæ•ˆã€‚ function destroy() public onlyOwner { selfdestruct(owner); } } +======= +>>>>>>> english/develop contract priced { - // Modifiers can receive arguments: + // 修饰器å¯ä»¥æŽ¥å—å‚数: modifier costs(uint price) { if (msg.value >= price) { _; @@ -60,19 +67,21 @@ if they are marked ``virtual``. For details, please see } } - contract Register is priced, destructible { + contract Register is priced, owned { mapping(address => bool) registeredAddresses; uint price; constructor(uint initialPrice) { price = initialPrice; } - // It is important to also provide the - // `payable` keyword here, otherwise the function will - // automatically reject all Ether sent to it. + // 在这里也使用关键字 `payable` éžå¸¸é‡è¦ï¼Œ + // å¦åˆ™å‡½æ•°ä¼šè‡ªåŠ¨æ‹’ç»æ‰€æœ‰å‘é€ç»™å®ƒçš„以太å¸ã€‚ function register() public payable costs(price) { 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_; } @@ -90,10 +99,8 @@ if they are marked ``virtual``. For details, please see locked = false; } - /// This function is protected by a mutex, which means that - /// reentrant calls from within `msg.sender.call` cannot call `f` again. - /// The `return 7` statement assigns 7 to the return value but still - /// executes the statement `locked = false` in the modifier. + /// 这个函数å—互斥é‡ä¿æŠ¤ï¼Œè¿™æ„å‘³ç€ `msg.sender.call` 中的é‡å…¥è°ƒç”¨ä¸èƒ½å†æ¬¡è°ƒç”¨ `f`。 + /// `return 7` 语å¥æŒ‡å®šè¿”回值为 7ï¼Œä½†ä¿®é¥°å™¨ä¸­çš„è¯­å¥ `locked = false` ä»ä¼šæ‰§è¡Œã€‚ function f() public noReentrancy returns (uint) { (bool success,) = msg.sender.call(""); require(success); @@ -101,40 +108,37 @@ if they are marked ``virtual``. For details, please see } } -If you want to access a modifier ``m`` defined in a contract ``C``, you can use ``C.m`` to -reference it without virtual lookup. It is only possible to use modifiers defined in the current -contract or its base contracts. Modifiers can also be defined in libraries but their use is -limited to functions of the same library. +如果您想访问定义在åˆçº¦ ``C`` 中的修饰器 ``m``, +您å¯ä»¥ä½¿ç”¨ ``C.m`` æ¥å¼•ç”¨å®ƒè€Œä¸éœ€è¦è™šæ‹ŸæŸ¥è¯¢ã€‚ +åªèƒ½ä½¿ç”¨å®šä¹‰åœ¨å½“å‰åˆçº¦æˆ–其基础åˆçº¦ä¸­çš„修饰器。 +修饰器也å¯ä»¥å®šä¹‰åœ¨åº“åˆçº¦ä¸­ï¼Œä½†å…¶ä½¿ç”¨ä»…é™äºŽåŒä¸€åº“åˆçº¦çš„函数。 -Multiple modifiers are applied to a function by specifying them in a -whitespace-separated list and are evaluated in the order presented. +如果åŒä¸€ä¸ªå‡½æ•°æœ‰å¤šä¸ªä¿®é¥°å™¨ï¼Œå®ƒä»¬ä¹‹é—´ä»¥ç©ºæ ¼éš”开,并按照所呈现的顺åºè¿›è¡Œè¯„ä¼°è¿ç®—。 -Modifiers cannot implicitly access or change the arguments and return values of functions they modify. -Their values can only be passed to them explicitly at the point of invocation. +修饰器ä¸èƒ½éšå¼åœ°è®¿é—®æˆ–改å˜å®ƒä»¬æ‰€ä¿®æ”¹çš„函数的å‚数和返回值。 +它们的值åªèƒ½åœ¨è°ƒç”¨çš„时候明确地传递给它们。 -In function modifiers, it is necessary to specify when you want the function to which the modifier is -applied to be run. The placeholder statement (denoted by a single underscore character ``_``) is used to -denote where the body of the function being modified should be inserted. Note that the -placeholder operator is different from using underscores as leading or trailing characters in variable -names, which is a stylistic choice. +在函数修改器中,有必è¦æŒ‡å®šä½•æ—¶è¿è¡Œåº”用修改器的函数。 +å ä½ç¬¦è¯­å¥ï¼ˆç”¨å•ä¸ªä¸‹åˆ’线字符 ``_`` 表示)用于表示被修改的函数主体应该æ’入的ä½ç½®ã€‚ +请注æ„,å ä½ç¬¦æ“作符与在å˜é‡å中使用下划线作为å‰å¯¼æˆ–å°¾éšå­—符ä¸åŒï¼Œ +åŽè€…是一ç§é£Žæ ¼ä¸Šçš„选择。 -Explicit returns from a modifier or function body only leave the current -modifier or function body. Return variables are assigned and -control flow continues after the ``_`` in the preceding modifier. +修饰器或函数体的显å¼è¿”回åªç¦»å¼€å½“å‰ä¿®é¥°å™¨æˆ–函数体。 +返回å˜é‡ä¼šè¢«èµ‹å€¼ï¼Œä½†æ•´ä¸ªæ‰§è¡Œé€»è¾‘会从å‰ä¸€ä¸ªä¿®é¥°å™¨ä¸­å®šä¹‰çš„ ``_`` 之åŽç»§ç»­æ‰§è¡Œã€‚ .. warning:: - In an earlier version of Solidity, ``return`` statements in functions - having modifiers behaved differently. + 在Solidity的早期版本中,具有修饰器的函数中的 ``return`` 语å¥ä¼šè¡¨çŽ°çš„ä¸åŒã€‚ -An explicit return from a modifier with ``return;`` does not affect the values returned by the function. -The modifier can, however, choose not to execute the function body at all and in that case the return -variables are set to their :ref:`default values` just as if the function had an empty -body. +用 ``return;`` 从修饰器显å¼è¿”回并ä¸å½±å“函数返回的值。 +然而,修饰器å¯ä»¥é€‰æ‹©å®Œå…¨ä¸æ‰§è¡Œå‡½æ•°ä¸»ä½“,在这ç§æƒ…况下, +返回å˜é‡è¢«è®¾ç½®ä¸º :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 -Arbitrary expressions are allowed for modifier arguments and in this context, -all symbols visible from the function are visible in the modifier. Symbols -introduced in the modifier are not visible in the function (as they might -change by overriding). +å…许修饰器å‚数使用任æ„表达å¼ï¼Œåœ¨è¿™ç§æƒ…况下,所有从函数中å¯è§çš„符å·åœ¨ä¿®é¥°å™¨ä¸­éƒ½æ˜¯å¯è§çš„。 +修饰器中引入的符å·åœ¨å‡½æ•°ä¸­æ˜¯ä¸å¯è§çš„(因为它们å¯èƒ½å› é‡è½½è€Œæ”¹å˜ï¼‰ã€‚ diff --git a/docs/contracts/functions.rst b/docs/contracts/functions.rst index 5b82a93bcc73..ed1017acbfb9 100644 --- a/docs/contracts/functions.rst +++ b/docs/contracts/functions.rst @@ -3,14 +3,13 @@ .. _functions: ********* -Functions +函数 ********* -Functions can be defined inside and outside of contracts. +å¯ä»¥åœ¨åˆçº¦å†…部和外部定义函数。 -Functions outside of a contract, also called "free functions", always have implicit ``internal`` -:ref:`visibility`. Their code is included in all contracts -that call them, similar to internal library functions. +åˆçº¦ä¹‹å¤–的函数,也称为 "自由函数",总是éšå«ç€ ``internal`` çš„ :ref:`å¯è§æ€§ `。 +它们的代ç åŒ…å«åœ¨æ‰€æœ‰è°ƒç”¨å®ƒä»¬çš„åˆçº¦ä¸­ï¼Œç±»ä¼¼äºŽå†…部库函数。 .. code-block:: solidity @@ -25,8 +24,8 @@ that call them, similar to internal library functions. contract ArrayExample { bool found; function f(uint[] memory arr) public { - // This calls the free function internally. - // The compiler will add its code to the contract. + // 这在内部调用自由函数。 + // 编译器会将其代ç æ·»åŠ åˆ°åˆçº¦ä¸­ã€‚ uint s = sum(arr); require(s >= 10); found = true; @@ -34,29 +33,24 @@ that call them, similar to internal library functions. } .. note:: - Functions defined outside a contract are still always executed - in the context of a contract. - They still can call other contracts, send them Ether and destroy the contract that called them, - among other things. The main difference to functions defined inside a contract - is that free functions do not have direct access to the variable ``this``, storage variables and functions - not in their scope. + 在åˆçº¦ä¹‹å¤–定义的函数ä»ç„¶æ€»æ˜¯åœ¨åˆçº¦çš„范围内执行。 + 它们ä»ç„¶å¯ä»¥è°ƒç”¨å…¶ä»–åˆçº¦ï¼Œå‘它们å‘é€ä»¥å¤ªï¼Œå¹¶é”€æ¯è°ƒç”¨å®ƒä»¬çš„åˆçº¦ï¼Œä»¥åŠå…¶ä»–一些事情。 + 与åˆçº¦å†…定义的函数的主è¦åŒºåˆ«æ˜¯ï¼Œè‡ªç”±å‡½æ•°ä¸èƒ½ç›´æŽ¥è®¿é—®å˜é‡ ``this``,存储å˜é‡å’Œä¸åœ¨å…¶èŒƒå›´å†…的函数。 .. _function-parameters-return-variables: -Function Parameters and Return Variables -======================================== +函数å‚数和返回å˜é‡ +==================== -Functions take typed parameters as input and may, unlike in many other -languages, also return an arbitrary number of values as output. +与许多其他语言ä¸åŒ, 函数接å—类型化的å‚数作为输入, +也å¯ä»¥è¿”回任æ„æ•°é‡çš„值作为输出。 -Function Parameters +函数å‚æ•° ------------------- -Function parameters are declared the same way as variables, and the name of -unused parameters can be omitted. +函数å‚数的声明方å¼ä¸Žå˜é‡ç›¸åŒï¼Œæœªä½¿ç”¨çš„å‚æ•°å称å¯ä»¥çœç•¥ã€‚ -For example, if you want your contract to accept one kind of external call -with two integers, you would use something like the following: +例如,如果您想让您的åˆçº¦æŽ¥å—一ç§å¸¦æœ‰ä¸¤ä¸ªæ•´æ•°çš„外部调用,您å¯ä»¥ä½¿ç”¨ç±»ä¼¼ä»¥ä¸‹çš„æ–¹å¼ï¼š .. code-block:: solidity @@ -70,18 +64,16 @@ with two integers, you would use something like the following: } } -Function parameters can be used as any other local variable and they can also be assigned to. +函数å‚æ•°å¯ä»¥åƒä»»ä½•å…¶ä»–局部å˜é‡ä¸€æ ·ä½¿ç”¨ï¼Œå®ƒä»¬ä¹Ÿå¯ä»¥è¢«èµ‹å€¼ã€‚ .. index:: return array, return string, array, string, array of strings, dynamic array, variably sized array, return struct, struct -Return Variables +返回的å˜é‡ ---------------- -Function return variables are declared with the same syntax after the -``returns`` keyword. +函数的返回å˜é‡åœ¨ ``returns`` 关键字之åŽç”¨åŒæ ·çš„语法声明。 -For example, suppose you want to return two results: the sum and the product of -two integers passed as function parameters, then you use something like: +例如,å‡è®¾æ‚¨æƒ³è¿”回两个结果:作为函数å‚数传递的两个整数的总和和乘积,那么您就使用类似的方法: .. code-block:: solidity @@ -99,16 +91,12 @@ two integers passed as function parameters, then you use something like: } } -The names of return variables can be omitted. -Return variables can be used as any other local variable and they -are initialized with their :ref:`default value ` and have that -value until they are (re-)assigned. +返回å˜é‡çš„åå­—å¯ä»¥è¢«çœç•¥ã€‚返回å˜é‡å¯ä»¥åƒå…¶ä»–本地å˜é‡ä¸€æ ·ä½¿ç”¨ï¼Œ +它们被åˆå§‹åŒ–为相应的 :ref:`默认值 `, +并且在它们被(é‡æ–°ï¼‰èµ‹å€¼ä¹‹å‰æ‹¥æœ‰è¿™ä¸ªå€¼ã€‚ -You can either explicitly assign to return variables and -then leave the function as above, -or you can provide return values -(either a single or :ref:`multiple ones`) directly with the ``return`` -statement: +您å¯ä»¥æ˜Žç¡®åœ°èµ‹å€¼ç»™è¿”回å˜é‡ï¼Œç„¶åŽåƒä¸Šé¢é‚£æ ·ç»“æŸå‡½æ•°ï¼Œ +或者您å¯ä»¥ç”¨ ``return`` 语å¥ç›´æŽ¥æ供返回值(å•ä¸ªæˆ– :ref:`多个返回值 `)。 .. code-block:: solidity @@ -125,63 +113,62 @@ statement: } } -If you use an early ``return`` to leave a function that has return variables, -you must provide return values together with the return statement. +如果您过早使用 ``return`` æ¥ç»“æŸä¸€ä¸ªæœ‰è¿”回å˜é‡çš„函数,您必须在返回语å¥ä¸­åŒæ—¶æ供返回值。 .. note:: - You cannot return some types from non-internal functions. - This includes the types listed below and any composite types that recursively contain them: + 您ä¸èƒ½ä»Žéžå†…部函数返回æŸäº›ç±»åž‹ã€‚ + 这包括下é¢åˆ—出的类型和任何递归地包å«å®ƒä»¬çš„å¤åˆç±»åž‹ï¼š - - mappings, - - internal function types, - - reference types with location set to ``storage``, - - multi-dimensional arrays (applies only to :ref:`ABI coder v1 `), - - structs (applies only to :ref:`ABI coder v1 `). + - 映射, + - 内部函数类型, + - å‚考类型,ä½ç½®è®¾ç½®ä¸º ``storage``, + - 多维数组(仅适用于 :ref:`ABI coder v1 `), + - 结构体(仅适用于 :ref:`ABI coder v1 `)。 - This restriction does not apply to library functions because of their different :ref:`internal ABI `. + 这个é™åˆ¶ä¸é€‚用于库函数,因为它们有ä¸åŒçš„ :ref:`内部 ABI `。 .. _multi-return: -Returning Multiple Values +返回多个值 ------------------------- -When a function has multiple return types, the statement ``return (v0, v1, ..., vn)`` can be used to return multiple values. -The number of components must be the same as the number of return variables -and their types have to match, potentially after an :ref:`implicit conversion `. +å½“ä¸€ä¸ªå‡½æ•°æœ‰å¤šä¸ªè¿”å›žç±»åž‹æ—¶ï¼Œè¯­å¥ ``return (v0, v1, ..., vn)`` å¯ä»¥ç”¨æ¥è¿”回多个值。 +声明的数é‡å¿…须与返回å˜é‡çš„æ•°é‡ç›¸åŒï¼Œå¹¶ä¸”它们的类型必须匹é…, +有å¯èƒ½æ˜¯ç»è¿‡ :ref:`éšå¼è½¬æ¢ `。 .. _state-mutability: -State Mutability +状æ€å¯å˜æ€§ ================ .. index:: ! view function, function;view .. _view-functions: -View Functions +View 函数 -------------- -Functions can be declared ``view`` in which case they promise not to modify the state. +函数å¯ä»¥è¢«å£°æ˜Žä¸º ``view``,在这ç§æƒ…况下,它们承诺ä¸ä¿®æ”¹çŠ¶æ€ã€‚ .. note:: - If the compiler's EVM target is Byzantium or newer (default) the opcode - ``STATICCALL`` is used when ``view`` functions are called, which enforces the state - to stay unmodified as part of the EVM execution. For library ``view`` functions - ``DELEGATECALL`` is used, because there is no combined ``DELEGATECALL`` and ``STATICCALL``. - This means library ``view`` functions do not have run-time checks that prevent state - modifications. This should not impact security negatively because library code is - usually known at compile-time and the static checker performs compile-time checks. - -The following statements are considered modifying the state: - -#. Writing to state variables. -#. :ref:`Emitting events `. -#. :ref:`Creating other contracts `. -#. Using ``selfdestruct``. -#. Sending Ether via calls. -#. Calling any function not marked ``view`` or ``pure``. -#. Using low-level calls. -#. Using inline assembly that contains certain opcodes. + 如果编译器的EVM版本是Byzantium或更新的(默认), + 当调用 ``view`` 函数时,会使用æ“ä½œç  ``STATICCALL``,这使得状æ€ä½œä¸ºEVM执行的一部分ä¿æŒä¸è¢«ä¿®æ”¹ã€‚ + 对于库åˆçº¦çš„ ``view`` 函数,会使用 ``DELEGATECALL``, + 因为没有组åˆçš„ ``DELEGATECALL`` å’Œ ``STATICCALL``。 + è¿™æ„味ç€åº“åˆçº¦ä¸­çš„ ``view`` 函数没有防止状æ€ä¿®æ”¹çš„è¿è¡Œæ—¶çš„检查。 + 这应该ä¸ä¼šå¯¹å®‰å…¨äº§ç”Ÿè´Ÿé¢å½±å“,因为库åˆçº¦çš„代ç é€šå¸¸åœ¨ç¼–译时就知é“了, + 而且é™æ€æ£€æŸ¥å™¨ä¹Ÿä¼šè¿›è¡Œç¼–译时检查。 + +以下声明被认为是修改状æ€ï¼š + +#. 修改状æ€å˜é‡ã€‚ +#. :ref:`产生事件 `。 +#. :ref:`创建其它åˆçº¦ `。 +#. 使用 ``selfdestruct``。 +#. 通过调用å‘é€ä»¥å¤ªå¸ã€‚ +#. 调用任何没有标记为 ``view`` 或者 ``pure`` 的函数。 +#. 使用低级调用。 +#. 使用包å«ç‰¹å®šæ“作ç çš„内è”汇编。 .. code-block:: solidity @@ -195,42 +182,38 @@ The following statements are considered modifying the state: } .. note:: - ``constant`` on functions used to be an alias to ``view``, but this was dropped in version 0.5.0. + 函数上的 ``constant`` 曾ç»æ˜¯ ``view`` 的别å,但在0.5.0版本中被å–消。 .. note:: - Getter methods are automatically marked ``view``. + Getter方法被自动标记为 ``view``。 .. note:: - Prior to version 0.5.0, the compiler did not use the ``STATICCALL`` opcode - for ``view`` functions. - This enabled state modifications in ``view`` functions through the use of - invalid explicit type conversions. - By using ``STATICCALL`` for ``view`` functions, modifications to the - state are prevented on the level of the EVM. + 在0.5.0版本之å‰ï¼Œç¼–译器没有为 ``view`` 函数使用 ``STATICCALL`` æ“作ç ã€‚ + 这使得 ``view`` 函数通过使用无效的显å¼ç±»åž‹è½¬æ¢è¿›è¡ŒçŠ¶æ€ä¿®æ”¹ã€‚ + 通过对 ``view`` 函数使用 ``STATICCALL``,在EVM层é¢ä¸Šé˜²æ­¢äº†å¯¹çŠ¶æ€çš„修改。 .. index:: ! pure function, function;pure .. _pure-functions: -Pure Functions +Pure 函数 -------------- -Functions can be declared ``pure`` in which case they promise not to read from or modify the state. -In particular, it should be possible to evaluate a ``pure`` function at compile-time given -only its inputs and ``msg.data``, but without any knowledge of the current blockchain state. -This means that reading from ``immutable`` variables can be a non-pure operation. +函数å¯ä»¥è¢«å£°æ˜Žä¸º ``pure``,在这ç§æƒ…况下,它们承诺ä¸è¯»å–或修改状æ€ã€‚ +特别是,应该å¯ä»¥åœ¨ç¼–译时评估一个 ``pure`` 函数,åªç»™å®ƒçš„输入和 ``msg.data``, +但ä¸çŸ¥é“当å‰åŒºå—链状æ€ã€‚è¿™æ„味ç€è¯»å– ``immutable`` çš„å˜é‡å¯ä»¥æ˜¯ä¸€ä¸ªéžæ ‡å‡†pureçš„æ“作。 .. note:: - If the compiler's EVM target is Byzantium or newer (default) the opcode ``STATICCALL`` is used, - which does not guarantee that the state is not read, but at least that it is not modified. + 如果编译器的EVM版本是Byzantium或更新的(默认),则使用æ“ä½œç  ``STATICCALL``, + 这并ä¸èƒ½ä¿è¯ä¸è¯»å–状æ€ï¼Œä½†è‡³å°‘ä¸èƒ½ä¿®æ”¹ã€‚ -In addition to the list of state modifying statements explained above, the following are considered reading from the state: +除了上é¢è§£é‡Šçš„状æ€ä¿®æ”¹è¯­å¥åˆ—表外,以下内容被认为是从状æ€ä¸­è¯»å–的: -#. Reading from state variables. -#. Accessing ``address(this).balance`` or ``
.balance``. -#. Accessing any of the members of ``block``, ``tx``, ``msg`` (with the exception of ``msg.sig`` and ``msg.data``). -#. Calling any function not marked ``pure``. -#. Using inline assembly that contains certain opcodes. +#. 读å–状æ€å˜é‡ã€‚ +#. 访问 ``address(this).balance`` 或者 ``
.balance``。 +#. 访问 ``block``, ``tx``, ``msg`` 中任æ„æˆå‘˜ (除 ``msg.sig`` å’Œ ``msg.data`` 之外)。 +#. 调用任何未标记为 ``pure`` 的函数。 +#. 使用包å«æŸäº›æ“作ç çš„内è”汇编。 .. code-block:: solidity @@ -243,105 +226,92 @@ In addition to the list of state modifying statements explained above, the follo } } -Pure functions are able to use the ``revert()`` and ``require()`` functions to revert -potential state changes when an :ref:`error occurs `. +当一个 :ref:`错误å‘生 ` 时, +Pure 函数能够使用 ``revert()`` å’Œ ``require()`` 函数æ¥æ¢å¤æ½œåœ¨çš„状æ€å˜åŒ–。 -Reverting a state change is not considered a "state modification", as only changes to the -state made previously in code that did not have the ``view`` or ``pure`` restriction -are reverted and that code has the option to catch the ``revert`` and not pass it on. +æ¢å¤ä¸€ä¸ªçŠ¶æ€å˜åŒ–ä¸è¢«è®¤ä¸ºæ˜¯ "状æ€ä¿®æ”¹", +因为åªæœ‰ä¹‹å‰åœ¨æ²¡æœ‰ ``view`` 或 ``pure`` é™åˆ¶çš„代ç ä¸­å¯¹çŠ¶æ€çš„改å˜æ‰ä¼šè¢«æ¢å¤ï¼Œ +并且该代ç å¯ä»¥é€‰æ‹©æ•æ‰ ``revert`` 而ä¸ä¼ é€’给它。 +<<<<<<< HEAD +è¿™ç§è¡Œä¸ºä¹Ÿä¸Ž ``STATICCALL`` æ“作ç ä¸€è‡´ã€‚ +======= This behavior is also in line with the ``STATICCALL`` opcode. +>>>>>>> english/develop .. warning:: - It is not possible to prevent functions from reading the state at the level - of the EVM, it is only possible to prevent them from writing to the state - (i.e. only ``view`` can be enforced at the EVM level, ``pure`` can not). + 在EVM层é¢ä¸å¯èƒ½é˜»æ­¢å‡½æ•°è¯»å–状æ€ï¼Œåªå¯èƒ½é˜»æ­¢å®ƒä»¬å†™å…¥çŠ¶æ€ + (å³åªæœ‰ ``view`` å¯ä»¥åœ¨EVM层é¢æ‰§è¡Œï¼Œ ``pure`` ä¸å¯ä»¥ï¼‰ã€‚ .. note:: - Prior to version 0.5.0, the compiler did not use the ``STATICCALL`` opcode - for ``pure`` functions. - This enabled state modifications in ``pure`` functions through the use of - invalid explicit type conversions. - By using ``STATICCALL`` for ``pure`` functions, modifications to the - state are prevented on the level of the EVM. + 在0.5.0版本之å‰ï¼Œç¼–译器没有为 ``pure`` 函数使用 ``STATICCALL`` æ“作ç ã€‚ + 这使得在 ``pure`` 函数中通过使用无效的显å¼ç±»åž‹è½¬æ¢è¿›è¡ŒçŠ¶æ€ä¿®æ”¹ã€‚ + 通过对 ``pure`` 函数使用 ``STATICCALL``,在EVM层é¢é˜²æ­¢äº†å¯¹çŠ¶æ€çš„修改。 .. note:: - Prior to version 0.4.17 the compiler did not enforce that ``pure`` is not reading the state. - It is a compile-time type check, which can be circumvented doing invalid explicit conversions - between contract types, because the compiler can verify that the type of the contract does - not do state-changing operations, but it cannot check that the contract that will be called - at runtime is actually of that type. + 在0.4.17版本之å‰ï¼Œç¼–译器并没有强制è¦æ±‚ ``pure`` ä¸è¯»å–状æ€ã€‚ + 这是一个编译时的类型检查,å¯ä»¥è§„é¿åœ¨åˆçº¦ç±»åž‹ä¹‹é—´åšæ— æ•ˆçš„显å¼è½¬æ¢ï¼Œ + 因为编译器å¯ä»¥éªŒè¯åˆçº¦çš„类型ä¸åšæ”¹å˜çŠ¶æ€çš„æ“作, + 但它ä¸èƒ½æ£€æŸ¥å°†åœ¨è¿è¡Œæ—¶è¢«è°ƒç”¨çš„åˆçº¦æ˜¯å¦çœŸçš„属于该类型。 .. _special-functions: -Special Functions +特殊的函数 ================= .. index:: ! receive ether function, function;receive, ! receive .. _receive-ether-function: -Receive Ether Function +接收以太的函数 ---------------------- -A contract can have at most one ``receive`` function, declared using -``receive() external payable { ... }`` -(without the ``function`` keyword). -This function cannot have arguments, cannot return anything and must have -``external`` visibility and ``payable`` state mutability. -It can be virtual, can override and can have modifiers. - -The receive function is executed on a -call to the contract with empty calldata. This is the function that is executed -on plain Ether transfers (e.g. via ``.send()`` or ``.transfer()``). If no such -function exists, but a payable :ref:`fallback function ` -exists, the fallback function will be called on a plain Ether transfer. If -neither a receive Ether nor a payable fallback function is present, the -contract cannot receive Ether through a transaction that does not represent a payable function call and throws an -exception. - -In the worst case, the ``receive`` function can only rely on 2300 gas being -available (for example when ``send`` or ``transfer`` is used), leaving little -room to perform other operations except basic logging. The following operations -will consume more gas than the 2300 gas stipend: - -- Writing to storage -- Creating a contract -- Calling an external function which consumes a large amount of gas -- Sending Ether +一个åˆçº¦æœ€å¤šå¯ä»¥æœ‰ä¸€ä¸ª ``receive`` 函数, +使用 ``receive() external payable { ... }`` æ¥å£°æ˜Žã€‚(没有 ``function`` 关键字)。 +这个函数ä¸èƒ½æœ‰å‚数,ä¸èƒ½è¿”回任何东西,必须具有 ``external`` çš„å¯è§æ€§å’Œ ``payable`` 的状æ€å¯å˜æ€§ã€‚ +它å¯ä»¥æ˜¯è™šæ‹Ÿçš„,å¯ä»¥é‡è½½ï¼Œä¹Ÿå¯ä»¥æœ‰ä¿®é¥°å™¨ã€‚ + +receive 函数是在调用åˆçº¦æ—¶æ‰§è¡Œçš„,并带有空的 calldata。 +这是在纯以太传输(例如通过 ``.send()`` 或 ``.transfer()`` )时执行的函数。 +如果ä¸å­˜åœ¨è¿™æ ·çš„函数,但存在一个 payable 类型的 :ref:`fallback函数 `, +这个 fallback 函数将在纯以太传输时被调用。 +如果既没有直接接收以太(receive函数),也没有 payable 类型的 fallback 函数, +那么åˆçº¦å°±ä¸èƒ½é€šè¿‡ä¸ä»£è¡¨æ”¯ä»˜å‡½æ•°è°ƒç”¨çš„交易接收以太å¸ï¼Œè¿˜ä¼šæŠ›å‡ºä¸€ä¸ªå¼‚常。 + +在最å的情况下, ``receive`` 函数åªæœ‰2300个气体å¯ç”¨ï¼ˆä¾‹å¦‚当使用 ``send`` 或 ``transfer`` 时), +除了基本的记录外,几乎没有空间æ¥æ‰§è¡Œå…¶ä»–æ“作。以下æ“作的消耗气体将超过2300气体的规定: + +- 写入存储 +- 创建åˆçº¦ +- è°ƒç”¨æ¶ˆè€—å¤§é‡ gas 的外部函数 +- å‘é€ä»¥å¤ªå¸ .. warning:: - When Ether is sent directly to a contract (without a function call, i.e. sender uses ``send`` or ``transfer``) - but the receiving contract does not define a receive Ether function or a payable fallback function, - an exception will be thrown, sending back the Ether (this was different - before Solidity v0.4.0). If you want your contract to receive Ether, - you have to implement a receive Ether function (using payable fallback functions for receiving Ether is - not recommended, since the fallback is invoked and would not fail for interface confusions - on the part of the sender). + 当以太被直接å‘é€åˆ°ä¸€ä¸ªåˆçº¦ï¼ˆæ²¡æœ‰ä½¿ç”¨å‡½æ•°è°ƒç”¨ï¼Œå³å‘é€è€…使用 ``send`` 或 ``transfer``), + 但接收åˆçº¦æ²¡æœ‰å®šä¹‰ä¸€ä¸ªæŽ¥æ”¶ä»¥å¤ªçš„函数或一个 payable 类型的 fallback 函数,会抛出一个异常, + 将以太é€å›žï¼ˆè¿™åœ¨Solidity v0.4.0之å‰æ˜¯ä¸åŒçš„)。因此,如果您想让您的åˆçº¦æŽ¥æ”¶ä»¥å¤ªï¼Œ + 您必须实现一个 receive 函数(ä¸å»ºè®®ä½¿ç”¨ payable 类型的 fallback 函数æ¥æŽ¥æ”¶ä»¥å¤ªï¼Œ + 因为它ä¸ä¼šå› ä¸ºæŽ¥å£æ··ä¹±è€Œå¤±è´¥ï¼‰ã€‚ .. warning:: - A contract without a receive Ether function can receive Ether as a - recipient of a *coinbase transaction* (aka *miner block reward*) - or as a destination of a ``selfdestruct``. + 没有接收以太å¸åŠŸèƒ½çš„åˆçº¦å¯ä»¥ä½œä¸º *coinbase交易*(åˆç§° *矿工区å—奖励*)的接收者 + 或作为 ``selfdestruct`` 的目的地接收以太å¸ã€‚ - A contract cannot react to such Ether transfers and thus also - cannot reject them. This is a design choice of the EVM and - Solidity cannot work around it. + åˆçº¦ä¸èƒ½å¯¹è¿™æ ·çš„以太å¸è½¬ç§»åšå‡ºå应,因此也ä¸èƒ½æ‹’ç»å®ƒä»¬ã€‚ + 这是EVM的一个设计选择,Solidity无法绕过它。 - It also means that ``address(this).balance`` can be higher - than the sum of some manual accounting implemented in a - contract (i.e. having a counter updated in the receive Ether function). + 这也æ„å‘³ç€ ``address(this).balance`` å¯ä»¥é«˜äºŽåˆçº¦ä¸­ + 实现的一些手工记å¸çš„总和(å³åœ¨æŽ¥æ”¶ä»¥å¤ªå‡½æ•°ä¸­æ›´æ–°çš„累加器)。 -Below you can see an example of a Sink contract that uses function ``receive``. +下é¢æ‚¨å¯ä»¥çœ‹åˆ°ä¸€ä¸ªä½¿ç”¨ ``receive`` 函数的Sinkåˆçº¦çš„例å­ã€‚ .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.6.0 <0.9.0; - // This contract keeps all Ether sent to it with no way - // to get it back. + // 这个åˆçº¦ä¼šä¿ç•™æ‰€æœ‰å‘é€ç»™å®ƒçš„以太å¸ï¼Œæ²¡æœ‰åŠžæ³•è¿”还。 contract Sink { event Received(address, uint); receive() external payable { @@ -353,48 +323,40 @@ Below you can see an example of a Sink contract that uses function ``receive``. .. _fallback-function: -Fallback Function +Fallback 函数 ----------------- -A contract can have at most one ``fallback`` function, declared using either ``fallback () external [payable]`` -or ``fallback (bytes calldata input) external [payable] returns (bytes memory output)`` -(both without the ``function`` keyword). -This function must have ``external`` visibility. A fallback function can be virtual, can override -and can have modifiers. +一个åˆçº¦æœ€å¤šå¯ä»¥æœ‰ä¸€ä¸ª ``fallback`` 函数,使用 ``fallback () external [payable]`` +或 ``fallback (bytes calldata input) external [payable] returns (bytes memory output)`` +æ¥å£°æ˜Žï¼ˆéƒ½æ²¡æœ‰ ``function`` 关键字)。 +这个函数必须具有 ``external`` 的函数å¯è§æ€§ã€‚ +一个 fallback 函数å¯ä»¥è¢«æ ‡è®°ä¸º virtual,å¯ä»¥æ ‡è®°ä¸º override,也å¯ä»¥æœ‰ä¿®é¥°å™¨ã€‚ -The fallback function is executed on a call to the contract if none of the other -functions match the given function signature, or if no data was supplied at -all and there is no :ref:`receive Ether function `. -The fallback function always receives data, but in order to also receive Ether -it must be marked ``payable``. +如果其他函数都ä¸ç¬¦åˆç»™å®šçš„函数签å,或者根本没有æ供数æ®ï¼Œ +也没有 :ref:`接收以太的函数 `,那么fallback函数将在调用åˆçº¦æ—¶æ‰§è¡Œã€‚ +fallback函数总是接收数æ®ï¼Œä½†ä¸ºäº†åŒæ—¶æŽ¥æ”¶ä»¥å¤ªï¼Œå®ƒå¿…须被标记为 ``payable``。 -If the version with parameters is used, ``input`` will contain the full data sent to the contract -(equal to ``msg.data``) and can return data in ``output``. The returned data will not be -ABI-encoded. Instead it will be returned without modifications (not even padding). +如果使用带å‚数的版本, ``input`` 将包å«å‘é€ç»™åˆçº¦çš„全部数æ®ï¼ˆç­‰äºŽ ``msg.data``), +并å¯ä»¥åœ¨ ``output`` 中返回数æ®ã€‚返回的数æ®å°†ä¸ä¼šè¢«ABIç¼–ç ã€‚ +相å,它将在没有修改的情况下返回(甚至没有填充)。 -In the worst case, if a payable fallback function is also used in -place of a receive function, it can only rely on 2300 gas being -available (see :ref:`receive Ether function ` -for a brief description of the implications of this). +在最å的情况下,如果一个å¯æŽ¥æ”¶ä»¥å¤ªçš„fallback函数也被用æ¥ä»£æ›¿æŽ¥æ”¶åŠŸèƒ½ï¼Œ +那么它åªæœ‰2300气体是å¯ç”¨çš„ +(å‚è§ :ref:`接收以太函数 ` 对这一å«ä¹‰çš„简è¦æ述)。 -Like any function, the fallback function can execute complex -operations as long as there is enough gas passed on to it. +åƒä»»ä½•å‡½æ•°ä¸€æ ·ï¼Œåªè¦æœ‰è¶³å¤Ÿçš„气体传递给它,fallback函数就å¯ä»¥æ‰§è¡Œå¤æ‚çš„æ“作。 .. warning:: - A ``payable`` fallback function is also executed for - plain Ether transfers, if no :ref:`receive Ether function ` - is present. It is recommended to always define a receive Ether - function as well, if you define a payable fallback function - to distinguish Ether transfers from interface confusions. + 如果没有 :ref:`receive 函数 ` 的存在, + 一个标记为 ``payable`` çš„ fallback 函数也会在普通的以太传输时执行。 + 如果您已ç»å®šä¹‰äº†ä¸€ä¸ª payable 类型的 fallback 函数, + 我们ä»å»ºè®®æ‚¨ä¹Ÿå®šä¹‰ä¸€ä¸ª receive 函数接收以太,以区分以太传输和接å£æ··æ·†çš„情况。 .. note:: - If you want to decode the input data, you can check the first four bytes - for the function selector and then - you can use ``abi.decode`` together with the array slice syntax to - decode ABI-encoded data: + 如果您想对输入数æ®è¿›è¡Œè§£ç ï¼Œæ‚¨å¯ä»¥æ£€æŸ¥å‰å››ä¸ªå­—节的函数选择器, + 然åŽæ‚¨å¯ä»¥ä½¿ç”¨ ``abi.decode`` 与数组切片语法一起对ABIç¼–ç çš„æ•°æ®è¿›è¡Œè§£ç ï¼š ``(c, d) = abi.decode(input[4:], (uint256, uint256));`` - Note that this should only be used as a last resort and - proper functions should be used instead. + 注æ„,这åªèƒ½ä½œä¸ºæœ€åŽçš„手段,应该使用适当的函数æ¥ä»£æ›¿ã€‚ .. code-block:: solidity @@ -404,26 +366,22 @@ operations as long as there is enough gas passed on to it. contract Test { uint x; - // This function is called for all messages sent to - // this contract (there is no other function). - // Sending Ether to this contract will cause an exception, - // because the fallback function does not have the `payable` - // modifier. + // 所有å‘é€åˆ°æ­¤åˆçº¦çš„消æ¯éƒ½ä¼šè°ƒç”¨æ­¤å‡½æ•°ï¼ˆæ²¡æœ‰å…¶ä»–函数)。 + // å‘该åˆçº¦å‘é€ä»¥å¤ªå¸å°†å¼•èµ·å¼‚常, + // 因为fallback函数没有 `payable` 修饰器。 fallback() external { x = 1; } } contract TestPayable { uint x; uint y; - // This function is called for all messages sent to - // this contract, except plain Ether transfers - // (there is no other function except the receive function). - // Any call with non-empty calldata to this contract will execute - // the fallback function (even if Ether is sent along with the call). + // 所有å‘é€åˆ°æ­¤åˆçº¦çš„消æ¯éƒ½ä¼šè°ƒç”¨è¿™ä¸ªå‡½æ•°ï¼Œ + // 除了普通的以太传输(除了receive函数,没有其他函数)。 + // 任何对该åˆçº¦çš„éžç©ºçš„调用都将执行fallback函数(å³ä½¿ä»¥å¤ªä¸Žè°ƒç”¨ä¸€èµ·è¢«å‘é€ï¼‰ã€‚ fallback() external payable { x = 1; y = msg.value; } - // This function is called for plain Ether transfers, i.e. - // for every call with empty calldata. + // 这个函数是为纯以太传输而调用的, + // å³ä¸ºæ¯ä¸€ä¸ªå¸¦æœ‰ç©ºcalldata的调用。 receive() external payable { x = 2; y = msg.value; } } @@ -431,32 +389,31 @@ operations as long as there is enough gas passed on to it. function callTest(Test test) public returns (bool) { (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()")); require(success); - // results in test.x becoming == 1. + // 结果是 test.x 等于 1。 - // address(test) will not allow to call ``send`` directly, since ``test`` has no payable - // fallback function. - // It has to be converted to the ``address payable`` type to even allow calling ``send`` on it. + // address(test)å°†ä¸å…许直接调用 ``send``, + // 因为 ``test`` 没有å¯æŽ¥æ”¶ä»¥å¤ªçš„fallback函数。 + // 它必须被转æ¢ä¸º ``address payable`` 类型,æ‰å…许调用 ``send``。 address payable testPayable = payable(address(test)); - // If someone sends Ether to that contract, - // the transfer will fail, i.e. this returns false here. + // 如果有人å‘该åˆçº¦å‘é€ä»¥å¤ªå¸ï¼Œè½¬è´¦å°†å¤±è´¥ï¼Œå³è¿™é‡Œè¿”回false。 return testPayable.send(2 ether); } function callTestPayable(TestPayable test) public returns (bool) { (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()")); require(success); - // results in test.x becoming == 1 and test.y becoming 0. + // 结果是 test.x 等于 1,test.y 等于 0。 (success,) = address(test).call{value: 1}(abi.encodeWithSignature("nonExistingFunction()")); require(success); - // results in test.x becoming == 1 and test.y becoming 1. + // 结果是 test.x 等于 1,test.y 等于 1。 - // If someone sends Ether to that contract, the receive function in TestPayable will be called. - // Since that function writes to storage, it takes more gas than is available with a - // simple ``send`` or ``transfer``. Because of that, we have to use a low-level call. + // 如果有人å‘该åˆçº¦å‘é€ä»¥å¤ªå¸ï¼ŒTestPayableçš„receive函数将被调用。 + // 由于该函数会写入存储空间,它需è¦çš„气体比简å•çš„ ``send`` 或 ``transfer`` è¦å¤šã€‚ + // 由于这个原因,我们必须è¦ä½¿ç”¨ä¸€ä¸ªä½Žçº§åˆ«çš„调用。 (success,) = address(test).call{value: 2 ether}(""); require(success); - // results in test.x becoming == 2 and test.y becoming 2 ether. + // 结果是 test.x 等于 1,test.y 等于 2 个以太。 return true; } @@ -466,14 +423,12 @@ operations as long as there is enough gas passed on to it. .. _overload-function: -Function Overloading +函数é‡è½½ ==================== -A contract can have multiple functions of the same name but with different parameter -types. -This process is called "overloading" and also applies to inherited functions. -The following example shows overloading of the function -``f`` in the scope of contract ``A``. +一个åˆçº¦å¯ä»¥æœ‰å¤šä¸ªåŒå的,但å‚数类型ä¸åŒçš„函数。 +这个过程被称为 "é‡è½½",也适用于继承的函数。 +下é¢çš„例å­æ˜¾ç¤ºäº†åœ¨åˆçº¦ ``A`` 范围内对函数 ``f`` çš„é‡è½½ã€‚ .. code-block:: solidity @@ -491,15 +446,14 @@ The following example shows overloading of the function } } -Overloaded functions are also present in the external interface. It is an error if two -externally visible functions differ by their Solidity types but not by their external types. +é‡è½½å‡½æ•°ä¹Ÿå­˜åœ¨äºŽå¤–部接å£ä¸­ã€‚如果两个外部å¯è§å‡½æ•°ä»…区别于 Solidity 内的类型而ä¸æ˜¯å®ƒä»¬çš„外部类型则会导致错误。 .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.16 <0.9.0; - // This will not compile + // 这段代ç ä¸ä¼šç¼–译 contract A { function f(B value) public pure returns (B out) { out = value; @@ -514,19 +468,17 @@ externally visible functions differ by their Solidity types but not by their ext } -Both ``f`` function overloads above end up accepting the address type for the ABI although -they are considered different inside Solidity. +以上两个 ``f`` 函数é‡è½½æœ€ç»ˆéƒ½æŽ¥å—ABI的地å€ç±»åž‹ï¼Œå°½ç®¡å®ƒä»¬åœ¨Solidity中被认为是ä¸åŒçš„。 -Overload resolution and Argument matching +é‡è½½è§£æžå’Œå‚æ•°åŒ¹é… ----------------------------------------- -Overloaded functions are selected by matching the function declarations in the current scope -to the arguments supplied in the function call. Functions are selected as overload candidates -if all arguments can be implicitly converted to the expected types. If there is not exactly one -candidate, resolution fails. +通过将当å‰èŒƒå›´å†…的函数声明与函数调用中æ供的å‚数相匹é…,å¯ä»¥é€‰æ‹©é‡è½½å‡½æ•°ã€‚ +如果所有å‚数都å¯ä»¥éšå¼åœ°è½¬æ¢ä¸ºé¢„期类型,则选择函数作为é‡è½½å€™é€‰é¡¹ã€‚ +如果一个候选都没有,解æžå¤±è´¥ã€‚ .. note:: - Return parameters are not taken into account for overload resolution. + 返回å‚æ•°ä¸ä½œä¸ºé‡è½½è§£æžçš„ä¾æ®ã€‚ .. code-block:: solidity @@ -543,6 +495,6 @@ candidate, resolution fails. } } -Calling ``f(50)`` would create a type error since ``50`` can be implicitly converted both to ``uint8`` -and ``uint256`` types. On another hand ``f(256)`` would resolve to ``f(uint256)`` overload as ``256`` cannot be implicitly -converted to ``uint8``. +调用 ``f(50)`` 会导致类型错误,因为 ``50`` æ—¢å¯ä»¥è¢«éšå¼è½¬æ¢ä¸º ``uint8`` +也å¯ä»¥è¢«éšå¼è½¬æ¢ä¸º ``uint256``。 å¦ä¸€æ–¹é¢ï¼Œè°ƒç”¨ ``f(256)`` 则会解æžä¸º ``f(uint256)`` é‡è½½ï¼Œ +因为 ``256`` ä¸èƒ½éšå¼è½¬æ¢ä¸º ``uint8``。 diff --git a/docs/contracts/inheritance.rst b/docs/contracts/inheritance.rst index c787c5af6a90..4cd34dfc1ee8 100644 --- a/docs/contracts/inheritance.rst +++ b/docs/contracts/inheritance.rst @@ -1,221 +1,352 @@ .. index:: ! inheritance, ! base class, ! contract;base, ! deriving *********** -Inheritance +继承 *********** -Solidity supports multiple inheritance including polymorphism. +Solidity支æŒå¤šé‡ç»§æ‰¿ï¼ŒåŒ…括多æ€æ€§ã€‚ -Polymorphism means that a function call (internal and external) -always executes the function of the same name (and parameter types) -in the most derived contract in the inheritance hierarchy. -This has to be explicitly enabled on each function in the -hierarchy using the ``virtual`` and ``override`` keywords. -See :ref:`Function Overriding ` for more details. +多æ€æ€§æ„味ç€å‡½æ•°è°ƒç”¨ï¼ˆå†…部和外部)总是执行继承层次结构中最新继承的åˆçº¦ä¸­çš„åŒå函数(和å‚数类型)。 +但必须使用 ``virtual`` å’Œ ``override`` 关键字在层次结构中的æ¯ä¸ªå‡½æ•°ä¸Šæ˜Žç¡®å¯ç”¨ã€‚ +å‚è§ :ref:`函数é‡è½½ ` 以了解更多细节。 -It is possible to call functions further up in the inheritance -hierarchy internally by explicitly specifying the contract -using ``ContractName.functionName()`` or using ``super.functionName()`` -if you want to call the function one level higher up in -the flattened inheritance hierarchy (see below). +通过使用 ``ContractName.functionName()`` 明确指定åˆçº¦ï¼Œ +å¯ä»¥åœ¨å†…部调用继承层次结构中更高的函数。 +或者如果您想在æ‰å¹³åŒ–的继承层次中调用高一级的函数(è§ä¸‹æ–‡ï¼‰ï¼Œ +å¯ä»¥ä½¿ç”¨ ``super.functionName()``。 -When a contract inherits from other contracts, only a single -contract is created on the blockchain, and the code from all the base contracts -is compiled into the created contract. This means that all internal calls -to functions of base contracts also just use internal function calls -(``super.f(..)`` will use JUMP and not a message call). +当一个åˆçº¦ç»§æ‰¿è‡ªå…¶ä»–åˆçº¦æ—¶ï¼Œåœ¨åŒºå—链上åªåˆ›å»ºä¸€ä¸ªå•ä¸€çš„åˆçº¦ï¼Œ +所有基础åˆçº¦çš„代ç è¢«ç¼–译到创建的åˆçº¦ä¸­ã€‚ +è¿™æ„味ç€å¯¹åŸºç¡€åˆçº¦çš„所有内部函数的调用也åªæ˜¯ä½¿ç”¨å†…部函数调用 +( ``super.f(..)`` 将使用 JUMP 而ä¸æ˜¯æ¶ˆæ¯è°ƒç”¨ï¼‰ã€‚ -State variable shadowing is considered as an error. A derived contract can -only declare a state variable ``x``, if there is no visible state variable -with the same name in any of its bases. +状æ€å˜é‡çš„阴影被认为是一个错误。 +一个派生åˆçº¦åªèƒ½å£°æ˜Žä¸€ä¸ªçŠ¶æ€å˜é‡ ``x``, +如果在它的任何基类中没有相åŒå称的å¯è§çŠ¶æ€å˜é‡ã€‚ -The general inheritance system is very similar to -`Python's `_, -especially concerning multiple inheritance, but there are also -some :ref:`differences `. +总的æ¥è¯´ï¼ŒSolidity 的继承系统与 `Python的继承系统 `_ +éžå¸¸ç›¸ä¼¼ï¼Œç‰¹åˆ«æ˜¯å…³äºŽå¤šé‡ç»§æ‰¿æ–¹é¢ï¼Œä½†ä¹Ÿæœ‰ä¸€äº› :ref:`ä¸åŒä¹‹å¤„ `。 -Details are given in the following example. +详细情况è§ä¸‹é¢çš„例å­ã€‚ .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; - // This will report a warning due to deprecated selfdestruct +<<<<<<< HEAD + // 这将报告一个由于废弃的 selfdestruct 而产生的警告 + +======= +>>>>>>> english/develop contract Owned { - constructor() { owner = payable(msg.sender); } address payable owner; + constructor() { owner = payable(msg.sender); } + } + +<<<<<<< HEAD + + // 使用 `is` 从å¦ä¸€ä¸ªåˆçº¦æ´¾ç”Ÿã€‚派生åˆçº¦å¯ä»¥è®¿é—®æ‰€æœ‰éžç§æœ‰æˆå‘˜ï¼Œ + // 包括内部函数和状æ€å˜é‡ï¼Œä½†æ— æ³•é€šè¿‡ `this` æ¥å¤–部访问。 + contract Destructible is Owned { + // 关键字 `virtual` æ„味ç€è¯¥å‡½æ•°å¯ä»¥åœ¨æ´¾ç”Ÿç±»ä¸­æ”¹å˜å…¶è¡Œä¸ºï¼ˆ"é‡è½½")。 + function destroy() virtual public { + if (msg.sender == owner) selfdestruct(owner); + } } + // 这些抽象åˆçº¦ä»…用于给编译器æ供接å£ã€‚ + // 注æ„函数没有函数体。 + // 如果一个åˆçº¦æ²¡æœ‰å®žçŽ°æ‰€æœ‰å‡½æ•°ï¼Œåˆ™åªèƒ½ç”¨ä½œæŽ¥å£ã€‚ +======= // 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 Destructible is Owned { + contract Emittable is Owned { + event Emitted(); + // The keyword `virtual` means that the function can change // its behavior in derived classes ("overriding"). - function destroy() virtual public { - if (msg.sender == owner) selfdestruct(owner); + 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 `Destructible`, yet there is only a single + // 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, Destructible { + contract Named is Owned, Emittable { +>>>>>>> english/develop constructor(bytes32 name) { Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970); NameReg(config.lookup(1)).register(name); } +<<<<<<< HEAD + // 函数å¯ä»¥è¢«å¦ä¸€ä¸ªå…·æœ‰ç›¸åŒå称和相åŒæ•°é‡/类型输入的函数é‡è½½ã€‚ + // 如果é‡è½½å‡½æ•°æœ‰ä¸åŒç±»åž‹çš„输出å‚数,会导致错误。 + // 本地和基于消æ¯çš„函数调用都会考虑这些é‡è½½ã€‚ + // 如果您想é‡è½½è¿™ä¸ªå‡½æ•°ï¼Œæ‚¨éœ€è¦ä½¿ç”¨ `override` 关键字。 + // 如果您想让这个函数å†æ¬¡è¢«é‡è½½ï¼Œæ‚¨éœ€è¦å†æŒ‡å®š `virtual` 关键字。 + function destroy() public virtual override { + if (msg.sender == owner) { + Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970); + 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 + // 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 destroy() public virtual override { + 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. - Destructible.destroy(); + 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, Destructible, Named("GoldFeed") { + 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 `destroy` anymore. - function destroy() public override(Destructible, Named) { Named.destroy(); } + // 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; } -Note that above, we call ``Destructible.destroy()`` to "forward" the -destruction request. The way this is done is problematic, as +<<<<<<< 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; - // This will report a warning due to deprecated selfdestruct +<<<<<<< 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 { /* do cleanup 1 */ Destructible.destroy(); } + function destroy() public virtual override { /* 清除æ“作 1 */ Destructible.destroy(); } } contract Base2 is Destructible { - function destroy() public virtual override { /* do cleanup 2 */ Destructible.destroy(); } + 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(); + } } -A call to ``Final.destroy()`` will call ``Base2.destroy`` because we specify it +<<<<<<< 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.destroy``. The way around this is to use ``super``: +``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; - // This will report a warning due to deprecated selfdestruct +<<<<<<< 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 { /* do cleanup 1 */ super.destroy(); } + function destroy() public virtual override { /* 清除æ“作 1 */ super.destroy(); } } contract Base2 is Destructible { - function destroy() public virtual override { /* do cleanup 2 */ super.destroy(); } + 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(); + } } -If ``Base2`` calls a function of ``super``, it does not simply +<<<<<<< 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.destroy()`` (note that +inheritance graph, so it will call ``Base1.emitEvent()`` (note that the final inheritance sequence is -- starting with the most -derived contract: Final, Base2, Base1, Destructible, owned). +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 .. _function-overriding: -Function Overriding +函数é‡è½½ =================== -Base functions can be overridden by inheriting contracts to change their -behavior if they are marked as ``virtual``. The overriding function must then -use the ``override`` keyword in the function header. -The overriding function may only change the visibility of the overridden function from ``external`` to ``public``. -The mutability may be changed to a more strict one following the order: -``nonpayable`` can be overridden by ``view`` and ``pure``. ``view`` can be overridden by ``pure``. -``payable`` is an exception and cannot be changed to any other mutability. +如果基函数被标记为 ``virtual``,则å¯ä»¥é€šè¿‡ç»§æ‰¿åˆçº¦æ¥æ”¹å˜å…¶è¡Œä¸ºã€‚ +被é‡è½½çš„函数必须在函数头中使用 ``override`` 关键字。 +é‡è½½å‡½æ•°åªèƒ½å°†è¢«é‡è½½å‡½æ•°çš„å¯è§æ€§ä»Ž ``external`` 改为 ``public``。 +å¯å˜æ€§å¯ä»¥æŒ‰ç…§ä»¥ä¸‹é¡ºåºæ”¹å˜ä¸ºæ›´ä¸¥æ ¼çš„å¯å˜æ€§ã€‚ +``nonpayable`` å¯ä»¥è¢« ``view`` å’Œ ``pure`` é‡è½½ã€‚ +``view`` å¯ä»¥è¢« ``pure`` é‡å†™ã€‚ ``payable`` 是一个例外,ä¸èƒ½è¢«æ”¹å˜ä¸ºä»»ä½•å…¶ä»–å¯å˜æ€§ã€‚ -The following example demonstrates changing mutability and visibility: +下é¢çš„例å­æ¼”示了改å˜å‡½æ•°å¯å˜æ€§å’Œå¯è§æ€§ï¼š .. code-block:: solidity @@ -234,12 +365,10 @@ The following example demonstrates changing mutability and visibility: function foo() override public pure {} } -For multiple inheritance, the most derived base contracts that define the same -function must be specified explicitly after the ``override`` keyword. -In other words, you have to specify all base contracts that define the same function -and have not yet been overridden by another base contract (on some path through the inheritance graph). -Additionally, if a contract inherits the same function from multiple (unrelated) -bases, it has to explicitly override it: +对于多é‡ç»§æ‰¿ï¼Œå¿…须在 ``override`` 关键字åŽæ˜Žç¡®æŒ‡å®šå®šä¹‰åŒä¸€å‡½æ•°çš„最多派生基类åˆçº¦ã€‚ +æ¢å¥è¯è¯´ï¼Œæ‚¨å¿…须指定所有定义åŒä¸€å‡½æ•°çš„基类åˆçº¦ï¼Œ +并且还没有被å¦ä¸€ä¸ªåŸºç±»åˆçº¦é‡è½½ï¼ˆåœ¨ç»§æ‰¿å›¾çš„æŸä¸ªè·¯å¾„上)。 +此外,如果一个åˆçº¦ä»Žå¤šä¸ªï¼ˆä¸ç›¸å…³çš„)基类åˆçº¦ä¸Šç»§æ‰¿äº†åŒä¸€ä¸ªå‡½æ•°ï¼Œå¿…须明确地é‡è½½å®ƒã€‚ .. code-block:: solidity @@ -258,15 +387,14 @@ bases, it has to explicitly override it: contract Inherited is Base1, Base2 { - // Derives from multiple bases defining foo(), so we must explicitly - // override it + // 派生自多个定义 foo() 函数的基类åˆçº¦ï¼Œ + // 所以我们必须明确地é‡è½½å®ƒ function foo() public override(Base1, Base2) {} } -An explicit override specifier is not required if -the function is defined in a common base contract -or if there is a unique function in a common base contract -that already overrides all other functions. +如果函数被定义在一个共åŒçš„基类åˆçº¦ä¸­ï¼Œ +或者在一个共åŒçš„基类åˆçº¦ä¸­æœ‰ä¸€ä¸ªç‹¬ç‰¹çš„函数已ç»é‡è½½äº†æ‰€æœ‰å…¶ä»–的函数, +则ä¸éœ€è¦æ˜Žç¡®çš„函数é‡è½½æŒ‡å®šç¬¦ã€‚ .. code-block:: solidity @@ -276,45 +404,41 @@ that already overrides all other functions. contract A { function f() public pure{} } contract B is A {} contract C is A {} - // No explicit override required + // 无需明确的é‡è½½ contract D is B, C {} -More formally, it is not required to override a function (directly or -indirectly) inherited from multiple bases if there is a base contract -that is part of all override paths for the signature, and (1) that -base implements the function and no paths from the current contract -to the base mentions a function with that signature or (2) that base -does not implement the function and there is at most one mention of -the function in all paths from the current contract to that base. +更准确地说,如果有一个基类åˆçº¦æ˜¯è¯¥ç­¾å的所有é‡è½½è·¯å¾„的一部分, +并且(1)该基类åˆçº¦å®žçŽ°äº†è¯¥å‡½æ•°ï¼Œå¹¶ä¸”从当å‰åˆçº¦åˆ°è¯¥åŸºç±»åˆçº¦çš„任何路径都没有æ到具有该签å的函数, +或者(2)该基类åˆçº¦æ²¡æœ‰å®žçŽ°è¯¥å‡½æ•°ï¼Œå¹¶ä¸”从当å‰åˆçº¦åˆ°è¯¥åŸºç±»åˆçº¦çš„所有路径中最多åªæœ‰ä¸€ä¸ªæ到该函数, +那么就ä¸éœ€è¦é‡è½½ä»Žå¤šä¸ªåŸºç±»åˆçº¦ç»§æ‰¿çš„函数(直接或间接)。 -In this sense, an override path for a signature is a path through -the inheritance graph that starts at the contract under consideration -and ends at a contract mentioning a function with that signature -that does not override. +在这个æ„义上,一个签åçš„é‡è½½è·¯å¾„是一æ¡ç»§æ‰¿å›¾çš„路径, +它从所考虑的åˆçº¦å¼€å§‹ï¼Œåˆ°æ到具有该签å的函数的åˆçº¦ç»“æŸï¼Œ +而该签å没有é‡è½½ã€‚ +<<<<<<< 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:: - Functions with the ``private`` visibility cannot be ``virtual``. + 具有 ``private`` å¯è§æ€§çš„函数ä¸èƒ½æ˜¯ ``virtual``。 .. note:: - Functions without implementation have to be marked ``virtual`` - outside of interfaces. In interfaces, all functions are - automatically considered ``virtual``. + 在接å£åˆçº¦ä¹‹å¤–,没有实现的函数必须被标记为 ``virtual``。 + 在接å£åˆçº¦ä¸­ï¼Œæ‰€æœ‰çš„函数都被自动视为 ``virtual``。 .. note:: - Starting from Solidity 0.8.8, the ``override`` keyword is not - required when overriding an interface function, except for the - case where the function is defined in multiple bases. + 从Solidity 0.8.8开始,当é‡è½½ä¸€ä¸ªæŽ¥å£å‡½æ•°æ—¶ï¼Œ + ä¸éœ€è¦ ``override`` 关键字,除éžè¯¥å‡½æ•°è¢«å®šä¹‰åœ¨å¤šä¸ªåŸºç¡€ä¸Šã€‚ -Public state variables can override external functions if the -parameter and return types of the function matches the getter function -of the variable: +如果函数的å‚数和返回类型与å˜é‡çš„getter函数匹é…,公共状æ€å˜é‡å¯ä»¥é‡è½½ä¸ºå¤–部函数。 .. code-block:: solidity @@ -333,20 +457,18 @@ of the variable: .. note:: - While public state variables can override external functions, they themselves cannot - be overridden. + 虽然公共状æ€å˜é‡å¯ä»¥é‡è½½å¤–部函数,但它们本身ä¸èƒ½è¢«é‡è½½ã€‚ .. index:: ! overriding;modifier .. _modifier-overriding: -Modifier Overriding +修饰器é‡è½½ =================== -Function modifiers can override each other. This works in the same way as -:ref:`function overriding ` (except that there is no overloading for modifiers). The -``virtual`` keyword must be used on the overridden modifier -and the ``override`` keyword must be used in the overriding modifier: +函数修改器å¯ä»¥ç›¸äº’é‡è½½ã€‚ +这与 :ref:`函数é‡è½½ ` 的工作方å¼ç›¸åŒï¼ˆé™¤äº†å¯¹ä¿®æ”¹å™¨æ²¡æœ‰é‡è½½ï¼‰ã€‚ +``virtual`` 关键字必须用在被é‡è½½çš„修改器上, ``override`` 关键字必须用在é‡è½½çš„修改器上: .. code-block:: solidity @@ -364,8 +486,7 @@ and the ``override`` keyword must be used in the overriding modifier: } -In case of multiple inheritance, all direct base contracts must be specified -explicitly: +在多é‡ç»§æ‰¿çš„情况下,必须明确指定所有的直接基类åˆçº¦ã€‚ .. code-block:: solidity @@ -393,27 +514,28 @@ explicitly: .. _constructor: -Constructors +构造函数 ============ +<<<<<<< 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 -initialisation code. +initialization code. +>>>>>>> english/develop -Before the constructor code is executed, state variables are initialised to -their specified value if you initialise them inline, or their :ref:`default value` if you do not. +在构造函数代ç æ‰§è¡Œä¹‹å‰ï¼Œå¦‚果您用内è”编程的方å¼åˆå§‹åŒ–状æ€å˜é‡ï¼Œåˆ™å°†å…¶åˆå§‹åŒ–为指定的值; +如果您ä¸ç”¨å†…è”编程的方å¼æ¥åˆå§‹åŒ–,则将其åˆå§‹åŒ–为 :ref:`默认值 `。 -After the constructor has run, the final code of the contract is deployed -to the blockchain. The deployment of -the code costs additional gas linear to the length of the code. -This code includes all functions that are part of the public interface -and all functions that are reachable from there through function calls. -It does not include the constructor code or internal functions that are -only called from the constructor. +构造函数è¿è¡ŒåŽï¼Œåˆçº¦çš„最终代ç è¢«éƒ¨ç½²åˆ°åŒºå—链上。 +部署代ç çš„gas花费与代ç é•¿åº¦æˆçº¿æ€§å…³ç³»ã€‚ +这段代ç åŒ…括属于公共接å£çš„所有函数,以åŠæ‰€æœ‰é€šè¿‡å‡½æ•°è°ƒç”¨å¯ä»¥åˆ°è¾¾çš„函数。 +但ä¸åŒ…括构造函数代ç æˆ–åªä»Žæž„造函数中调用的内部函数。 -If there is no -constructor, the contract will assume the default constructor, which is -equivalent to ``constructor() {}``. For example: +如果没有构造函数,åˆçº¦å°†å‡å®šé»˜è®¤çš„构造函数, +相当于 ``constructor() {}``。比如说: .. code-block:: solidity @@ -432,27 +554,27 @@ equivalent to ``constructor() {}``. For example: constructor() {} } -You can use internal parameters in a constructor (for example storage pointers). In this case, -the contract has to be marked :ref:`abstract `, because these parameters -cannot be assigned valid values from outside but only through the constructors of derived contracts. +您å¯ä»¥åœ¨æž„造函数中使用内部å‚数(例如,存储指针)。 +在这ç§æƒ…况下,åˆçº¦å¿…须被标记为 :ref:`abstract `, +因为这些å‚æ•°ä¸èƒ½ä»Žå¤–部分é…有效的值,åªèƒ½é€šè¿‡æ´¾ç”Ÿåˆçº¦çš„构造函数æ¥èµ‹å€¼ã€‚ + .. warning:: - Prior to version 0.4.22, constructors were defined as functions with the same name as the contract. - This syntax was deprecated and is not allowed anymore in version 0.5.0. + 在0.4.22版本之å‰ï¼Œæž„造函数被定义为与åˆçº¦åŒå的函数。 + è¿™ç§è¯­æ³•å·²è¢«åºŸå¼ƒï¼Œåœ¨0.5.0版本中ä¸å†å…许。 .. warning:: - Prior to version 0.7.0, you had to specify the visibility of constructors as either - ``internal`` or ``public``. + 在0.7.0版本之å‰ï¼Œæ‚¨å¿…须指定构造函数的å¯è§æ€§ä¸º ``internal`` 或 ``public``。 .. index:: ! base;constructor, inheritance list, contract;abstract, abstract contract -Arguments for Base Constructors +基本构造函数的å‚æ•° =============================== -The constructors of all the base contracts will be called following the -linearization rules explained below. If the base constructors have arguments, -derived contracts need to specify all of them. This can be done in two ways: +所有基类åˆçº¦çš„构造函数将按照下é¢è§£é‡Šçš„线性化规则被调用。 +如果基类åˆçº¦æž„造函数有å‚数,派生åˆçº¦éœ€è¦æŒ‡å®šæ‰€æœ‰çš„å‚数。 +è¿™å¯ä»¥é€šè¿‡ä¸¤ç§æ–¹å¼å®žçŽ°ï¼š .. code-block:: solidity @@ -464,25 +586,33 @@ derived contracts need to specify all of them. This can be done in two ways: constructor(uint x_) { x = x_; } } - // Either directly specify in the inheritance list... + // è¦ä¹ˆç›´æŽ¥åœ¨ç»§æ‰¿åˆ—表中指定... contract Derived1 is Base(7) { constructor() {} } - // or through a "modifier" of the derived constructor... + // 或者通过派生构造函数的一个 "修改器"…… contract Derived2 is Base { constructor(uint y) Base(y * y) {} } - // or declare abstract... + // 或者将åˆçº¦å£°æ˜Žä¸ºabstract类型…… abstract contract Derived3 is Base { } - // and have the next concrete derived contract initialize it. + // 并让下一个具体的派生åˆçº¦å¯¹å…¶è¿›è¡Œåˆå§‹åŒ–。 contract DerivedFromDerived is Derived3 { constructor() Base(10 + 10) {} } +<<<<<<< HEAD +一ç§æ–¹å¼æ˜¯ç›´æŽ¥åœ¨ç»§æ‰¿åˆ—表中给出( ``is Base(7)`` )。 +å¦ä¸€ç§æ˜¯é€šè¿‡ä¿®æ”¹å™¨ä½œä¸ºæ´¾ç”Ÿæž„造函数的一部分被调用的方å¼ï¼ˆ ``Base(_y * _y)`` )。 +如果构造函数å‚数是一个常é‡ï¼Œå¹¶ä¸”定义了åˆçº¦çš„行为或æ述了它,那么第一ç§æ–¹å¼æ›´æ–¹ä¾¿ã€‚ +如果基类åˆçº¦çš„构造函数å‚æ•°ä¾èµ–于派生åˆçº¦çš„å‚数,则必须使用第二ç§æ–¹å¼ã€‚ +å‚数必须在继承列表中或在派生构造函数中以修饰器的形å¼ç»™å‡ºã€‚ +在两个地方都指定å‚数是一个错误。 +======= 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 @@ -493,40 +623,34 @@ 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 -If a derived contract does not specify the arguments to all of its base -contracts' constructors, it must be declared abstract. In that case, when -another contract derives from it, that other contract's inheritance list -or constructor must provide the necessary parameters -for all base classes that haven't had their parameters specified (otherwise, -that other contract must be declared abstract as well). For example, in the above -code snippet, see ``Derived3`` and ``DerivedFromDerived``. +如果一个派生åˆçº¦æ²¡æœ‰æŒ‡å®šå…¶æ‰€æœ‰åŸºç±»åˆçº¦çš„构造函数的å‚数,那么它必须被声明为 abstract 类型。在这ç§æƒ…况下, +当å¦ä¸€ä¸ªåˆçº¦ä»Žå®ƒæ´¾ç”Ÿæ—¶ï¼Œå…¶ä»–åˆçº¦çš„继承列表或构造函数必须为所有没有指定å‚数的基类åˆçº¦æ供必è¦çš„å‚æ•° +(å¦åˆ™ï¼Œå…¶ä»–åˆçº¦ä¹Ÿå¿…须被声明为 abstract 类型)。例如,在上é¢çš„代ç ç‰‡æ®µä¸­ï¼Œ +å¯ä»¥æŸ¥çœ‹åˆçº¦ ``Derived3`` å’Œ ``DerivedFromDerived``。 .. index:: ! inheritance;multiple, ! linearization, ! C3 linearization .. _multi-inheritance: -Multiple Inheritance and Linearization +多é‡ç»§æ‰¿ä¸Žçº¿æ€§åŒ– ====================================== -Languages that allow multiple inheritance have to deal with -several problems. One is the `Diamond Problem `_. -Solidity is similar to Python in that it uses "`C3 Linearization `_" -to force a specific order in the directed acyclic graph (DAG) of base classes. This -results in the desirable property of monotonicity but -disallows some inheritance graphs. Especially, the order in -which the base classes are given in the ``is`` directive is -important: You have to list the direct base contracts -in the order from "most base-like" to "most derived". -Note that this order is the reverse of the one used in Python. - -Another simplifying way to explain this is that when a function is called that -is defined multiple times in different contracts, the given bases -are searched from right to left (left to right in Python) in a depth-first manner, -stopping at the first match. If a base contract has already been searched, it is skipped. - -In the following code, Solidity will give the -error "Linearization of inheritance graph impossible". +编程语言实现多é‡ç»§æ‰¿éœ€è¦è§£å†³å‡ ä¸ªé—®é¢˜ã€‚ +一个问题是 `钻石问题 `_ 。 +Solidity 借鉴了 Python çš„æ–¹å¼å¹¶ä¸”使用 "`C3 线性化 `_" +强制一个由基类构æˆçš„ DAG(有å‘无环图)ä¿æŒä¸€ä¸ªç‰¹å®šçš„顺åºã€‚ +这最终实现我们所希望的唯一化的结果,但也使æŸäº›ç»§æ‰¿æ–¹å¼å˜ä¸ºæ— æ•ˆã€‚ +尤其是,基类在 ``is`` åŽé¢çš„顺åºå¾ˆé‡è¦ã€‚ 在下é¢çš„代ç ä¸­ï¼Œ +您必须按照从 “最接近的基类â€ï¼ˆmost base-like)到 “最远的继承â€ï¼ˆmost derived)的顺åºæ¥æŒ‡å®šæ‰€æœ‰çš„基类。 +注æ„,这个顺åºä¸ŽPython中使用的顺åºç›¸å。 + +å¦ä¸€ç§ç®€åŒ–的解释方å¼æ˜¯ï¼Œå½“一个函数被调用时, +它在ä¸åŒçš„åˆçº¦ä¸­è¢«å¤šæ¬¡å®šä¹‰ï¼Œç»™å®šçš„基类以深度优先的方å¼ä»Žå³åˆ°å·¦ï¼ˆPython中从左到å³ï¼‰è¿›è¡Œæœç´¢ï¼Œ +在第一个匹é…处åœæ­¢ã€‚如果一个基类åˆçº¦å·²ç»è¢«æœç´¢è¿‡äº†ï¼Œå®ƒå°±è¢«è·³è¿‡ã€‚ + +在下é¢çš„代ç ä¸­ï¼ŒSolidity 会给出 “Linearization of inheritance graph impossible†这样的错误。 .. code-block:: solidity @@ -535,19 +659,18 @@ error "Linearization of inheritance graph impossible". contract X {} contract A is X {} - // This will not compile + // 这段代ç ä¸ä¼šç¼–译 contract C is A, X {} -The reason for this is that ``C`` requests ``X`` to override ``A`` -(by specifying ``A, X`` in this order), but ``A`` itself -requests to override ``X``, which is a contradiction that -cannot be resolved. +代ç ç¼–译出错的原因是 ``C`` è¦æ±‚ ``X`` é‡å†™ ``A`` +(因为定义的顺åºæ˜¯ ``A, X`` ), 但是 ``A`` 本身è¦æ±‚é‡å†™ ``X``, +这是一ç§æ— æ³•è§£å†³çš„冲çªã€‚ -Due to the fact that you have to explicitly override a function -that is inherited from multiple bases without a unique override, -C3 linearization is not too important in practice. +由于您必须明确地é‡è½½ä¸€ä¸ªä»Žå¤šä¸ªåŸºç±»åˆçº¦ç»§æ‰¿çš„函数, +而没有唯一的é‡è½½ï¼ŒC3线性化在实践中ä¸æ˜¯å¤ªé‡è¦ã€‚ -One area where inheritance linearization is especially important and perhaps not as clear is when there are multiple constructors in the inheritance hierarchy. The constructors will always be executed in the linearized order, regardless of the order in which their arguments are provided in the inheriting contract's constructor. For example: +继承的线性化特别é‡è¦çš„一个领域是,当继承层次中存在多个构造函数时,也许ä¸é‚£ä¹ˆæ¸…楚。 +构造函数将总是按照线性化的顺åºæ‰§è¡Œï¼Œè€Œä¸ç®¡å®ƒä»¬çš„å‚数在继承åˆçº¦çš„构造函数中是以何ç§é¡ºåºæ供的。 比如说: .. code-block:: solidity @@ -562,7 +685,7 @@ One area where inheritance linearization is especially important and perhaps not constructor() {} } - // Constructors are executed in the following order: + // 构造函数按以下顺åºæ‰§è¡Œï¼š // 1 - Base1 // 2 - Base2 // 3 - Derived1 @@ -570,7 +693,7 @@ One area where inheritance linearization is especially important and perhaps not constructor() Base1() Base2() {} } - // Constructors are executed in the following order: + // 构造函数按以下顺åºæ‰§è¡Œï¼š // 1 - Base2 // 2 - Base1 // 3 - Derived2 @@ -578,7 +701,7 @@ One area where inheritance linearization is especially important and perhaps not constructor() Base2() Base1() {} } - // Constructors are still executed in the following order: + // 构造函数ä»æŒ‰ä»¥ä¸‹é¡ºåºæ‰§è¡Œï¼š // 1 - Base2 // 2 - Base1 // 3 - Derived3 @@ -587,9 +710,17 @@ One area where inheritance linearization is especially important and perhaps not } -Inheriting Different Kinds of Members of the Same Name +继承有相åŒåå­—çš„ä¸åŒç±»åž‹æˆå‘˜ ====================================================== +<<<<<<< HEAD +由于继承的原因,当åˆçº¦æœ‰ä»¥ä¸‹ä»»ä½•ä¸€å¯¹å…·æœ‰ç›¸åŒçš„å称时,这是一个错误: + - 函数和修饰器 + - 函数和事件 + - 事件和修饰器 + +有一ç§ä¾‹å¤–情况,状æ€å˜é‡çš„ getter å¯ä»¥é‡è½½ä¸€ä¸ªå¤–部函数。 +======= The only situations where, due to inheritance, a contract may contain multiple definitions sharing the same name are: @@ -598,3 +729,4 @@ the same name are: - Overriding of external virtual functions by state variable getters. - Overriding of virtual modifiers. - Overloading of events. +>>>>>>> english/develop diff --git a/docs/contracts/interfaces.rst b/docs/contracts/interfaces.rst index a3085667b7f4..472be69f72a7 100644 --- a/docs/contracts/interfaces.rst +++ b/docs/contracts/interfaces.rst @@ -2,25 +2,24 @@ .. _interfaces: -********** -Interfaces -********** +********************** +接å£ï¼ˆinterface)åˆçº¦ +********************** -Interfaces are similar to abstract contracts, but they cannot have any functions implemented. -There are further restrictions: +接å£ï¼ˆinterface)åˆçº¦ç±»ä¼¼äºŽæŠ½è±¡ï¼ˆabstract)åˆçº¦ï¼Œä½†æ˜¯å®ƒä»¬ä¸èƒ½å®žçŽ°ä»»ä½•å‡½æ•°ã€‚并且还有进一步的é™åˆ¶ï¼š -- They cannot inherit from other contracts, but they can inherit from other interfaces. -- All declared functions must be external in the interface, even if they are public in the contract. -- They cannot declare a constructor. -- They cannot declare state variables. -- They cannot declare modifiers. +- 它们ä¸èƒ½ç»§æ‰¿å…¶ä»–åˆçº¦ï¼Œä½†æ˜¯å®ƒä»¬å¯ä»¥ç»§æ‰¿å…¶ä»–接å£åˆçº¦ã€‚ +- 在接å£åˆçº¦ä¸­æ‰€æœ‰å£°æ˜Žçš„函数必须是 external 类型的,å³ä½¿å®ƒä»¬åœ¨åˆçº¦ä¸­æ˜¯ public 类型的。 +- 它们ä¸èƒ½å£°æ˜Žæž„造函数。 +- 它们ä¸èƒ½å£°æ˜ŽçŠ¶æ€å˜é‡ã€‚ +- 它们ä¸èƒ½å£°æ˜Žä¿®é¥°å™¨ã€‚ -Some of these restrictions might be lifted in the future. +å°†æ¥å¯èƒ½ä¼šè§£é™¤è¿™äº›é‡Œçš„æŸäº›é™åˆ¶ã€‚ -Interfaces are basically limited to what the Contract ABI can represent, and the conversion between the ABI and -an interface should be possible without any information loss. +接å£åˆçº¦åŸºæœ¬ä¸Šä»…é™äºŽåˆçº¦ ABI å¯ä»¥è¡¨ç¤ºçš„内容, +并且 ABI 和接å£åˆçº¦ä¹‹é—´çš„转æ¢åº”该ä¸ä¼šä¸¢å¤±ä»»ä½•ä¿¡æ¯ã€‚ -Interfaces are denoted by their own keyword: +接å£åˆçº¦ç”±å®ƒä»¬è‡ªå·±çš„关键字表示: .. code-block:: solidity @@ -33,15 +32,13 @@ Interfaces are denoted by their own keyword: function transfer(address recipient, uint amount) external; } -Contracts can inherit interfaces as they would inherit other contracts. +å°±åƒç»§æ‰¿å…¶ä»–åˆçº¦ä¸€æ ·ï¼Œåˆçº¦å¯ä»¥ç»§æ‰¿æŽ¥å£åˆçº¦ã€‚ -All functions declared in interfaces are implicitly ``virtual`` and any -functions that override them do not need the ``override`` keyword. -This does not automatically mean that an overriding function can be overridden again - -this is only possible if the overriding function is marked ``virtual``. +所有在接å£åˆçº¦ä¸­å£°æ˜Žçš„函数都是éšå¼çš„ ``virtual`` 的类型, +任何é‡è½½å®ƒä»¬çš„函数都ä¸éœ€è¦ ``override`` 关键字。 +这并ä¸è‡ªåŠ¨æ„味ç€ä¸€ä¸ªé‡è½½çš„函数å¯ä»¥è¢«å†æ¬¡é‡è½½--è¿™åªæœ‰åœ¨é‡è½½çš„函数被标记为 ``virtual`` æ—¶æ‰å¯èƒ½ã€‚ -Interfaces can inherit from other interfaces. This has the same rules as normal -inheritance. +接å£åˆçº¦å¯ä»¥ä»Žå…¶ä»–接å£åˆçº¦ç»§æ‰¿ã€‚这与普通的继承有ç€ç›¸åŒçš„规则。 .. code-block:: solidity @@ -57,15 +54,17 @@ inheritance. } interface SubInterface is ParentA, ParentB { - // Must redefine test in order to assert that the parent - // meanings are compatible. + // å¿…é¡»é‡æ–°å®šä¹‰test,以便断言父类的å«ä¹‰æ˜¯å…¼å®¹çš„。 function test() external override(ParentA, ParentB) returns (uint256); } -Types defined inside interfaces and other contract-like structures -can be accessed from other contracts: ``Token.TokenType`` or ``Token.Coin``. +在接å£åˆçº¦å’Œå…¶ä»–类似åˆçº¦çš„结构中定义的类型å¯ä»¥ä»Žå…¶ä»–åˆçº¦ä¸­è®¿é—®ï¼š ``Token.TokenType`` 或 ``Token.Coin``。 +<<<<<<< HEAD +.. 警告: +======= .. warning:: +>>>>>>> english/develop - Interfaces have supported ``enum`` types since :doc:`Solidity version 0.5.0 <050-breaking-changes>`, make - sure the pragma version specifies this version as a minimum. + 接å£åˆçº¦ä»Ž :doc:`Solidity 0.5.0 <050-breaking-changes>` å¼€å§‹æ”¯æŒ ``enum`` 类型, + 请确ä¿pragma版本至少指定这个版本。 diff --git a/docs/contracts/libraries.rst b/docs/contracts/libraries.rst index 7256ebe0315a..46def7309022 100644 --- a/docs/contracts/libraries.rst +++ b/docs/contracts/libraries.rst @@ -3,53 +3,40 @@ .. _libraries: ********* -Libraries +库åˆçº¦ ********* -Libraries are similar to contracts, but their purpose is that they are deployed -only once at a specific address and their code is reused using the ``DELEGATECALL`` -(``CALLCODE`` until Homestead) -feature of the EVM. This means that if library functions are called, their code -is executed in the context of the calling contract, i.e. ``this`` points to the -calling contract, and especially the storage from the calling contract can be -accessed. As a library is an isolated piece of source code, it can only access -state variables of the calling contract if they are explicitly supplied (it -would have no way to name them, otherwise). Library functions can only be -called directly (i.e. without the use of ``DELEGATECALL``) if they do not modify -the state (i.e. if they are ``view`` or ``pure`` functions), -because libraries are assumed to be stateless. In particular, it is -not possible to destroy a library. +库åˆçº¦ä¸Žæ™®é€šåˆçº¦ç±»ä¼¼ï¼Œä½†æ˜¯å®ƒä»¬åªéœ€è¦åœ¨ç‰¹å®šçš„地å€éƒ¨ç½²ä¸€æ¬¡ï¼Œ +并且它们的代ç å¯ä»¥é€šè¿‡ EVM çš„ ``DELEGATECALL`` (Homestead 之å‰ä½¿ç”¨ ``CALLCODE`` 关键字)特性进行é‡ç”¨ã€‚ +è¿™æ„味ç€å¦‚果库函数被调用,它的代ç åœ¨è°ƒç”¨åˆçº¦çš„上下文中执行, +å³ ``this`` 指å‘调用åˆçº¦ï¼Œç‰¹åˆ«æ˜¯å¯ä»¥è®¿é—®è°ƒç”¨åˆçº¦çš„存储。 +因为æ¯ä¸ªåº“åˆçº¦éƒ½æ˜¯ä¸€æ®µç‹¬ç«‹çš„代ç ï¼Œæ‰€ä»¥å®ƒä»…能访问调用åˆçº¦æ˜Žç¡®æ供的状æ€å˜é‡ï¼ˆå¦åˆ™å®ƒå°±æ— æ³•é€šè¿‡å字访问这些å˜é‡ï¼‰ã€‚ +如果库函数ä¸ä¿®æ”¹çŠ¶æ€ï¼ˆä¹Ÿå°±æ˜¯è¯´ï¼Œå¦‚果它们是 ``view`` 或者 ``pure`` 函数), +它们å¯ä»¥é€šè¿‡ç›´æŽ¥è°ƒç”¨æ¥ä½¿ç”¨ï¼ˆå³ä¸ä½¿ç”¨ ``DELEGATECALL`` 关键字), +这是因为我们å‡å®šåº“åˆçº¦æ˜¯æ— çŠ¶æ€çš„。 +特别的是,销æ¯ä¸€ä¸ªåº“åˆçº¦æ˜¯ä¸å¯èƒ½çš„。 .. note:: - Until version 0.4.20, it was possible to destroy libraries by - circumventing Solidity's type system. Starting from that version, - libraries contain a :ref:`mechanism` that - disallows state-modifying functions - to be called directly (i.e. without ``DELEGATECALL``). - -Libraries can be seen as implicit base contracts of the contracts that use them. -They will not be explicitly visible in the inheritance hierarchy, but calls -to library functions look just like calls to functions of explicit base -contracts (using qualified access like ``L.f()``). -Of course, calls to internal functions -use the internal calling convention, which means that all internal types -can be passed and types :ref:`stored in memory ` will be passed by reference and not copied. -To realize this in the EVM, the code of internal library functions -that are called from a contract -and all functions called from therein will at compile time be included in the calling -contract, and a regular ``JUMP`` call will be used instead of a ``DELEGATECALL``. + 在0.4.20版本之å‰ï¼Œæœ‰å¯èƒ½é€šè¿‡è§„é¿Solidity的类型系统æ¥ç ´å库åˆçº¦ã€‚ + 从该版本开始,库åˆçº¦åŒ…å«ä¸€ä¸ª :ref:`ä¿æŠ¤æœºåˆ¶ `, + ä¸å…许直接调用修改状æ€çš„函数(å³æ²¡æœ‰ ``DELEGATECALL`` )。 + +库åˆçº¦å¯ä»¥çœ‹ä½œæ˜¯ä½¿ç”¨ä»–们的åˆçº¦çš„éšå¼çš„基类åˆçº¦ã€‚ +虽然它们在继承关系中ä¸ä¼šæ˜¾å¼å¯è§ï¼Œä½†è°ƒç”¨åº“函数与调用显å¼çš„基类åˆçº¦å分类似 +(如果 ``L`` 是库åˆçº¦çš„è¯ï¼Œå¯ä»¥ä½¿ç”¨ ``L.f()`` 调用库函数)。 +当然,需è¦ä½¿ç”¨å†…部调用约定æ¥è°ƒç”¨å†…部函数,这æ„味ç€æ‰€æœ‰çš„内部类型都å¯ä»¥è¢«ä¼ é€’, +类型 :ref:`存储在内存 ` 将被引用传递而ä¸æ˜¯å¤åˆ¶ã€‚ +为了在EVM中实现这一点,从åˆçº¦ä¸­è°ƒç”¨çš„内部库函数的代ç å’Œå…¶ä¸­è°ƒç”¨çš„所有函数将在编译时包å«åœ¨è°ƒç”¨åˆçº¦ä¸­ï¼Œ +并使用常规的 ``JUMP`` 调用,而ä¸æ˜¯ ``DELEGATECALL``。 .. note:: - The inheritance analogy breaks down when it comes to public functions. - Calling a public library function with ``L.f()`` results in an external call (``DELEGATECALL`` - to be precise). - In contrast, ``A.f()`` is an internal call when ``A`` is a base contract of the current contract. + 当涉åŠåˆ°å…¬å…±å‡½æ•°æ—¶ï¼Œç»§æ‰¿çš„类比就失效了。 + 用 ``L.f()`` 调用公共库函数的结果是一个外部调用(准确地说,是 ``DELEGATECALL`` )。 + 相å,当 ``A.f()`` 是当å‰åˆçº¦çš„基类åˆçº¦æ—¶ï¼Œ ``A.f()`` 是一个内部调用。 .. index:: using for, set -The following example illustrates how to use libraries (but using a manual method, -be sure to check out :ref:`using for ` for a -more advanced example to implement a set). +下é¢çš„示例说明如何使用库(但也请务必看看 :ref:`using for ` 有一个实现 set 更好的例å­ï¼‰ã€‚ .. code-block:: solidity @@ -57,25 +44,22 @@ more advanced example to implement a set). pragma solidity >=0.6.0 <0.9.0; - // We define a new struct datatype that will be used to - // hold its data in the calling contract. + // 我们定义了一个新的结构体数æ®ç±»åž‹ï¼Œç”¨äºŽåœ¨è°ƒç”¨åˆçº¦ä¸­ä¿å­˜æ•°æ®ã€‚ struct Data { mapping(uint => bool) flags; } library Set { - // Note that the first parameter is of type "storage - // reference" and thus only its storage address and not - // its contents is passed as part of the call. This is a - // special feature of library functions. It is idiomatic - // to call the first parameter `self`, if the function can - // be seen as a method of that object. + // 注æ„第一个å‚数是 “storage referenceâ€ç±»åž‹ï¼Œ + // 因此在调用中å‚数传递的åªæ˜¯å®ƒçš„存储地å€è€Œä¸æ˜¯å†…容。 + // 这是库函数的一个特性。如果该函数å¯ä»¥è¢«è§†ä¸ºå¯¹è±¡çš„方法, + // 则习惯称第一个å‚数为 `self` 。 function insert(Data storage self, uint value) public returns (bool) { if (self.flags[value]) - return false; // already there + return false; // å·²ç»å­˜åœ¨ self.flags[value] = true; return true; } @@ -85,7 +69,7 @@ more advanced example to implement a set). returns (bool) { if (!self.flags[value]) - return false; // not there + return false; // ä¸å­˜åœ¨ self.flags[value] = false; return true; } @@ -104,31 +88,23 @@ more advanced example to implement a set). Data knownValues; function register(uint value) public { - // The library functions can be called without a - // specific instance of the library, since the - // "instance" will be the current contract. + // ä¸éœ€è¦åº“的特定实例就å¯ä»¥è°ƒç”¨åº“函数, + // 因为当å‰åˆçº¦å°±æ˜¯ “instanceâ€ã€‚ require(Set.insert(knownValues, value)); } - // In this contract, we can also directly access knownValues.flags, if we want. + // 如果我们愿æ„,我们也å¯ä»¥åœ¨è¿™ä¸ªåˆçº¦ä¸­ç›´æŽ¥è®¿é—® knownValues.flags。 } -Of course, you do not have to follow this way to use -libraries: they can also be used without defining struct -data types. Functions also work without any storage -reference parameters, and they can have multiple storage reference -parameters and in any position. +当然,您ä¸å¿…按照这ç§æ–¹å¼åŽ»ä½¿ç”¨åº“:它们也å¯ä»¥åœ¨ä¸å®šä¹‰ç»“æž„æ•°æ®ç±»åž‹çš„情况下使用。 +函数也ä¸éœ€è¦ä»»ä½•å­˜å‚¨å¼•ç”¨å‚数,库å¯ä»¥å‡ºçŽ°åœ¨ä»»ä½•ä½ç½®å¹¶ä¸”å¯ä»¥æœ‰å¤šä¸ªå­˜å‚¨å¼•ç”¨å‚数。 -The calls to ``Set.contains``, ``Set.insert`` and ``Set.remove`` -are all compiled as calls (``DELEGATECALL``) to an external -contract/library. If you use libraries, be aware that an -actual external function call is performed. -``msg.sender``, ``msg.value`` and ``this`` will retain their values -in this call, though (prior to Homestead, because of the use of ``CALLCODE``, ``msg.sender`` and -``msg.value`` changed, though). +调用 ``Set.contains``, ``Set.insert`` å’Œ ``Set.remove`` 都被编译为对外部åˆçº¦/库的调用( ``DELEGATECALL`` )。 +如果使用库,请注æ„实际执行的是外部函数调用。 +``msg.sender``, ``msg.value`` å’Œ ``this`` 在调用中将ä¿ç•™å®ƒä»¬çš„值, +(在 Homestead 之å‰ï¼Œå› ä¸ºä½¿ç”¨äº† ``CALLCODE`` ,改å˜äº† ``msg.sender`` å’Œ ``msg.value``)。 -The following example shows how to use :ref:`types stored in memory ` and -internal functions in libraries in order to implement -custom types without the overhead of external function calls: +下é¢çš„例å­æ˜¾ç¤ºäº†å¦‚何使用 :ref:`存储在内存中的类型 ` 和库åˆçº¦ä¸­çš„内部函数, +以实现自定义类型,而没有外部函数调用的开销: .. code-block:: solidity :force: @@ -162,7 +138,7 @@ custom types without the overhead of external function calls: } } if (carry > 0) { - // too bad, we have to add a limb + // 太差了,我们需è¦å¢žåŠ ä¸€ä¸ª limb uint[] memory newLimbs = new uint[](r.limbs.length + 1); uint i; for (i = 0; i < r.limbs.length; ++i) @@ -192,56 +168,52 @@ custom types without the overhead of external function calls: } } -It is possible to obtain the address of a library by converting -the library type to the ``address`` type, i.e. using ``address(LibraryName)``. +通过将库åˆçº¦çš„类型转æ¢ä¸º ``address`` 类型,å³ä½¿ç”¨ ``address(LibraryName)``,å¯ä»¥èŽ·å¾—一个库的地å€ã€‚ -As the compiler does not know the address where the library will be deployed, the compiled hex code -will contain placeholders of the form ``__$30bbc0abd4d6364515865950d3e0d10953$__``. The placeholder -is a 34 character prefix of the hex encoding of the keccak256 hash of the fully qualified library -name, which would be for example ``libraries/bigint.sol:BigInt`` if the library was stored in a file -called ``bigint.sol`` in a ``libraries/`` directory. Such bytecode is incomplete and should not be -deployed. Placeholders need to be replaced with actual addresses. You can do that by either passing -them to the compiler when the library is being compiled or by using the linker to update an already -compiled binary. See :ref:`library-linking` for information on how to use the commandline compiler -for linking. +由于编译器ä¸çŸ¥é“库åˆçº¦çš„部署地å€ï¼Œ +编译åŽçš„å六进制代ç å°†åŒ…å« ``__$30bbc0abd4d6364515865950d3e0d10953$__`` å½¢å¼çš„å ä½ç¬¦ã€‚ +å ä½ç¬¦æ˜¯å®Œå…¨ç­‰åŒäºŽåº“åˆçº¦åçš„keccak256哈希值的34个字符的å‰ç¼€ï¼Œä¾‹å¦‚ ``libraries/bigint.sol:BigInt``, +如果该库存储在 ``libraries/`` 目录下一个å为 ``bigint.sol`` 的文件中。 +这样的字节ç æ˜¯ä¸å®Œæ•´çš„,ä¸åº”该被部署。å ä½ç¬¦éœ€è¦è¢«æ›¿æ¢æˆå®žé™…地å€ã€‚ +您å¯ä»¥åœ¨ç¼–译库的时候把它们传递给编译器,或者用链接器æ¥æ›´æ–°å·²ç»ç¼–译好的二进制文件。 +å‚è§ :ref:`library-linking`,了解如何使用命令行编译器进行链接。 -In comparison to contracts, libraries are restricted in the following ways: +与åˆçº¦ç›¸æ¯”,库在以下方é¢å—到é™åˆ¶ï¼š -- they cannot have state variables -- they cannot inherit nor be inherited -- they cannot receive Ether -- they cannot be destroyed +- 它们ä¸èƒ½æœ‰çŠ¶æ€å˜é‡ +- 它们ä¸èƒ½ç»§æ‰¿ï¼Œä¹Ÿä¸èƒ½è¢«ç»§æ‰¿ +- 它们ä¸èƒ½æŽ¥æ”¶ä»¥å¤ª +- 它们ä¸èƒ½è¢«é”€æ¯ -(These might be lifted at a later point.) +(这些å¯èƒ½ä¼šåœ¨ä»¥åŽçš„时间里被解除)。 .. _library-selectors: .. index:: ! selector; of a library function -Function Signatures and Selectors in Libraries +库åˆçº¦ä¸­çš„函数签å和选择器 ============================================== -While external calls to public or external library functions are possible, the calling convention for such calls -is considered to be internal to Solidity and not the same as specified for the regular :ref:`contract ABI`. -External library functions support more argument types than external contract functions, for example recursive structs -and storage pointers. For that reason, the function signatures used to compute the 4-byte selector are computed -following an internal naming schema and arguments of types not supported in the contract ABI use an internal encoding. +虽然对公共或外部库函数的外部调用是å¯èƒ½çš„,但这ç§è°ƒç”¨çš„调用惯例被认为是 Solidity 内部的, +与常规 :ref:`åˆçº¦ ABI ` 所指定的ä¸ä¸€æ ·ã€‚ +外部库函数比外部åˆçº¦å‡½æ•°æ”¯æŒæ›´å¤šçš„å‚数类型,例如递归结构和存储指针。 +由于这个原因,用于计算4字节选择器的函数签å是按照内部命å模å¼è®¡ç®—的, +åˆçº¦ABI中ä¸æ”¯æŒçš„类型的å‚数使用内部编ç ã€‚ -The following identifiers are used for the types in the signatures: +ç­¾å中的类型使用了以下标识符: -- Value types, non-storage ``string`` and non-storage ``bytes`` use the same identifiers as in the contract ABI. -- Non-storage array types follow the same convention as in the contract ABI, i.e. ``[]`` for dynamic arrays and - ``[M]`` for fixed-size arrays of ``M`` elements. -- Non-storage structs are referred to by their fully qualified name, i.e. ``C.S`` for ``contract C { struct S { ... } }``. -- Storage pointer mappings use ``mapping( => ) storage`` where ```` and ```` are - the identifiers for the key and value types of the mapping, respectively. -- Other storage pointer types use the type identifier of their corresponding non-storage type, but append a single space - followed by ``storage`` to it. +- 值类型ã€éžå­˜å‚¨çš„ ``string`` å’Œéžå­˜å‚¨çš„ ``bytes`` 使用与åˆçº¦ABI中相åŒçš„标识符。 +- éžå­˜å‚¨æ•°ç»„类型éµå¾ªä¸Žåˆçº¦ABI中相åŒçš„æƒ¯ä¾‹ï¼Œå³ ``[]`` 用于动æ€æ•°ç»„, + ``[M]`` 用于 ``M`` 元素的固定大å°æ•°ç»„。 +- éžå­˜å‚¨ç»“构体用其完全等åŒäºŽçš„å称æ¥æŒ‡ä»£ï¼Œå³ ``C.S`` 代表 ``contract C { struct S { ... } }``。 +- 存储指针映射使用 ``mapping( => ) storage``, + 其中 ```` å’Œ ```` 分别是映射的键和值类型的标识。 +- 其他存储指针类型使用其对应的éžå­˜å‚¨ç±»åž‹çš„类型标识符,但在其åŽé¢é™„åŠ ä¸€ä¸ªç©ºæ ¼ï¼Œå³ ``storage``。 -The argument encoding is the same as for the regular contract ABI, except for storage pointers, which are encoded as a -``uint256`` value referring to the storage slot to which they point. +å‚æ•°çš„ç¼–ç ä¸Žæ™®é€šåˆçº¦ABI相åŒï¼Œé™¤äº†å­˜å‚¨æŒ‡é’ˆï¼Œ +它被编ç ä¸ºä¸€ä¸ª ``uint256`` 值,指的是它们所指å‘的存储槽。 -Similarly to the contract ABI, the selector consists of the first four bytes of the Keccak256-hash of the signature. -Its value can be obtained from Solidity using the ``.selector`` member as follows: +与åˆçº¦ABI类似,选择器由签åçš„Keccak256-hashçš„å‰å››ä¸ªå­—节组æˆã€‚ +它的值å¯ä»¥é€šè¿‡ä½¿ç”¨ ``.selector`` æˆå‘˜ä»Ž Solidity 获得,如下: .. code-block:: solidity @@ -262,30 +234,21 @@ Its value can be obtained from Solidity using the ``.selector`` member as follow .. _call-protection: -Call Protection For Libraries +库的调用ä¿æŠ¤ ============================= -As mentioned in the introduction, if a library's code is executed -using a ``CALL`` instead of a ``DELEGATECALL`` or ``CALLCODE``, -it will revert unless a ``view`` or ``pure`` function is called. - -The EVM does not provide a direct way for a contract to detect -whether it was called using ``CALL`` or not, but a contract -can use the ``ADDRESS`` opcode to find out "where" it is -currently running. The generated code compares this address -to the address used at construction time to determine the mode -of calling. - -More specifically, the runtime code of a library always starts -with a push instruction, which is a zero of 20 bytes at -compilation time. When the deploy code runs, this constant -is replaced in memory by the current address and this -modified code is stored in the contract. At runtime, -this causes the deploy time address to be the first -constant to be pushed onto the stack and the dispatcher -code compares the current address against this constant -for any non-view and non-pure function. - -This means that the actual code stored on chain for a library -is different from the code reported by the compiler as -``deployedBytecode``. +正如介ç»ä¸­æ到的那样,如果库的代ç æ˜¯é€šè¿‡ ``CALL`` æ¥æ‰§è¡Œï¼Œ +而ä¸æ˜¯ ``DELEGATECALL`` 或者 ``CALLCODE``, +那么执行的结果会被æ¢å¤ï¼Œ 除éžæ˜¯å¯¹ ``view`` 或者 ``pure`` 函数的调用。 + +EVM没有æ供一个直接的方法让åˆçº¦æ£€æµ‹å®ƒæ˜¯å¦è¢«ä½¿ç”¨ ``CALL`` 调用, +但是åˆçº¦å¯ä»¥ä½¿ç”¨ ``ADDRESS`` æ“作ç æ¥æ‰¾å‡ºå®ƒå½“å‰è¿è¡Œçš„ "ä½ç½®"。 +生æˆçš„代ç å°†è¿™ä¸ªåœ°å€ä¸Žæž„造时使用的地å€è¿›è¡Œæ¯”较,以确定调用的模å¼ã€‚ + +更具体地说,一个库åˆçº¦çš„è¿è¡Œæ—¶ä»£ç æ€»æ˜¯ä»¥ push 指令开始, +在编译时它是一个20字节的零。 +当部署代ç è¿è¡Œæ—¶ï¼Œè¿™ä¸ªå¸¸æ•°åœ¨å†…存中被当å‰åœ°å€æ‰€å–代,这个修改åŽçš„代ç è¢«å­˜å‚¨åœ¨åˆçº¦ä¸­ã€‚ +在è¿è¡Œæ—¶ï¼Œè¿™å¯¼è‡´éƒ¨ç½²æ—¶çš„地å€æˆä¸ºç¬¬ä¸€ä¸ªè¢«æŽ¨å…¥å †æ ˆçš„常数, +对于任何 éž-view å’Œ éž-pure 函数,调度器代ç ä¼šå°†å½“å‰åœ°å€ä¸Žè¿™ä¸ªå¸¸æ•°è¿›è¡Œæ¯”较。 + +è¿™æ„味ç€ä¸€ä¸ªå­˜å‚¨åœ¨é“¾ä¸Šçš„库åˆçº¦çš„实际代ç ï¼Œä¸Žç¼–译器报告的 ``deployedBytecode`` 的代ç ä¸åŒã€‚ diff --git a/docs/contracts/using-for.rst b/docs/contracts/using-for.rst index a05cb277c6d9..a17d2487f1e4 100644 --- a/docs/contracts/using-for.rst +++ b/docs/contracts/using-for.rst @@ -6,48 +6,43 @@ Using For ********* -The directive ``using A for B`` can be used to attach -functions (``A``) as operators to user-defined value types -or as member functions to any type (``B``). -The member functions receive the object they are called on -as their first parameter (like the ``self`` variable in Python). -The operator functions receive operands as parameters. - -It is valid either at file level or inside a contract, -at contract level. - -The first part, ``A``, can be one of: - -- A list of functions, optionally with an operator name assigned (e.g. - ``using {f, g as +, h, L.t} for uint``). - If no operator is specified, the function can be either a library function or a free function and - is attached to the type as a member function. - Otherwise it must be a free function and it becomes the definition of that operator on the type. -- The name of a library (e.g. ``using L for uint``) - - all non-private functions of the library are attached to the type - as member functions - -At file level, the second part, ``B``, has to be an explicit type (without data location specifier). -Inside contracts, you can also use ``*`` in place of the type (e.g. ``using L for *;``), -which has the effect that all functions of the library ``L`` -are attached to *all* types. - -If you specify a library, *all* non-private functions in the library get attached, -even those where the type of the first parameter does not -match the type of the object. The type is checked at the -point the function is called and function overload -resolution is performed. - -If you use a list of functions (e.g. ``using {f, g, h, L.t} for uint``), -then the type (``uint``) has to be implicitly convertible to the -first parameter of each of these functions. This check is -performed even if none of these functions are called. -Note that private library functions can only be specified when ``using for`` is inside a library. - -If you define an operator (e.g. ``using {f as +} for T``), then the type (``T``) must be a -:ref:`user-defined value type ` and the definition must be a ``pure`` function. -Operator definitions must be global. -The following operators can be defined this way: +指令 ``using A for B`` å¯ç”¨äºŽå°†å‡½æ•°ï¼ˆ ``A``) +作为è¿ç®—符附加到用户定义的值类型 +或作为æˆå‘˜å‡½æ•°é™„加到任何类型( ``B``)。 +æˆå‘˜å‡½æ•°å°†è°ƒç”¨å®ƒä»¬çš„对象作为第一个å‚æ•° +(类似于 Python 中的 ``self`` å˜é‡ï¼‰ã€‚ +è¿ç®—符函数将接收æ“作数作为å‚数。 + +它å¯ä»¥åœ¨æ–‡ä»¶çº§åˆ«æˆ–者在åˆçº¦çº§åˆ«çš„åˆçº¦å†…部有效。 + +第一部分, ``A``,å¯ä»¥æ˜¯ä»¥ä¸‹ä¹‹ä¸€ï¼š + +- 一个函数列表,å¯é€‰æ‹©åˆ†é…è¿ç®—符å称 + (例如 ``using {f, g as +, h, L.t} for uint``)。 + 如果未指定è¿ç®—符,则该函数å¯ä»¥æ˜¯åº“函数或自由函数, + 并将其作为æˆå‘˜å‡½æ•°é™„加到类型。 + å¦åˆ™ï¼Œå®ƒå¿…须是一个自由函数,并æˆä¸ºè¯¥ç±»åž‹ä¸Šè¯¥è¿ç®—符的定义。 +- 一个库åˆçº¦çš„å称(例如 ``using L for uint``)- + 该库åˆçº¦çš„所有éžç§æœ‰å‡½æ•°éƒ½ä½œä¸ºæˆå‘˜å‡½æ•°é™„加到该类型上。 + +在文件级别中,第二部分, ``B``,必须是一个明确的类型(没有数æ®ä½ç½®æŒ‡å®šï¼‰ã€‚ +在åˆçº¦å†…部,您也å¯ä»¥ç”¨ ``*`` 代替类型(例如 ``using L for *;`` ), +这样åšçš„效果是,库åˆçº¦ ``L`` 中所有的函数都会被附加到 *所有* 类型上。 + +如果您指定了一个库åˆçº¦ï¼Œé‚£ä¹ˆè¯¥åº“åˆçº¦ä¸­çš„ *所有* éžç§æœ‰å‡½æ•°éƒ½ä¼šè¢«é™„加到该类型上, +å³ä½¿æ˜¯é‚£äº›ç¬¬ä¸€ä¸ªå‚数的类型与对象的类型ä¸åŒ¹é…的函数。 +类型会在函数被调用的时候检查, +并执行函数é‡è½½è§£æžã€‚ + +如果您使用一个函数列表(例如 ``using {f, g, h, L.t} for uint`` ), +那么类型( ``uint`` )必须å¯ä»¥éšå¼åœ°è½¬æ¢ä¸ºè¿™äº›å‡½æ•°çš„第一个å‚数。 +å³ä½¿è¿™äº›å‡½æ•°éƒ½æ²¡æœ‰è¢«è°ƒç”¨ï¼Œä¹Ÿè¦è¿›è¡Œè¿™ç§æ£€æŸ¥ã€‚ +请注æ„,åªæœ‰å½“ ``using for`` ä½äºŽåº“åˆçº¦å†…时,æ‰èƒ½æŒ‡å®šç§æœ‰åº“函数。 + +如果您定义了一个æ“作符(例如 ``using {f as +} for T``),那么类型( ``T``)必须是一个 +:ref:`用户定义的值类型 `,并且定义必须是一个 ``pure`` 函数。 +æ“作符定义必须是全局的。 +以下æ“作符å¯ä»¥ç”¨è¿™ç§æ–¹å¼å®šä¹‰ï¼š +------------+----------+---------------------------------------------+ | Category | Operator | Possible signatures | @@ -85,24 +80,18 @@ The following operators can be defined this way: | | ``>=`` | ``function (T, T) pure returns (bool)`` | +------------+----------+---------------------------------------------+ -Note that unary and binary ``-`` need separate definitions. -The compiler will choose the right definition based on how the operator is invoked. +注æ„,一元和二元的 ``-`` 需è¦å•ç‹¬å®šä¹‰ã€‚ +编译器会根æ®æ“作符的调用方å¼é€‰æ‹©æ­£ç¡®çš„定义。 -The ``using A for B;`` directive is active only within the current -scope (either the contract or the current module/source unit), -including within all of its functions, and has no effect -outside of the contract or module in which it is used. +``using A for B;`` 指令åªåœ¨å½“å‰ä½œç”¨åŸŸï¼ˆåˆçº¦æˆ–当å‰æ¨¡å—/æºå•å…ƒï¼‰å†…有效, +包括其中所有的函数,在使用它的åˆçº¦æˆ–模å—之外没有任何效果。 -When the directive is used at file level and applied to a -user-defined type which was defined at file level in the same file, -the word ``global`` can be added at the end. This will have the -effect that the functions and operators are attached to the type everywhere -the type is available (including other files), not only in the -scope of the using statement. +当在文件级别使用该指令并应用于在åŒä¸€æ–‡ä»¶ä¸­ç”¨æˆ·å®šä¹‰ç±»åž‹æ—¶ï¼Œ +å¯ä»¥åœ¨æœ«å°¾æ·»åŠ  ``global`` 关键字。 +这将使函数和æ“作符附加到该类型的任何å¯ç”¨ä½ç½®ï¼ˆåŒ…括其他文件), +而ä¸ä»…仅是在 using 语å¥çš„范围内。 -Let us rewrite the set example from the -:ref:`libraries` section in this way, using file-level functions -instead of library functions. +下é¢æˆ‘们将使用文件级函数æ¥é‡å†™ :ref:`libraries` 部分中的 set 示例。 .. code-block:: solidity @@ -110,10 +99,10 @@ instead of library functions. pragma solidity ^0.8.13; struct Data { mapping(uint => bool) flags; } - // Now we attach functions to the type. - // The attached functions can be used throughout the rest of the module. - // If you import the module, you have to - // repeat the using directive there, for example as + // 现在我们给这个类型附加上函数。 + // 附加的函数å¯ä»¥åœ¨æ¨¡å—的其他部分使用。 + // 如果您导入了该模å—, + // 您必须在那里é‡å¤using指令,例如 // import "flags.sol" as Flags; // using {Flags.insert, Flags.remove, Flags.contains} // for Flags.Data; @@ -123,7 +112,7 @@ instead of library functions. returns (bool) { if (self.flags[value]) - return false; // already there + return false; // å·²ç»å­˜åœ¨ self.flags[value] = true; return true; } @@ -132,7 +121,7 @@ instead of library functions. returns (bool) { if (!self.flags[value]) - return false; // not there + return false; // ä¸å­˜åœ¨ self.flags[value] = false; return true; } @@ -149,16 +138,14 @@ instead of library functions. Data knownValues; function register(uint value) public { - // Here, all variables of type Data have - // corresponding member functions. - // The following function call is identical to - // `Set.insert(knownValues, value)` + // 这里, Data 类型的所有å˜é‡éƒ½æœ‰ä¸Žä¹‹ç›¸å¯¹åº”çš„æˆå‘˜å‡½æ•°ã€‚ + // 下é¢çš„函数调用和 `Set.insert(knownValues, value)` 的效果完全相åŒã€‚ require(knownValues.insert(value)); } } -It is also possible to extend built-in types in that way. -In this example, we will use a library. +也å¯ä»¥é€šè¿‡è¿™ç§æ–¹å¼æ¥æ‰©å±•å†…置类型。 +在这个例å­ä¸­ï¼Œæˆ‘们将使用一个库åˆçº¦ã€‚ .. code-block:: solidity @@ -186,7 +173,7 @@ In this example, we will use a library. } function replace(uint from, uint to) public { - // This performs the library function call + // 这将执行库åˆçº¦ä¸­çš„函数调用 uint index = data.indexOf(from); if (index == type(uint).max) data.push(to); @@ -195,13 +182,11 @@ In this example, we will use a library. } } -Note that all external library calls are actual EVM function calls. This means that -if you pass memory or value types, a copy will be performed, even in case of the -``self`` variable. The only situation where no copy will be performed -is when storage reference variables are used or when internal library -functions are called. +注æ„,所有的外部库调用实际都是EVM函数调用。 +è¿™æ„味ç€ï¼Œå¦‚果传递内存或值类型,å³ä½¿æ˜¯ ``self`` å˜é‡ï¼Œä¹Ÿä¼šæ‰§è¡Œå¤åˆ¶ã€‚ +åªæœ‰åœ¨ä½¿ç”¨å­˜å‚¨å¼•ç”¨å˜é‡æˆ–调用内部库函数时,æ‰ä¸ä¼šæ‰§è¡Œå¤åˆ¶ã€‚ -Another example shows how to define a custom operator for a user-defined type: +å¦ä¸€ä¸ªå±•ç¤ºäº†å¦‚何为用户定义的类型定义自定义æ“作符的示例: .. code-block:: solidity diff --git a/docs/contracts/visibility-and-getters.rst b/docs/contracts/visibility-and-getters.rst index 5bf46dea551b..6cbf3eee7940 100644 --- a/docs/contracts/visibility-and-getters.rst +++ b/docs/contracts/visibility-and-getters.rst @@ -1,67 +1,60 @@ .. index:: ! visibility, external, public, private, internal -.. |visibility-caveat| replace:: Making something ``private`` or ``internal`` only prevents other contracts from reading or modifying the information, but it will still be visible to the whole world outside of the blockchain. +.. |visibility-caveat| replace:: 标记一些å˜é‡ä¸º ``private`` 或 ``internal``,åªèƒ½é˜²æ­¢å…¶ä»–åˆçº¦è¯»å–或修改信æ¯ï¼Œä½†å®ƒä»ç„¶ä¼šè¢«åŒºå—链之外的整个世界看到。 .. _visibility-and-getters: ********************** -Visibility and Getters +å¯è§æ€§å’Œ getter 函数 ********************** -State Variable Visibility -========================= +状æ€å˜é‡çš„å¯è§æ€§ +================= ``public`` - Public state variables differ from internal ones only in that the compiler automatically generates - :ref:`getter functions` for them, which allows other contracts to read their values. - When used within the same contract, the external access (e.g. ``this.x``) invokes the getter - while internal access (e.g. ``x``) gets the variable value directly from storage. - Setter functions are not generated so other contracts cannot directly modify their values. + 公开状æ€å˜é‡ä¸Žå†…部å˜é‡çš„ä¸åŒä¹‹å¤„åœ¨äºŽï¼Œç¼–è¯‘å™¨ä¼šè‡ªåŠ¨ä¸ºå®ƒä»¬ç”Ÿæˆ :ref:`getter函数 `, + 从而å…许其他åˆçº¦è¯»å–它们的值。当在åŒä¸€ä¸ªåˆçº¦ä¸­ä½¿ç”¨æ—¶ï¼Œå¤–部访问(例如 ``this.x``)会调用getter, + 而内部访问(例如 ``x``)会直接从存储中获å–å˜é‡å€¼ã€‚ + Setter函数没有被生æˆï¼Œæ‰€ä»¥å…¶ä»–åˆçº¦ä¸èƒ½ç›´æŽ¥ä¿®æ”¹å…¶å€¼ã€‚ ``internal`` - Internal state variables can only be accessed from within the contract they are defined in - and in derived contracts. - They cannot be accessed externally. - This is the default visibility level for state variables. + 内部状æ€å˜é‡åªèƒ½ä»Žå®ƒä»¬æ‰€å®šä¹‰çš„åˆçº¦å’Œæ´¾ç”Ÿåˆçº¦ä¸­è®¿é—®ã€‚ + 它们ä¸èƒ½è¢«å¤–部访问。 + 这是状æ€å˜é‡çš„默认å¯è§æ€§ã€‚ ``private`` - Private state variables are like internal ones but they are not visible in derived contracts. + ç§æœ‰çŠ¶æ€å˜é‡å°±åƒå†…部å˜é‡ä¸€æ ·ï¼Œä½†å®ƒä»¬åœ¨æ´¾ç”Ÿåˆçº¦ä¸­æ˜¯ä¸å¯è§çš„。 .. warning:: |visibility-caveat| -Function Visibility +函数的å¯è§æ€§ =================== -Solidity knows two kinds of function calls: external ones that do create an actual EVM message call and internal ones that do not. -Furthermore, internal functions can be made inaccessible to derived contracts. -This gives rise to four types of visibility for functions. +Solidity 有两ç§å‡½æ•°è°ƒç”¨ï¼šç¡®å®žåˆ›å»ºäº†å®žé™… EVM 消æ¯è°ƒç”¨çš„外部函数和ä¸åˆ›å»º EVM 消æ¯è°ƒç”¨çš„内部函数。 +此外,派生åˆçº¦å¯èƒ½æ— æ³•è®¿é—®å†…部函数。 +这就产生了四ç§ç±»åž‹çš„函数的å¯è§æ€§ã€‚ ``external`` - External functions are part of the contract interface, - which means they can be called from other contracts and - via transactions. An external function ``f`` cannot be called - internally (i.e. ``f()`` does not work, but ``this.f()`` works). + 外部函数作为åˆçº¦æŽ¥å£çš„一部分,æ„味ç€æˆ‘们å¯ä»¥ä»Žå…¶ä»–åˆçº¦å’Œäº¤æ˜“中调用。 + 一个外部函数 ``f`` ä¸èƒ½ä»Žå†…部调用 + ï¼ˆå³ ``f()`` ä¸èµ·ä½œç”¨ï¼Œä½† ``this.f()`` å¯ä»¥ï¼‰ã€‚ ``public`` - Public functions are part of the contract interface - and can be either called internally or via message calls. + 公开函数是åˆçº¦æŽ¥å£çš„一部分,å¯ä»¥åœ¨å†…部或通过消æ¯è°ƒç”¨ã€‚ ``internal`` - Internal functions can only be accessed from within the current contract - or contracts deriving from it. - They cannot be accessed externally. - Since they are not exposed to the outside through the contract's ABI, they can take parameters of internal types like mappings or storage references. + 内部函数åªèƒ½ä»Žå½“å‰çš„åˆçº¦æˆ–从它派生出æ¥çš„åˆçº¦ä¸­è®¿é—®ã€‚ + 它们ä¸èƒ½è¢«å¤–部访问。 + 由于它们没有通过åˆçº¦çš„ABI暴露在外部,它们å¯ä»¥æŽ¥å—内部类型的å‚数,如映射或存储引用。 ``private`` - Private functions are like internal ones but they are not visible in derived contracts. + ç§æœ‰å‡½æ•°å’Œå†…部函数一样,但它们在派生åˆçº¦ä¸­æ˜¯ä¸å¯è§çš„。 .. warning:: |visibility-caveat| -The visibility specifier is given after the type for -state variables and between parameter list and -return parameter list for functions. +在状æ€å˜é‡çš„类型之åŽï¼Œä»¥åŠåœ¨å‡½æ•°çš„å‚数列表和返回å‚数列表之间,都会给出å¯è§æ€§æŒ‡å®šç¬¦ã€‚ .. code-block:: solidity @@ -74,9 +67,8 @@ return parameter list for functions. uint public data; } -In the following example, ``D``, can call ``c.getData()`` to retrieve the value of -``data`` in state storage, but is not able to call ``f``. Contract ``E`` is derived from -``C`` and, thus, can call ``compute``. +在下é¢çš„例å­ä¸­ï¼Œåˆçº¦ ``D``, å¯ä»¥è°ƒç”¨ ``c.getData()`` æ¥æ£€ç´¢çŠ¶æ€å­˜å‚¨ä¸­ ``data`` 的值, +但ä¸èƒ½è°ƒç”¨ ``f``。 åˆçº¦ ``E`` 是从åˆçº¦ ``C`` 派生出æ¥çš„,因此å¯ä»¥è°ƒç”¨ ``compute``。 .. code-block:: solidity @@ -92,36 +84,34 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value function compute(uint a, uint b) internal pure returns (uint) { return a + b; } } - // This will not compile + // 这将ä¸ä¼šç¼–译 contract D { function readData() public { C c = new C(); - uint local = c.f(7); // error: member `f` is not visible + uint local = c.f(7); // 错误:æˆå‘˜ `f` ä¸å¯è§ c.setData(3); local = c.getData(); - local = c.compute(3, 5); // error: member `compute` is not visible + local = c.compute(3, 5); // 错误:æˆå‘˜ `compute` ä¸å¯è§ } } contract E is C { function g() public { C c = new C(); - uint val = compute(3, 5); // access to internal member (from derived to parent contract) + uint val = compute(3, 5); // 访问内部æˆå‘˜ï¼ˆä»Žç»§æ‰¿åˆçº¦è®¿é—®çˆ¶åˆçº¦æˆå‘˜ï¼‰ } } .. index:: ! getter;function, ! function;getter .. _getter-functions: -Getter Functions +Getter 函数 ================ -The compiler automatically creates getter functions for -all **public** state variables. For the contract given below, the compiler will -generate a function called ``data`` that does not take any -arguments and returns a ``uint``, the value of the state -variable ``data``. State variables can be initialized -when they are declared. +编译器会自动为所有 **公开** 状æ€å˜é‡åˆ›å»ºgetter函数。 +对于下é¢ç»™å‡ºçš„åˆçº¦ï¼Œç¼–译器将生æˆä¸€ä¸ªå为 ``data`` 的函数, +它没有任何输入å‚数,并返回一个 ``uint``, +å³çŠ¶æ€å˜é‡ ``data`` 的值。状æ€å˜é‡åœ¨å£°æ˜Žæ—¶å¯ä»¥è¢«åˆå§‹åŒ–。 .. code-block:: solidity @@ -139,10 +129,9 @@ when they are declared. } } -The getter functions have external visibility. If the -symbol is accessed internally (i.e. without ``this.``), -it evaluates to a state variable. If it is accessed externally -(i.e. with ``this.``), it evaluates to a function. +getter函数具有外部å¯è§æ€§ã€‚ +如果该符å·è¢«å†…部访问(å³æ²¡æœ‰ ``this.``),它被评估为一个状æ€å˜é‡ã€‚ +如果它被外部访问(å³æœ‰ ``this.``),它将被评价为一个函数。 .. code-block:: solidity @@ -152,17 +141,16 @@ it evaluates to a state variable. If it is accessed externally contract C { uint public data; function x() public returns (uint) { - data = 3; // internal access - return this.data(); // external access + data = 3; // 内部访问 + return this.data(); // 外部访问 } } -If you have a ``public`` state variable of array type, then you can only retrieve -single elements of the array via the generated getter function. This mechanism -exists to avoid high gas costs when returning an entire array. You can use -arguments to specify which individual element to return, for example -``myArray(0)``. If you want to return an entire array in one call, then you need -to write a function, for example: +如果您有一个数组类型的 ``public`` 状æ€å˜é‡ï¼Œ +那么您åªèƒ½é€šè¿‡ç”Ÿæˆçš„getter函数检索数组的å•ä¸ªå…ƒç´ ã€‚ +è¿™ç§æœºåˆ¶çš„存在是为了é¿å…在返回整个数组时产生高é¢çš„气体æˆæœ¬ã€‚ +您å¯ä»¥ä½¿ç”¨å‚æ•°æ¥æŒ‡å®šè¦è¿”回的å•ä¸ªå…ƒç´ ï¼Œä¾‹å¦‚ ``myArray(0)``。 +如果您想在一次调用中返回整个数组,那么您需è¦å†™ä¸€ä¸ªå‡½æ•°ï¼Œä¾‹å¦‚: .. code-block:: solidity @@ -170,26 +158,26 @@ to write a function, for example: pragma solidity >=0.4.16 <0.9.0; contract arrayExample { - // public state variable + // 公开状æ€å˜é‡ uint[] public myArray; - // Getter function generated by the compiler + // 编译器生æˆçš„getter函数 /* function myArray(uint i) public view returns (uint) { return myArray[i]; } */ - // function that returns entire array + // 返回整个数组的函数 function getArray() public view returns (uint[] memory) { return myArray; } } -Now you can use ``getArray()`` to retrieve the entire array, instead of -``myArray(i)``, which returns a single element per call. +现在您å¯ä»¥ä½¿ç”¨ ``getArray()`` æ¥æ£€ç´¢æ•´ä¸ªæ•°ç»„, +而ä¸æ˜¯ä½¿ç”¨ ``myArray(i)``,它æ¯æ¬¡è°ƒç”¨åªè¿”回一个元素。 -The next example is more complex: +下一个例å­ç¨å¾®å¤æ‚一些: .. code-block:: solidity @@ -208,9 +196,8 @@ The next example is more complex: mapping(uint => mapping(bool => Data[])) public data; } -It generates a function of the following form. The mapping and arrays (with the -exception of byte arrays) in the struct are omitted because there is no good way -to select individual struct members or provide a key for the mapping: +它生æˆäº†ä¸€ä¸ªå¦‚下形å¼çš„函数。结构中的映射和数组(字节数组除外)被çœç•¥äº†ï¼Œ +因为没有好的方法æ¥é€‰æ‹©å•ä¸ªç»“æž„æˆå‘˜æˆ–为映射æ供一个键: .. code-block:: solidity diff --git a/docs/contributing.rst b/docs/contributing.rst index 7f444871d546..07dc14a69a31 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -1,195 +1,216 @@ ############ -Contributing +è´¡çŒ®æ–¹å¼ ############ -Help is always welcome and there are plenty of options to contribute to Solidity. +对于大家的帮助,我们一如既往地欢迎。而且有很多选择å¯ä»¥ä¸º Solidity åšå‡ºè´¡çŒ®ã€‚ -In particular, we appreciate support in the following areas: +特别是,我们感谢在以下领域的支æŒ: -* Reporting issues. -* Fixing and responding to `Solidity's GitHub issues - `_, especially those tagged as - `"good first issue" `_ which are - meant as introductory issues for external contributors. -* Improving the documentation. -* `Translating `_ the documentation into more languages. -* Responding to questions from other users on `StackExchange - `_ and the `Solidity Gitter Chat - `_. -* Getting involved in the language design process by proposing language changes or new features in the `Solidity forum `_ and providing feedback. +* 报告问题。 +* ä¿®å¤å’Œå“应 `Solidity çš„ GitHub 问题 + `_,特别是那些被标记为 + `"很好的第一个问题" `_,这是 + 作为外部贡献者的介ç»æ€§é—®é¢˜ã€‚ +* 完善文档。 +* 将文档 `翻译 `_ æˆæ›´å¤šçš„语言。 +* 在 `StackExchange `_ å’Œ + `Solidity Gitter Chat `_ 上回答其他用户的问题。 +* 通过在 `Solidityè®ºå› `_ 上æ出语言改进或新功能,并æä¾›å馈æ¥å‚与语言设计的过程。 -To get started, you can try :ref:`building-from-source` in order to familiarize -yourself with the components of Solidity and the build process. Also, it may be -useful to become well-versed at writing smart-contracts in Solidity. +为了开始å‚与,您å¯ä»¥å°è¯• :ref:`building-from-source`,以熟悉 Solidity 的组件和构建过程。 +此外,精通在 Solidity 中编写智能åˆçº¦å¯èƒ½æ˜¯æœ‰ç”¨çš„。 -Please note that this project is released with a `Contributor Code of Conduct `_. By participating in this project — in the issues, pull requests, or Gitter channels — you agree to abide by its terms. +请注æ„,本项目å‘布时有一个 `贡献者行为准则 `_。å‚与此项目 - 在 issues,pull requests 或 Gitter channels 中 - å³è¡¨ç¤ºæ‚¨åŒæ„éµå®ˆå…¶æ¡æ¬¾ã€‚ -Team Calls -========== +团队电è¯ä¼šè®® +============ -If you have issues or pull requests to discuss, or are interested in hearing what -the team and contributors are working on, you can join our public team call: +如果您有问题或拉动请求è¦è®¨è®ºï¼Œæˆ–有兴趣å¬å¬å›¢é˜Ÿå’Œè´¡çŒ®è€…正在åšä»€ä¹ˆï¼Œæ‚¨å¯ä»¥åŠ å…¥æˆ‘们的公共团队电è¯ä¼šè®®ï¼š -- Wednesdays at 3PM CET/CEST. +- æ¯å‘¨ä¸‰ä¸‹åˆ3点,中欧标准时间/中欧å¤ä»¤æ—¶é—´ã€‚ -The call takes place on `Jitsi `_. +<<<<<<< HEAD +会议在 `Jitsi `_ 举行。 +======= +The call takes place on `Jitsi `_. +>>>>>>> english/develop -How to Report Issues +如何报告问题 ==================== -To report an issue, please use the -`GitHub issues tracker `_. When -reporting issues, please mention the following details: - +è¦æŠ¥å‘Šä¸€ä¸ªé—®é¢˜ï¼Œè¯·ä½¿ç”¨ +`GitHub问题跟踪器 `_。 +当报告问题时,请æåŠä»¥ä¸‹ç»†èŠ‚: + +<<<<<<< HEAD +* Solidity版本。 +* æºä»£ç ï¼ˆå¦‚æžœå¯ä»¥çš„è¯ï¼‰ã€‚ +* æ“作系统。 +* é‡çŽ°è¯¥é—®é¢˜çš„步骤。 +* 实际行为与预期行为。 +======= * Solidity version. * Source code (if applicable). * Operating system. * Steps to reproduce the issue. * Actual vs. expected behavior. +>>>>>>> english/develop -Reducing the source code that caused the issue to a bare minimum is always -very helpful, and sometimes even clarifies a misunderstanding. +将导致问题的æºä»£ç å‡å°‘到最低é™åº¦æ€»æ˜¯éžå¸¸æœ‰å¸®åŠ©çš„,有时甚至å¯ä»¥æ¾„清一个误解。 -For technical discussions about language design, a post in the -`Solidity forum `_ is the correct place (see :ref:`solidity_language_design`). +关于语言设计的技术讨论,去 +`Solidity è®ºå› `_ æ‰æ˜¯æ­£ç¡®çš„é€‰æ‹©ï¼ˆè§ :ref:`solidity_language_design`)。 -Workflow for Pull Requests +拉å–请求的工作æµç¨‹ ========================== -In order to contribute, please fork off of the ``develop`` branch and make your -changes there. Your commit messages should detail *why* you made your change -in addition to *what* you did (unless it is a tiny change). +为了进行贡献,请 fork 一个 ``develop`` 分支并在那里进行修改。 +除了您 *åšäº†ä»€ä¹ˆ* 之外,您还需è¦åœ¨æ交信æ¯ä¸­è¯´æ˜Žï¼Œ +您 *为什么* åšè¿™äº›ä¿®æ”¹ï¼ˆé™¤éžåªæ˜¯ä¸ªå¾®å°çš„改动)。 -If you need to pull in any changes from ``develop`` after making your fork (for -example, to resolve potential merge conflicts), please avoid using ``git merge`` -and instead, ``git rebase`` your branch. This will help us review your change -more easily. +在进行了 fork 之åŽï¼Œå¦‚果您还需è¦ä»Ž ``develop`` 分支 pull 任何å˜æ›´çš„è¯ +(例如,为了解决潜在的åˆå¹¶å†²çªï¼‰ï¼Œè¯·é¿å…使用 ``git rebase`` , +而是用 ``git rebase`` 您的分支。 -Additionally, if you are writing a new feature, please ensure you add appropriate -test cases under ``test/`` (see below). +此外,如果您正在编写一个新的功能,请确ä¿æ‚¨åœ¨ ``test/`` 下添加适当的测试案例(è§ä¸‹æ–‡ï¼‰ã€‚ -However, if you are making a larger change, please consult with the `Solidity Development Gitter channel -`_ (different from the one mentioned above — this one is -focused on compiler and language development instead of language usage) first. +但是,如果您在进行一个更大的å˜æ›´ï¼Œè¯·å…ˆä¸Ž +`Solidity Development Gitter channel `_ +(与上文æ到的ä¸åŒ - 这个å˜æ›´ä¾§é‡äºŽç¼–译器和编程语言开å‘,而ä¸æ˜¯ç¼–程语言的使用)进行咨询。 -New features and bugfixes should be added to the ``Changelog.md`` file: please -follow the style of previous entries, when applicable. +新的特性和 bug ä¿®å¤ä¼šè¢«æ·»åŠ åˆ° ``Changelog.md`` 文件中:使用的时候请éµå¾ªä¸Šè¿°æ–¹å¼ã€‚ -Finally, please make sure you respect the `coding style -`_ -for this project. Also, even though we do CI testing, please test your code and -ensure that it builds locally before submitting a pull request. +最åŽï¼Œè¯·ç¡®ä¿æ‚¨éµå®ˆäº†è¿™ä¸ªé¡¹ç›®çš„ `ç¼–ç é£Žæ ¼ `_ 。 +还有,虽然我们采用了æŒç»­é›†æˆæµ‹è¯•ï¼Œä½†æ˜¯åœ¨æ交 pull request 之å‰ï¼Œè¯·æµ‹è¯•æ‚¨çš„代ç å¹¶ç¡®ä¿å®ƒèƒ½åœ¨æœ¬åœ°è¿›è¡Œç¼–译。 -We highly recommend going through our `review checklist `_ before submitting the pull request. -We thoroughly review every PR and will help you get it right, but there are many common problems that can be easily avoided, making the review much smoother. +我们强烈建议在æ交拉动请求之å‰ï¼Œå…ˆçœ‹ä¸€ä¸‹æˆ‘们的 `å®¡æŸ¥æ¸…å• `_。 +我们会彻底审查æ¯ä¸€ä¸ªPR,并会帮助您把它弄好,但有许多常è§é—®é¢˜å¯ä»¥å¾ˆå®¹æ˜“地é¿å…,使审查更加顺利。 -Thank you for your help! +æ„Ÿè°¢æ‚¨çš„å¸®åŠ©ï¼ -Running the Compiler Tests +è¿è¡Œç¼–译器测试 ========================== -Prerequisites +先决æ¡ä»¶ ------------- +<<<<<<< HEAD +为了è¿è¡Œæ‰€æœ‰çš„编译器测试,您å¯èƒ½æƒ³é€‰æ‹©æ€§åœ°å®‰è£…一些ä¾èµ–项 +( `evmone `_, +`libz3 `_, å’Œ +`libhera `_)。 +======= For running all compiler tests you may want to optionally install a few dependencies (`evmone `_, `libz3 `_). +>>>>>>> english/develop -On macOS systems, some of the testing scripts expect GNU coreutils to be installed. -This can be easiest accomplished using Homebrew: ``brew install coreutils``. +在 macOS 系统上,一些测试脚本需è¦å®‰è£… GNU 核心工具。 +å¯ä»¥ä½¿ç”¨ Homebrew 很简å•åœ°å®Œæˆå®‰è£…: ``brew install coreutils``。 -On Windows systems, make sure that you have a privilege to create symlinks, -otherwise several tests may fail. -Administrators should have that privilege, but you may also -`grant it to other users `_ -or -`enable Developer Mode `_. +在 Windows 系统上,确ä¿æ‚¨æœ‰åˆ›å»ºç¬¦å·é“¾æŽ¥çš„æƒé™ï¼Œ +å¦åˆ™ä¸€äº›æµ‹è¯•å¯èƒ½ä¼šå¤±è´¥ã€‚ +管ç†å‘˜åº”该有这个æƒé™ï¼Œä½†æ‚¨ä¹Ÿå¯ä»¥ +`将其授予其他用户 `_ +或 `å¯ç”¨å¼€å‘è€…æ¨¡å¼ `_。 -Running the Tests +è¿è¡Œæµ‹è¯• ----------------- -Solidity includes different types of tests, most of them bundled into the -`Boost C++ Test Framework `_ application ``soltest``. -Running ``build/test/soltest`` or its wrapper ``scripts/soltest.sh`` is sufficient for most changes. +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 `_ çš„ä½ç½®ï¼Œä»¥è¿è¡Œè¯­ä¹‰æµ‹è¯•ã€‚ -The test system automatically tries to discover the location of -the `evmone `_ for running the semantic tests. +``evmone`` 库必须ä½äºŽå½“å‰å·¥ä½œç›®å½•ç›¸å¯¹çš„ ``deps`` 或 ``deps/lib`` 目录, +其父级目录或其父级目录的父级目录中。å¦å¤–, +å¯ä»¥é€šè¿‡ ``ETH_EVMONE`` 环境å˜é‡æŒ‡å®š ``evmone`` 共享对象的显å¼ä½ç½®ã€‚ -The ``evmone`` library must be located in the ``deps`` or ``deps/lib`` directory relative to the -current working directory, to its parent or its parent's parent. Alternatively, an explicit location -for the ``evmone`` shared object can be specified via the ``ETH_EVMONE`` environment variable. +``evmone`` 主è¦ç”¨äºŽè¿è¡Œè¯­ä¹‰å’Œgas测试。 +如果您没有安装它,您å¯ä»¥é€šè¿‡å‘ ``scripts/soltest.sh`` 传递 ``--no-semantic-tests`` 标志æ¥è·³è¿‡è¿™äº›æµ‹è¯•ã€‚ -``evmone`` is needed mainly for running semantic and gas tests. -If you do not have it installed, you can skip these tests by passing the ``--no-semantic-tests`` -flag to ``scripts/soltest.sh``. +<<<<<<< HEAD +è¿è¡ŒEwasm测试默认是ç¦ç”¨çš„,å¯ä»¥é€šè¿‡ ``./scripts/soltest.sh --ewasm`` 明确å¯ç”¨ï¼Œ +è¦æ±‚ `hera `_ 被 ``soltest`` 找到。 +å®šä½ ``hera`` 库的机制与 ``evmone`` 相åŒï¼Œåªæ˜¯ç”¨äºŽæŒ‡å®šæ˜Žç¡®ä½ç½®çš„å˜é‡è¢«ç§°ä¸º ``ETH_HERA``。 -The ``evmone`` library should both end with the file name +``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 -For running SMT tests, the ``libz3`` library must be installed and locatable -by ``cmake`` during compiler configure stage. +为了è¿è¡ŒSMT测试, ``libz3`` 库必须被安装,并在编译器é…置阶段被 ``cmake`` å¯ä»¥æ‰¾åˆ°ã€‚ -If the ``libz3`` library is not installed on your system, you should disable the -SMT tests by exporting ``SMT_FLAGS=--no-smt`` before running ``./scripts/tests.sh`` or -running ``./scripts/soltest.sh --no-smt``. -These tests are ``libsolidity/smtCheckerTests`` and ``libsolidity/smtCheckerTestsJSON``. +如果您的系统没有安装 ``libz3`` 库,您应该在è¿è¡Œ ``./scripts/tests.sh`` 或 ``./scripts/soltest.sh --no-smt`` 之å‰ï¼Œ +通过导出 ``SMT_FLAGS=--no-smt`` æ¥ç¦ç”¨SMT测试。 +这些测试是 ``libsolidity/smtCheckerTests`` å’Œ ``libsolidity/smtCheckerTestsJSON``。 .. note:: - To get a list of all unit tests run by Soltest, run ``./build/test/soltest --list_content=HRF``. + è¦èŽ·å¾—Soltestè¿è¡Œçš„所有å•å…ƒæµ‹è¯•çš„列表,请è¿è¡Œ ``./build/test/soltest --list_content=HRF``。 -For quicker results you can run a subset of, or specific tests. +为了获得更快的结果,您å¯ä»¥è¿è¡Œä¸€ä¸ªå­é›†ï¼Œæˆ–特定的测试。 -To run a subset of tests, you can use filters: +è¦è¿è¡Œæµ‹è¯•çš„一个å­é›†ï¼Œå¯ä»¥ä½¿ç”¨è¿‡æ»¤å™¨ï¼š ``./scripts/soltest.sh -t TestSuite/TestName``, -where ``TestName`` can be a wildcard ``*``. +其中 ``TestName`` å¯ä»¥æ˜¯é€šé…符 ``*``。 -Or, for example, to run all the tests for the yul disambiguator: -``./scripts/soltest.sh -t "yulOptimizerTests/disambiguator/*" --no-smt``. +或者,举例æ¥è¯´ï¼Œè¿è¡Œyul 消歧义器的所有测试: +``./scripts/soltest.sh -t "yulOptimizerTests/disambiguator/*" --no-smt``。 -``./build/test/soltest --help`` has extensive help on all of the options available. +``./build/test/soltest --help`` 有关于所有å¯ç”¨é€‰é¡¹çš„广泛帮助。 -See especially: +尤其是å¯ä»¥æŸ¥çœ‹ï¼š -- `show_progress (-p) `_ to show test completion, -- `run_test (-t) `_ to run specific tests cases, and -- `report-level (-r) `_ give a more detailed report. +- `show_progress (-p) `_ æ¥æ˜¾ç¤ºæµ‹è¯•å®Œæˆã€‚ +- `run_test (-t) `_ æ¥è¿è¡Œç‰¹å®šçš„æµ‹è¯•æ¡ˆä¾‹ï¼Œä»¥åŠ +- `report-level (-r) `_ 给出一个更详细的报告。 .. note:: - Those working in a Windows environment wanting to run the above basic sets - without libz3. Using Git Bash, you use: ``./build/test/Release/soltest.exe -- --no-smt``. - If you are running this in plain Command Prompt, use ``.\build\test\Release\soltest.exe -- --no-smt``. + 那些在Windows环境下使用的人,想在没有libz3的情况下è¿è¡Œä¸Šè¿°åŸºæœ¬é›†ï¼Œå¯ä»¥ä½¿ç”¨Git Bash, + 使用命令为: ``./build/test/Release/soltest.exe -- --no-smt``。 + 如果您在普通的命令æ示符下è¿è¡Œï¼Œä½¿ç”¨ ``.\build\test\Release\soltest.exe -- --no-smt``。 + +如果您想使用GDB进行调试,确ä¿æ‚¨çš„构建方å¼ä¸Ž “通常†ä¸åŒã€‚ +例如,您å¯ä»¥åœ¨æ‚¨çš„ ``build`` 文件夹中è¿è¡Œä»¥ä¸‹å‘½ä»¤ï¼š -If you want to debug using GDB, make sure you build differently than the "usual". -For example, you could run the following command in your ``build`` folder: +如果您想使用 GDB 进行调试,请确ä¿æ‚¨çš„构建方å¼ä¸Žâ€œé€šå¸¸â€çš„构建方å¼ä¸åŒã€‚ +例如,您å¯ä»¥åœ¨ ``build`` 文件夹中è¿è¡Œä»¥ä¸‹å‘½ä»¤ï¼š .. code-block:: bash cmake -DCMAKE_BUILD_TYPE=Debug .. make -This creates symbols so that when you debug a test using the ``--debug`` flag, -you have access to functions and variables in which you can break or print with. +这会创建了一些符å·ï¼Œæ‰€ä»¥å½“您使用 ``--debug`` 标志调试测试时, +您å¯ä»¥è®¿é—®å…¶ä¸­çš„函数和å˜é‡ï¼Œæ‚¨å¯ä»¥ç”¨å®ƒæ¥ä¸­æ–­æˆ–打å°ã€‚ -The CI runs additional tests (including ``solc-js`` and testing third party Solidity -frameworks) that require compiling the Emscripten target. +CIè¿è¡Œé¢å¤–的测试(包括 ``solc-js`` 和测试第三方Solidity框架),需è¦ç¼–译 Emscripten 目标。 -Writing and Running Syntax Tests +编写和è¿è¡Œè¯­æ³•æµ‹è¯• -------------------------------- -Syntax tests check that the compiler generates the correct error messages for invalid code -and properly accepts valid code. -They are stored in individual files inside the ``tests/libsolidity/syntaxTests`` folder. -These files must contain annotations, stating the expected result(s) of the respective test. -The test suite compiles and checks them against the given expectations. +语法测试检查编译器是å¦å¯¹æ— æ•ˆçš„代ç äº§ç”Ÿæ­£ç¡®çš„错误信æ¯ï¼Œå¹¶æ­£ç¡®æŽ¥å—有效的代ç ã€‚ +它们被ä¿å­˜åœ¨ ``tests/libsolidity/syntaxTests`` 文件夹下的å•ä¸ªæ–‡ä»¶ä¸­ã€‚ +这些文件必须包å«æ³¨é‡Šï¼Œè¯´æ˜Žå„自测试的预期结果。 +测试套件会根æ®ç»™å®šçš„期望值进行编译和检查。 -For example: ``./test/libsolidity/syntaxTests/double_stateVariable_declaration.sol`` +例如: ``./test/libsolidity/syntaxTests/double_stateVariable_declaration.sol`` .. code-block:: solidity @@ -198,17 +219,18 @@ For example: ``./test/libsolidity/syntaxTests/double_stateVariable_declaration.s uint128 variable; } // ---- - // DeclarationError: (36-52): Identifier already declared. + // 声明错误:(36-52)。标识符已被声明。 -A syntax test must contain at least the contract under test itself, followed by the separator ``// ----``. The comments that follow the separator are used to describe the -expected compiler errors or warnings. The number range denotes the location in the source where the error occurred. -If you want the contract to compile without any errors or warning you can leave -out the separator and the comments that follow it. +语法测试必须至少包å«è¢«æµ‹åˆçº¦æœ¬èº«ï¼ŒåŽé¢æ˜¯åˆ†éš”符 ``//----``。 +分隔符åŽé¢çš„注释是用æ¥æ述预期的编译器错误或警告的。 +数字范围表示错误å‘生在æºä»£ç ä¸­çš„ä½ç½®ã€‚ +如果您希望åˆçº¦åœ¨ç¼–译时没有任何错误或警告,您å¯ä»¥ä¸ä½¿ç”¨åˆ†éš”符和åŽé¢çš„注释。 -In the above example, the state variable ``variable`` was declared twice, which is not allowed. This results in a ``DeclarationError`` stating that the identifier was already declared. +在上é¢çš„例å­ä¸­ï¼ŒçŠ¶æ€å˜é‡ ``variable`` 被声明了两次,这是ä¸å…许的。这导致了一个 ``声明错误``,说明标识符已ç»è¢«å£°æ˜Žã€‚ -The ``isoltest`` tool is used for these tests and you can find it under ``./build/test/tools/``. It is an interactive tool which allows -editing of failing contracts using your preferred text editor. Let's try to break this test by removing the second declaration of ``variable``: +用æ¥è¿›è¡Œé‚£äº›æµ‹è¯•çš„工具å«åš ``isoltest``,å¯ä»¥åœ¨ ``./build/test/tools/`` 下找到。 +它是一个交互工具,å…许您使用您喜欢的文本编辑器编辑失败的åˆçº¦ã€‚ +让我们把第二个 ``variable`` 的声明去掉æ¥ä½¿æµ‹è¯•å¤±è´¥ï¼š .. code-block:: solidity @@ -216,9 +238,9 @@ editing of failing contracts using your preferred text editor. Let's try to brea uint256 variable; } // ---- - // DeclarationError: (36-52): Identifier already declared. + // 声明错误:(36-52)。标识符已被声明。 -Running ``./build/test/tools/isoltest`` again results in a test failure: +å†æ¬¡è¿è¡Œ ``./build/test/tools/isoltest`` 就会得到一个失败的测试: .. code-block:: text @@ -234,19 +256,26 @@ Running ``./build/test/tools/isoltest`` again results in a test failure: Success -``isoltest`` prints the expected result next to the obtained result, and also -provides a way to edit, update or skip the current contract file, or quit the application. +``isoltest`` 在获得的结果æ—边打å°å‡ºé¢„期的结果, +还æ供了一个编辑,更新,跳过当å‰åˆçº¦æ–‡ä»¶æˆ–退出应用程åºçš„办法。 -It offers several options for failing tests: +它为失败的测试æ供了几ç§é€‰æ‹©ï¼š +<<<<<<< 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 -All of these options apply to the current contract, except ``quit`` which stops the entire testing process. +所有这些选项都适用于当å‰çš„åˆçº¦ï¼Œé™¤äº† ``quit``,它å¯ä»¥åœæ­¢æ•´ä¸ªæµ‹è¯•è¿‡ç¨‹ã€‚ -Automatically updating the test above changes it to +在上边的情况自动更新åˆçº¦ä¼šæŠŠå®ƒå˜ä¸º .. code-block:: solidity @@ -255,7 +284,7 @@ Automatically updating the test above changes it to } // ---- -and re-run the test. It now passes again: +并é‡æ–°è¿è¡Œæµ‹è¯•ã€‚它将会通过: .. code-block:: text @@ -265,9 +294,9 @@ and re-run the test. It now passes again: .. note:: - Choose a name for the contract file that explains what it tests, e.g. ``double_variable_declaration.sol``. - Do not put more than one contract into a single file, unless you are testing inheritance or cross-contract calls. - Each file should test one aspect of your new feature. + 为åˆçº¦æ–‡ä»¶é€‰æ‹©ä¸€ä¸ªèƒ½è§£é‡Šå…¶æµ‹è¯•å†…容的å字,例如: ``double_variable_declaration.sol``。 + ä¸è¦æŠŠä¸€ä¸ªä»¥ä¸Šçš„åˆçº¦æ”¾åœ¨ä¸€ä¸ªæ–‡ä»¶ä¸­ï¼Œé™¤éžæ‚¨åœ¨æµ‹è¯•ç»§æ‰¿æˆ–è·¨åˆçº¦çš„调用。 + æ¯ä¸ªæ–‡ä»¶åº”该测试您的新功能的一个方é¢ã€‚ Command-line Tests ------------------ @@ -326,28 +355,27 @@ There are several kinds of command-line tests: - ``test.*``: a single script to run, usually ``test.sh`` or ``test.py``. The script must be executable. -Running the Fuzzer via AFL +通过 AFL è¿è¡Œ Fuzzer ========================== -Fuzzing is a technique that runs programs on more or less random inputs to find exceptional execution -states (segmentation faults, exceptions, etc). Modern fuzzers are clever and run a directed search -inside the input. We have a specialized binary called ``solfuzzer`` which takes source code as input -and fails whenever it encounters an internal compiler error, segmentation fault or similar, but -does not fail if e.g., the code contains an error. This way, fuzzing tools can find internal problems in the compiler. +Fuzzing 是一ç§æµ‹è¯•æŠ€æœ¯ï¼Œå®ƒå¯ä»¥é€šè¿‡è¿è¡Œå¤šå°‘ä¸ç­‰çš„éšæœºè¾“å…¥æ¥æ‰¾å‡ºå¼‚常的执行状æ€ï¼ˆç‰‡æ®µæ•…éšœã€å¼‚常等等)。 +现代的 fuzzer å·²ç»å¯ä»¥å¾ˆèªæ˜Žåœ°åœ¨è¾“入中进行直接的查询。 +我们有一个专门的程åºå«åš ``solfuzzer``,它å¯ä»¥å°†æºä»£ç ä½œä¸ºè¾“入, +当å‘生一个内部编译错误,片段故障或者类似的错误时失败,但当代ç åŒ…å«é”™è¯¯çš„时候则ä¸ä¼šå¤±è´¥ã€‚ +通过这ç§æ–¹æ³•ï¼Œfuzzing 工具å¯ä»¥æ‰¾åˆ°é‚£äº›ç¼–译级别的内部错误。 -We mainly use `AFL `_ for fuzzing. You need to download and -install the AFL packages from your repositories (afl, afl-clang) or build them manually. -Next, build Solidity (or just the ``solfuzzer`` binary) with AFL as your compiler: +我们主è¦ä½¿ç”¨ `AFL `_ æ¥è¿›è¡Œ fuzzing 测试。 +您需è¦æ‰‹å·¥ä¸‹è½½å’Œæž„建 AFL。然åŽç”¨ AFL 作为编译器æ¥æž„建 Solidity(或åªæ˜¯ ``solfuzzer`` 二进制文件): .. code-block:: bash cd build - # if needed + # 如果需è¦çš„è¯ make clean cmake .. -DCMAKE_C_COMPILER=path/to/afl-gcc -DCMAKE_CXX_COMPILER=path/to/afl-g++ make solfuzzer -At this stage, you should be able to see a message similar to the following: +在这个阶段,您应该能够看到类似以下的信æ¯ï¼š .. code-block:: text @@ -358,16 +386,16 @@ At this stage, you should be able to see a message similar to the following: [+] Instrumented 1949 locations (64-bit, non-hardened mode, ratio 100%). [100%] Linking CXX executable solfuzzer -If the instrumentation messages did not appear, try switching the cmake flags pointing to AFL's clang binaries: +如果指示信æ¯æ²¡æœ‰å‡ºçŽ°ï¼Œå°è¯•åˆ‡æ¢æŒ‡å‘AFLçš„clang二进制文件的cmake标志: .. code-block:: bash - # if previously failed + # 如果之å‰å¤±è´¥äº† make clean cmake .. -DCMAKE_C_COMPILER=path/to/afl-clang -DCMAKE_CXX_COMPILER=path/to/afl-clang++ make solfuzzer -Otherwise, upon execution the fuzzer halts with an error saying binary is not instrumented: +å¦åˆ™ï¼Œåœ¨æ‰§è¡Œæ—¶ï¼Œfuzzer 就会åœæ­¢ï¼Œå¹¶å‡ºçŽ°é”™è¯¯ï¼Œè¯´äºŒè¿›åˆ¶æ²¡æœ‰è¢«æ£€æµ‹åˆ°ã€‚ .. code-block:: text @@ -389,174 +417,178 @@ Otherwise, upon execution the fuzzer halts with an error saying binary is not in Location : check_binary(), afl-fuzz.c:6920 -Next, you need some example source files. This makes it much easier for the fuzzer -to find errors. You can either copy some files from the syntax tests or extract test files -from the documentation or the other tests: +接下æ¥ï¼Œæ‚¨éœ€è¦ä¸€äº›ç¤ºä¾‹æºæ–‡ä»¶ã€‚这使得 fuzzer 更容易å‘现错误。 +您å¯ä»¥ä»Žè¯­æ³•æµ‹è¯•ä¸­å¤åˆ¶ä¸€äº›æ–‡ä»¶ï¼Œæˆ–者从文档或其他测试中æå–测试文件。 .. code-block:: bash mkdir /tmp/test_cases cd /tmp/test_cases - # extract from tests: + # 从测试中æå–: path/to/solidity/scripts/isolate_tests.py path/to/solidity/test/libsolidity/SolidityEndToEndTest.cpp - # extract from documentation: + # 从文件中摘录: 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 -Now run the fuzzer (the ``-m`` extends the size of memory to 60 MB): +现在è¿è¡Œ fuzzer( ``-m`` å‚数将使用的内存大å°æ‰©å±•ä¸º 60 MB): .. code-block:: bash afl-fuzz -m 60 -i /tmp/test_cases -o /tmp/fuzzer_reports -- /path/to/solfuzzer -The fuzzer creates source files that lead to failures in ``/tmp/fuzzer_reports``. -Often it finds many similar source files that produce the same error. You can -use the tool ``scripts/uniqueErrors.sh`` to filter out the unique errors. +fuzzer 会将导致失败的æºæ–‡ä»¶åˆ›å»ºåœ¨ ``/tmp/fuzzer_reports`` 中。 +通常它会找到产生相似错误的类似的æºæ–‡ä»¶ã€‚ +您å¯ä»¥ä½¿ç”¨ ``scripts/uniqueErrors.sh`` 工具æ¥é‚£äº›ç‹¬ç‰¹çš„错误。 -Whiskers -======== +Whiskers 系统 +============= -*Whiskers* is a string templating system similar to `Mustache `_. It is used by the -compiler in various places to aid readability, and thus maintainability and verifiability, of the code. +*Whiskers* 是一个类似于 `Mustache `_ 的字符串模æ¿åŒ–系统。 +它被编译器用在ä¸åŒçš„地方,以帮助代ç çš„å¯è¯»æ€§ï¼Œä»Žè€Œå¸®åŠ©ä»£ç çš„å¯ç»´æŠ¤æ€§å’Œå¯éªŒè¯æ€§ã€‚ -The syntax comes with a substantial difference to Mustache. The template markers ``{{`` and ``}}`` are -replaced by ``<`` and ``>`` in order to aid parsing and avoid conflicts with :ref:`yul` -(The symbols ``<`` and ``>`` are invalid in inline assembly, while ``{`` and ``}`` are used to delimit blocks). -Another limitation is that lists are only resolved one depth and they do not recurse. This may change in the future. +该语法与Mustache有很大区别。模æ¿æ ‡è®° ``{{`` å’Œ ``}}`` 被 ``<`` å’Œ ``>`` å–代, +以帮助解æžå¹¶é¿å…与 :ref:`yul` çš„å†²çª +ï¼ˆç¬¦å· ``<`` å’Œ ``>`` 在内è”汇编中是无效的,而 ``{`` å’Œ ``}`` 是用æ¥é™å®šå—的)。 +å¦ä¸€ä¸ªé™åˆ¶æ˜¯ï¼Œåˆ—表åªèƒ½è§£å†³ä¸€ä¸ªæ·±åº¦çš„问题,而且它们ä¸ä¼šé€’归。这在将æ¥å¯èƒ½ä¼šæ”¹å˜ã€‚ -A rough specification is the following: +下é¢æ˜¯ä¸€ä¸ªç²—略的说明: -Any occurrence of ```` is replaced by the string-value of the supplied variable ``name`` without any -escaping and without iterated replacements. An area can be delimited by ``<#name>...``. It is replaced -by as many concatenations of its contents as there were sets of variables supplied to the template system, -each time replacing any ```` items by their respective value. Top-level variables can also be used -inside such areas. +任何出现的 ```` 的地方都会被æ供的å˜é‡ ``name`` 的字符串值替æ¢ï¼Œæ²¡æœ‰ä»»ä½•è½¬ä¹‰ï¼Œä¹Ÿæ²¡æœ‰è¿­ä»£æ›¿æ¢ã€‚ +å¯ä»¥ç”¨ ``<#name>...`` æ¥åˆ’定一个区域。 +该区域中的内容将进行多次拼接,æ¯æ¬¡æ‹¼æŽ¥ä¼šä½¿ç”¨ç›¸åº”å˜é‡é›†ä¸­çš„值替æ¢åŒºåŸŸä¸­çš„ ```` 项, +模æ¿ç³»ç»Ÿä¸­æ供了多少组å˜é‡é›†ï¼Œå°±ä¼šè¿›è¡Œå¤šå°‘次拼接。顶层å˜é‡ä¹Ÿå¯ä»¥åœ¨è¿™ç§åŒºåŸŸå†…使用。 -There are also conditionals of the form ``......``, where template replacements -continue recursively either in the first or the second segment depending on the value of the boolean -parameter ``name``. If ``......`` is used, then the check is whether -the string parameter ``name`` is non-empty. +还有一些判断æ¡ä»¶çš„è¡¨è¾¾å¼ ``...``, +æ ¹æ®å¸ƒå°”å‚æ•° ``name`` 的值,会在第一段或第二段继续递归地替æ¢æ¨¡æ¿ã€‚ +如果使用 ``......`` è¿™ç§è¡¨è¾¾å¼ï¼Œé‚£ä¹ˆæ£€æŸ¥çš„是字符串å‚æ•° ``name`` 是å¦ä¸ºéžç©ºã€‚ .. _documentation-style: -Documentation Style Guide +æ–‡æ¡£é£Žæ ¼æŒ‡å— ========================= -In the following section you find style recommendations specifically focusing on documentation -contributions to Solidity. +在下é¢çš„部分,您å¯ä»¥æ‰¾åˆ°ä¸“门针对 Solidity 文档贡献的风格建议。 -English Language +英语 ---------------- -Use International English, unless using project or brand names. Try to reduce the usage of -local slang and references, making your language as clear to all readers as possible. -Below are some references to help: +使用国际英语,除éžä½¿ç”¨é¡¹ç›®æˆ–å“牌å称。 +å°½é‡å‡å°‘使用当地的俚语和å‚考文化,尽é‡ä½¿æ‚¨çš„语言对所有的读者都尽å¯èƒ½æ¸…晰。 +以下是一些å‚考资料,希望对大家有所帮助: -* `Simplified technical English `_ -* `International English `_ +* `简化技术英语 `_ +* `国际英语 `_ .. note:: - While the official Solidity documentation is written in English, there are community contributed :ref:`translations` - in other languages available. Please refer to the `translation guide `_ - for information on how to contribute to the community translations. + 虽然官方的 Solidity 文档是用英语写的,但也有社区贡献的其他语言的 :ref:`translations` å¯ç”¨ã€‚ + 请å‚考 `ç¿»è¯‘æŒ‡å— `_ + 以了解如何为社区翻译作出贡献。 -Title Case for Headings +标题的大å°å†™ ----------------------- -Use `title case `_ for headings. This means capitalise all principal words in -titles, but not articles, conjunctions, and prepositions unless they start the -title. +在标题中使用 `标题大å°å†™ `_。 +è¿™æ„味ç€æ ‡é¢˜ä¸­çš„所有主è¯éƒ½è¦å¤§å†™ï¼Œä½†ä¸åŒ…括冠è¯ï¼Œè¿žæŽ¥è¯å’Œä»‹è¯ï¼Œé™¤éžå®ƒä»¬æ˜¯æ ‡é¢˜çš„开头。 -For example, the following are all correct: +例如,下列å„项都是正确的: * Title Case for Headings. * For Headings Use Title Case. * Local and State Variable Names. * Order of Layout. -Expand Contractions +扩写缩写 ------------------- -Use expanded contractions for words, for example: +使用扩展的缩略语æ¥è¡¨è¾¾å•è¯ï¼Œä¾‹å¦‚: -* "Do not" instead of "Don't". -* "Can not" instead of "Can't". +* "Do not" 替代 "Don't"。 +* "Can not" 替代 "Can't"。 -Active and Passive Voice +ä¸»åŠ¨å’Œè¢«åŠ¨è¯­æ€ ------------------------ -Active voice is typically recommended for tutorial style documentation as it -helps the reader understand who or what is performing a task. However, as the -Solidity documentation is a mixture of tutorials and reference content, passive -voice is sometimes more applicable. +主动语æ€é€šå¸¸è¢«æŽ¨è用于教程风格的文档,因为它有助于读者ç†è§£è°æˆ–什么在执行一项任务。 +然而,由于 Solidity 文档是教程和å‚考内容的混åˆç‰©ï¼Œè¢«åŠ¨è¯­æ€æœ‰æ—¶æ›´é€‚用。 -As a summary: +综上所述: -* Use passive voice for technical reference, for example language definition and internals of the Ethereum VM. -* Use active voice when describing recommendations on how to apply an aspect of Solidity. +* 在技术å‚考方é¢ä½¿ç”¨è¢«åŠ¨è¯­æ€ï¼Œä¾‹å¦‚语言定义和Ethereum虚拟机的内部情况。 +* 在æ述关于如何应用 Solidity æŸæ–¹é¢çš„建议时,使用主动语æ€ã€‚ -For example, the below is in passive voice as it specifies an aspect of Solidity: +例如,下é¢çš„内容是被动语æ€ï¼Œå› ä¸ºå®ƒæŒ‡å®šäº† Solidity 的一个方é¢ï¼š - Functions can be declared ``pure`` in which case they promise not to read - from or modify the state. + 函数å¯ä»¥è¢«å£°æ˜Žä¸º ``pure``,在这ç§æƒ…况下,它们承诺ä¸è¯»å–或修改状æ€ã€‚ -For example, the below is in active voice as it discusses an application of Solidity: +例如,下é¢æ˜¯ä¸»åŠ¨è¯­æ€ï¼Œå› ä¸ºå®ƒè®¨è®ºäº†Solidity的一个应用: - When invoking the compiler, you can specify how to discover the first element - of a path, and also path prefix remappings. + 在调用编译器时,您å¯ä»¥æŒ‡å®šå¦‚何å‘现一个路径的第一个元素,也å¯ä»¥æŒ‡å®šè·¯å¾„å‰ç¼€çš„é‡æ˜ å°„。 -Common Terms +常用术语 ------------ -* "Function parameters" and "return variables", not input and output parameters. +* “函数å‚数“ å’Œ “返回å˜é‡â€œï¼Œè€Œä¸æ˜¯è¾“入和输出å‚数。 -Code Examples +代ç ç¤ºä¾‹ ------------- -A CI process tests all code block formatted code examples that begin with ``pragma solidity``, ``contract``, ``library`` -or ``interface`` using the ``./test/cmdlineTests.sh`` script when you create a PR. If you are adding new code examples, -ensure they work and pass tests before creating the PR. +CI进程在您创建PR时,使用 ``./test/cmdlineTests.sh`` 脚本测试所有 +以 ``pragma solidity``, ``contract``, ``library`` 或 ``interface`` 开头的代ç å—æ ¼å¼çš„示例代ç ã€‚ +如果您正在添加新的代ç å®žä¾‹ï¼Œåœ¨åˆ›å»ºPR之å‰ç¡®ä¿å®ƒä»¬èƒ½å¤Ÿå·¥ä½œå¹¶é€šè¿‡æµ‹è¯•ã€‚ -Ensure that all code examples begin with a ``pragma`` version that spans the largest where the contract code is valid. -For example ``pragma solidity >=0.4.0 <0.9.0;``. +ç¡®ä¿æ‰€æœ‰çš„代ç å®žä¾‹ä»¥ ``pragma`` 版本开始,跨越åˆçº¦ä»£ç æœ‰æ•ˆçš„最大范围。 +例如 ``pragma solidity >=0.4.0 <0.9.0;``。 -Running Documentation Tests +è¿è¡Œæ–‡æ¡£æµ‹è¯• --------------------------- -Make sure your contributions pass our documentation tests by running ``./docs/docs.sh`` that installs dependencies -needed for documentation and checks for any problems such as broken links or syntax issues. +通过è¿è¡Œ ``./scripts/docs.sh`` æ¥ç¡®ä¿æ‚¨çš„贡献通过我们的文档测试, +它安装了文档所需的ä¾èµ–,并检查是å¦å­˜åœ¨é—®é¢˜ï¼Œå¦‚无效的链接或语法问题。 .. _solidity_language_design: -Solidity Language Design +Solidity语言设计 ======================== -To actively get involved in the language design process and to share your ideas concerning the future of Solidity, -please join the `Solidity forum `_. +为了积æžå‚与语言设计过程,并分享您关于 Solidity 未æ¥çš„想法,请加入 `Solidity è®ºå› `_。 -The Solidity forum serves as the place to propose and discuss new language features and their implementation in -the early stages of ideation or modifications of existing features. +Solidity论å›ä½œä¸ºæ出和讨论新的语言功能åŠå…¶åœ¨æ—©æœŸæž„æ€é˜¶æ®µçš„实现或现有功能的修改的一个地方。 -As soon as proposals get more tangible, their -implementation will also be discussed in the `Solidity GitHub repository `_ -in the form of issues. +一旦æ案å˜å¾—更加具体, +它们的实施也将在 `Solidity GitHub仓库 `_ 中以问题的形å¼è®¨è®ºã€‚ -In addition to the forum and issue discussions, we regularly host language design discussion calls in which selected -topics, issues or feature implementations are debated in detail. The invitation to those calls is shared via the forum. +除了论å›å’Œé—®é¢˜è®¨è®ºä¹‹å¤–,我们还定期举办语言设计讨论会议,对选定的主题,问题或功能实现进行详细的辩论。 +这些会议的邀请函通过论å›å…±äº«ã€‚ -We are also sharing feedback surveys and other content that is relevant to language design in the forum. +我们也在论å›ä¸­åˆ†äº«å馈调查和其他与语言设计相关的内容。 -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 `_. +<<<<<<< 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 -For ad-hoc cases and questions, you can reach out to us via the `Solidity-dev Gitter channel `_ — a -dedicated chatroom for conversations around the Solidity compiler and language development. +对于特殊情况和问题,您å¯ä»¥é€šè¿‡ `Solidity-dev Gitter é¢‘é“ `_ 与我们è”系, +- 这是一个专门用于围绕 Solidity 编译器和语言开å‘çš„èŠå¤©å®¤ã€‚ -We are happy to hear your thoughts on how we can improve the language design process to be even more collaborative and transparent. +我们很高兴å¬åˆ°æ‚¨å¯¹æˆ‘们如何改进语言设计过程,使之更加å作和é€æ˜Žçš„想法。 diff --git a/docs/control-structures.rst b/docs/control-structures.rst index ea8a9c569de1..2711e4c4cc38 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -1,89 +1,81 @@ -################################## -Expressions and Control Structures -################################## +################### +表达å¼å’ŒæŽ§åˆ¶ç»“æž„ +################### .. index:: ! parameter, parameter;input, parameter;output, function parameter, parameter;function, return variable, variable;return, return .. index:: if, else, while, do/while, for, break, continue, return, switch, goto -Control Structures +控制结构 =================== -Most of the control structures known from curly-braces languages are available in Solidity: +大多数从大括å·è¯­è¨€ä¸­çŸ¥é“的控制结构都å¯ä»¥åœ¨Solidity中使用: -There is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, with -the usual semantics known from C or JavaScript. +有: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, +这些在 C 或者 JavaScript 中表达相åŒè¯­ä¹‰çš„关键è¯ã€‚ -Solidity also supports exception handling in the form of ``try``/``catch``-statements, -but only for :ref:`external function calls ` and -contract creation calls. Errors can be created using the :ref:`revert statement `. +Solidityä¹Ÿæ”¯æŒ ``try`` / ``catch`` å½¢å¼çš„语å¥çš„异常处ç†ï¼Œ +但åªé€‚用于 :ref:`外部函数调用 ` å’Œåˆçº¦åˆ›å»ºè°ƒç”¨ã€‚ +å¯ä»¥ä½¿ç”¨ :ref:`æ¢å¤çŠ¶æ€ ` æ¥åˆ›å»ºé”™è¯¯ã€‚ -Parentheses can *not* be omitted for conditionals, but curly braces can be omitted -around single-statement bodies. +æ¡ä»¶å¥ *ä¸èƒ½* çœç•¥æ‹¬å·ï¼Œä½†å•å¥ä½“周围å¯ä»¥çœç•¥å¤§æ‹¬å·ã€‚ -Note that there is no type conversion from non-boolean to boolean types as -there is in C and JavaScript, so ``if (1) { ... }`` is *not* valid -Solidity. +请注æ„,没有åƒCå’ŒJavaScript那样从éžå¸ƒå°”类型到布尔类型的类型转æ¢ï¼Œ +所以 ``if (1) { ... }`` 在Solidity *ä¸æ˜¯* 有效的。 .. index:: ! function;call, function;internal, function;external .. _function-calls: -Function Calls -============== +函数调用 +========= .. _internal-function-calls: -Internal Function Calls ------------------------ +内部函数调用 +-------------- -Functions of the current contract can be called directly ("internally"), also recursively, as seen in -this nonsensical example: +当å‰åˆçº¦ä¸­çš„函数å¯ä»¥ç›´æŽ¥ï¼ˆâ€œä»Žå†…部â€ï¼‰è°ƒç”¨ï¼Œä¹Ÿå¯ä»¥é€’归调用,就åƒä¸‹è¾¹è¿™ä¸ªè’谬的例å­ä¸€æ ·ï¼š .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.22 <0.9.0; - // This will report a warning + // 这会有一个警告 contract C { function g(uint a) public pure returns (uint ret) { return a + f(); } function f() internal pure returns (uint ret) { return g(7) + f(); } } -These function calls are translated into simple jumps inside the EVM. This has -the effect that the current memory is not cleared, i.e. passing memory references -to internally-called functions is very efficient. Only functions of the same -contract instance can be called internally. +这些函数调用在EVM内部被转化为简å•çš„跳转。 +这样åšçš„效果是,当å‰çš„内存ä¸ä¼šè¢«æ¸…空,也就是说, +将内存引用传递给内部调用的函数是éžå¸¸æœ‰æ•ˆçš„。 +但åªæœ‰åŒä¸€åˆçº¦å®žä¾‹çš„函数å¯ä»¥è¢«å†…部调用。 -You should still avoid excessive recursion, as every internal function call -uses up at least one stack slot and there are only 1024 slots available. +您还是应该é¿å…过度的递归调用,因为æ¯ä¸ªå†…部函数的调用都会å ç”¨è‡³å°‘一个堆栈槽,而å¯ç”¨çš„堆栈槽åªæœ‰1024个。 .. _external-function-calls: -External Function Calls ------------------------ +外部函数调用 +------------- -Functions can also be called using the ``this.g(8);`` and ``c.g(2);`` notation, where -``c`` is a contract instance and ``g`` is a function belonging to ``c``. -Calling the function ``g`` via either way results in it being called "externally", using a -message call and not directly via jumps. -Please note that function calls on ``this`` cannot be used in the constructor, -as the actual contract has not been created yet. +函数也å¯ä»¥ä½¿ç”¨ ``this.g(8);`` å’Œ ``c.g(2);`` 符å·æ¥è°ƒç”¨ï¼Œ +其中 ``c`` 是一个åˆçº¦å®žä¾‹ï¼Œ ``g`` 是属于 ``c`` 的函数。 +通过这两ç§æ–¹å¼è°ƒç”¨å‡½æ•° ``g`` 会导致它被 “外部†调用, +使用消æ¯è°ƒç”¨è€Œä¸æ˜¯ç›´æŽ¥é€šè¿‡è·³è½¬ã€‚ +请注æ„,对 ``this`` 的函数调用ä¸èƒ½åœ¨æž„造函数中使用,因为实际的åˆçº¦è¿˜æ²¡æœ‰è¢«åˆ›å»ºã€‚ -Functions of other contracts have to be called externally. For an external call, -all function arguments have to be copied to memory. +其他åˆçº¦çš„函数必须被外部调用。对于一个外部调用, +所有的函数å‚数都必须被拷è´åˆ°å†…存中。 .. note:: - A function call from one contract to another does not create its own transaction, - it is a message call as part of the overall transaction. + 从一个åˆçº¦åˆ°å¦ä¸€ä¸ªåˆçº¦çš„函数调用并ä¸åˆ›å»ºè‡ªå·±çš„交易,它是作为整个交易的一部分的消æ¯è°ƒç”¨ã€‚ -When calling functions of other contracts, you can specify the amount of Wei or -gas sent with the call with the special options ``{value: 10, gas: 10000}``. -Note that it is discouraged to specify gas values explicitly, since the gas costs -of opcodes can change in the future. Any Wei you send to the contract is added -to the total balance of that contract: +当调用其他åˆçº¦çš„函数时,您å¯ä»¥ç”¨ç‰¹æ®Šçš„选项 ``{value: 10, gas: 10000}`` 指定éšè°ƒç”¨å‘é€çš„Wei或气体(gas)数é‡ã€‚ +请注æ„,ä¸é¼“励明确指定气体值,因为æ“作ç çš„气体æˆæœ¬å¯èƒ½åœ¨æœªæ¥å‘生å˜åŒ–。 +您å‘é€ç»™åˆçº¦çš„任何Wei都会被添加到该åˆçº¦çš„总余é¢ä¸­ï¼š .. code-block:: solidity @@ -100,63 +92,53 @@ to the total balance of that contract: function callFeed() public { feed.info{value: 10, gas: 800}(); } } -You need to use the modifier ``payable`` with the ``info`` function because -otherwise, the ``value`` option would not be available. +您需è¦å¯¹ ``info`` 函数使用修饰符 ``payable``, +因为ä¸è¿™æ ·çš„è¯ï¼Œ ``value`` 选项则ä¸å¯ç”¨ã€‚ .. warning:: - Be careful that ``feed.info{value: 10, gas: 800}`` only locally sets the - ``value`` and amount of ``gas`` sent with the function call, and the - parentheses at the end perform the actual call. So - ``feed.info{value: 10, gas: 800}`` does not call the function and - the ``value`` and ``gas`` settings are lost, only - ``feed.info{value: 10, gas: 800}()`` performs the function call. - -Due to the fact that the EVM considers a call to a non-existing contract to -always succeed, Solidity uses the ``extcodesize`` opcode to check that -the contract that is about to be called actually exists (it contains code) -and causes an exception if it does not. This check is skipped if the return -data will be decoded after the call and thus the ABI decoder will catch the -case of a non-existing contract. - -Note that this check is not performed in case of :ref:`low-level calls ` which -operate on addresses rather than contract instances. + æ³¨æ„ ``feed.info{value: 10, gas: 800}`` åªåœ¨æœ¬åœ°è®¾ç½® ``value`` å’Œéšå‡½æ•°è°ƒç”¨å‘é€çš„ ``gas`` æ•°é‡ï¼Œ + 最åŽçš„括å·æ‰§è¡Œå®žé™…调用。所以 ``feed.info{value: 10, gas: 800}`` ä¸ä¼šè°ƒç”¨å‡½æ•°ï¼Œ + ``value`` å’Œ ``gas`` 的设置也会丢失, + åªæœ‰ ``feed.info{value: 10, gas: 800}()`` 执行了函数调用。 + +由于EVM认为对一个ä¸å­˜åœ¨çš„åˆçº¦çš„调用总是æˆåŠŸçš„, +Solidity使用 ``extcodesize`` æ“作ç æ¥æ£€æŸ¥å³å°†è¢«è°ƒç”¨çš„åˆçº¦æ˜¯å¦çœŸçš„存在(它包å«ä»£ç ï¼‰ï¼Œ +如果ä¸å­˜åœ¨å°±ä¼šå¼•èµ·å¼‚常。如果返回数æ®å°†åœ¨è°ƒç”¨åŽè¢«è§£ç ï¼Œ +则跳过该检查,因此ABI解ç å™¨å°†æ•èŽ·ä¸å­˜åœ¨çš„åˆçº¦çš„情况。 + +请注æ„,这个检查在 :ref:`低级调用 ` 的情况下ä¸æ‰§è¡Œï¼Œ +这些调用是对地å€è€Œä¸æ˜¯åˆçº¦å®žä¾‹è¿›è¡Œæ“作。 .. note:: - Be careful when using high-level calls to - :ref:`precompiled contracts `, - since the compiler considers them non-existing according to the - above logic even though they execute code and can return data. + 在对 :ref:`预编译åˆçº¦ ` 使用高级调用时è¦å°å¿ƒï¼Œ + 因为根æ®ä¸Šè¿°é€»è¾‘,编译器认为它们ä¸å­˜åœ¨ï¼Œå³ä½¿å®ƒä»¬æ‰§è¡Œä»£ç å¹¶å¯ä»¥è¿”回数æ®ã€‚ -Function calls also cause exceptions if the called contract itself -throws an exception or goes out of gas. +如果被调用的åˆçº¦æœ¬èº«æŠ›å‡ºå¼‚常或超出了gas值,函数调用也会引起异常。 .. warning:: - Any interaction with another contract imposes a potential danger, especially - if the source code of the contract is not known in advance. The - current contract hands over control to the called contract and that may potentially - do just about anything. Even if the called contract inherits from a known parent contract, - the inheriting contract is only required to have a correct interface. The - implementation of the contract, however, can be completely arbitrary and thus, - pose a danger. In addition, be prepared in case it calls into other contracts of - your system or even back into the calling contract before the first - call returns. This means - that the called contract can change state variables of the calling contract - via its functions. Write your functions in a way that, for example, calls to - external functions happen after any changes to state variables in your contract - so your contract is not vulnerable to a reentrancy exploit. + 与å¦ä¸€ä¸ªåˆçº¦çš„任何互动都会带æ¥æ½œåœ¨çš„å±é™©ï¼Œ + 特别是当åˆçº¦çš„æºä»£ç äº‹å…ˆä¸çŸ¥é“的时候。 + 当å‰çš„åˆçº¦å°†æŽ§åˆ¶æƒäº¤ç»™äº†è¢«è°ƒç”¨çš„åˆçº¦ï¼Œè€Œè¿™æœ‰å¯èƒ½åšä»»ä½•äº‹æƒ…。 + å³ä½¿è¢«è°ƒç”¨çš„åˆçº¦ç»§æ‰¿è‡ªä¸€ä¸ªå·²çŸ¥çš„父åˆçº¦ï¼Œ + 继承的åˆçº¦ä¹Ÿåªéœ€è¦æœ‰ä¸€ä¸ªæ­£ç¡®çš„接å£ã€‚ + 然而,åˆçº¦çš„实现完全å¯ä»¥æ˜¯ä»»æ„的,因此这会带æ¥å±é™©ã€‚ + 此外,è¦åšå¥½å‡†å¤‡ï¼Œä»¥é˜²å®ƒè°ƒç”¨åˆ°æ‚¨ç³»ç»Ÿä¸­çš„其他åˆçº¦ï¼Œ + 甚至在第一次调用返回之å‰å°±å›žåˆ°è°ƒç”¨åˆçº¦ä¸­ã€‚ + è¿™æ„味ç€è¢«è°ƒç”¨çš„åˆçº¦å¯ä»¥é€šè¿‡è¿™ä¸ªå‡½æ•°æ”¹å˜è°ƒç”¨åˆçº¦çš„状æ€å˜é‡ã€‚ + 编写您的函数时,例如,对外部函数的调用å‘生在对您的åˆçº¦ä¸­çš„状æ€å˜é‡çš„任何改å˜ä¹‹åŽï¼Œ + 这样您的åˆçº¦å°±ä¸ä¼šå—到é‡å…¥æ€§æ¼æ´žçš„攻击。 .. note:: - Before Solidity 0.6.2, the recommended way to specify the value and gas was to - use ``f.value(x).gas(g)()``. This was deprecated in Solidity 0.6.2 and is no - longer possible since Solidity 0.7.0. + 在 Solidity 0.6.2 之å‰ï¼ŒæŒ‡å®šä»¥å¤ªå€¼å’Œæ°”体值的推è方法是 + 使用 ``f.value(x).gas(g)()``。这在Solidity 0.6.2中被废弃, + 并且从Solidity 0.7.0开始ä¸å†æ”¯æŒã€‚ -Function Calls with Named Parameters ------------------------------------- +带命åå‚数的函数调用 +---------------------- -Function call arguments can be given by name, in any order, -if they are enclosed in ``{ }`` as can be seen in the following -example. The argument list has to coincide by name with the list of -parameters from the function declaration, but can be in arbitrary order. +函数调用å‚æ•°å¯ä»¥ç”¨åå­—æ¥è¡¨ç¤ºï¼Œå¦‚果用 ``{ }`` 括起æ¥çš„è¯ï¼Œ +å¯ä»¥ç”¨ä»»ä½•é¡ºåºï¼Œå¦‚下é¢çš„例å­æ‰€ç¤ºã€‚ +å‚数列表在å称上必须与函数声明中的å‚数列表相一致,但å¯ä»¥æœ‰ä»»æ„的顺åºã€‚ .. code-block:: solidity @@ -175,13 +157,12 @@ parameters from the function declaration, but can be in arbitrary order. } } -Omitted Names in Function Definitions -------------------------------------- +函数定义中çœç•¥çš„å称 +-------------------- -The names of parameters and return values in the function declaration can be omitted. -Those items with omitted names will still be present on the stack, but they are -inaccessible by name. An omitted return value name -can still return a value to the caller by use of the ``return`` statement. +函数声明中的å‚数和返回值的å称å¯ä»¥çœç•¥ã€‚ +那些å字被çœç•¥çš„å‚æ•°ä»ç„¶ä¼šå‡ºçŽ°åœ¨å †æ ˆä¸­ï¼Œä½†æ˜¯æ— æ³•é€šè¿‡å字访问。 +çœç•¥çš„返回值å称ä»ç„¶å¯ä»¥é€šè¿‡ä½¿ç”¨ ``return`` 语å¥å‘调用者返回一个值。 .. code-block:: solidity @@ -189,7 +170,7 @@ can still return a value to the caller by use of the ``return`` statement. pragma solidity >=0.4.22 <0.9.0; contract C { - // omitted name for parameter + // çœç•¥å‚æ•°å称 function func(uint k, uint) public pure returns(uint) { return k; } @@ -200,12 +181,12 @@ can still return a value to the caller by use of the ``return`` statement. .. _creating-contracts: -Creating Contracts via ``new`` -============================== +通过 ``new`` 创建åˆçº¦ +======================== -A contract can create other contracts using the ``new`` keyword. The full -code of the contract being created has to be known when the creating contract -is compiled so recursive creation-dependencies are not possible. +一个åˆçº¦å¯ä»¥ä½¿ç”¨ ``new`` 关键字创建其他åˆçº¦ã€‚ +待创建åˆçº¦çš„完整代ç å¿…须在创建的åˆçº¦è¢«ç¼–译时知é“, +所以递归的创建ä¾èµ–是ä¸å¯èƒ½çš„。 .. code-block:: solidity @@ -219,7 +200,7 @@ is compiled so recursive creation-dependencies are not possible. } contract C { - D d = new D(4); // will be executed as part of C's constructor + D d = new D(4); // 将作为åˆçº¦ C 构造函数的一部分执行 function createD(uint arg) public { D newD = new D(arg); @@ -227,40 +208,33 @@ is compiled so recursive creation-dependencies are not possible. } function createAndEndowD(uint arg, uint amount) public payable { - // Send ether along with the creation + // éšåˆçº¦çš„创建å‘é€ ether D newD = new D{value: amount}(arg); newD.x(); } } -As seen in the example, it is possible to send Ether while creating -an instance of ``D`` using the ``value`` option, but it is not possible -to limit the amount of gas. -If the creation fails (due to out-of-stack, not enough balance or other problems), -an exception is thrown. +正如在例å­ä¸­æ‰€çœ‹åˆ°çš„,在使用 ``value`` 选项创建 ``D`` 的实例时, +å¯ä»¥å‘é€ä»¥å¤ªï¼Œä½†ä¸å¯èƒ½é™åˆ¶æ°”体的数é‡ã€‚ +如果创建失败(由于堆栈耗尽,没有足够的余é¢æˆ–其他问题),会抛出一个异常。 -Salted contract creations / create2 +加ç›åˆçº¦åˆ›å»º / create2 ----------------------------------- -When creating a contract, the address of the contract is computed from -the address of the creating contract and a counter that is increased with -each contract creation. +当创建一个åˆçº¦æ—¶ï¼Œåˆçº¦çš„地å€æ˜¯ç”±åˆ›å»ºåˆçº¦çš„地å€å’Œä¸€ä¸ªè®¡æ•°å™¨è®¡ç®—出æ¥çš„, +这个计数器在æ¯æ¬¡åˆ›å»ºåˆçº¦æ—¶éƒ½ä¼šå¢žåŠ ã€‚ -If you specify the option ``salt`` (a bytes32 value), then contract creation will -use a different mechanism to come up with the address of the new contract: +如果您指定了选项 ``salt`` (一个32字节的值), +那么åˆçº¦çš„创建将使用一ç§ä¸åŒçš„机制æ¥å¾—出新åˆçº¦çš„地å€ã€‚ -It will compute the address from the address of the creating contract, -the given salt value, the (creation) bytecode of the created contract and the constructor -arguments. +它将从创建åˆçº¦çš„地å€ã€ç»™å®šçš„ç›å€¼ã€åˆ›å»ºåˆçº¦çš„(创建)字节ç å’Œæž„造函数å‚数中计算出地å€ã€‚ -In particular, the counter ("nonce") is not used. This allows for more flexibility -in creating contracts: You are able to derive the address of the -new contract before it is created. Furthermore, you can rely on this address -also in case the creating -contracts creates other contracts in the meantime. +特别的是,计数器(“nonceâ€ï¼‰æ²¡æœ‰è¢«ä½¿ç”¨ã€‚这使得创建åˆçº¦æ—¶æœ‰æ›´å¤šçš„çµæ´»æ€§ã€‚ +您能够在新åˆçº¦åˆ›å»ºä¹‹å‰å¾—出它的地å€ã€‚此外,在创建åˆçº¦çš„åŒæ—¶åˆ›å»ºå…¶ä»–åˆçº¦çš„情况下, +您也å¯ä»¥ä¾èµ–这个地å€ã€‚ -The main use-case here is contracts that act as judges for off-chain interactions, -which only need to be created if there is a dispute. +这里的主è¦ç”¨ä¾‹æ˜¯åšä¸ºé“¾å¤–互动的评判的åˆçº¦ï¼Œ +åªæœ‰åœ¨æœ‰äº‰è®®çš„时候æ‰éœ€è¦åˆ›å»ºã€‚ .. code-block:: solidity @@ -275,9 +249,9 @@ which only need to be created if there is a dispute. contract C { function createDSalted(bytes32 salt, uint arg) public { - // This complicated expression just tells you how the address - // can be pre-computed. It is just there for illustration. - // You actually only need ``new D{salt: salt}(arg)``. + // 这个å¤æ‚的表达å¼åªæ˜¯å‘Šè¯‰æ‚¨å¦‚何预先计算出地å€ã€‚ + // 它åªæ˜¯ç”¨äºŽè¯´æ˜Žé—®é¢˜ã€‚ + // 实际上您åªéœ€è¦ ``new D{salt: salt}(arg)``。 address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked( bytes1(0xff), address(this), @@ -294,42 +268,35 @@ which only need to be created if there is a dispute. } .. warning:: - There are some peculiarities in relation to salted creation. A contract can be - re-created at the same address after having been destroyed. Yet, it is possible - for that newly created contract to have a different deployed bytecode even - though the creation bytecode has been the same (which is a requirement because - otherwise the address would change). This is due to the fact that the constructor - can query external state that might have changed between the two creations - and incorporate that into the deployed bytecode before it is stored. + 在用加ç›æ–¹å¼åˆ›å»ºåˆçº¦æ—¶ï¼Œæœ‰ä¸€äº›ç‰¹æ®Šæ€§ã€‚一个åˆçº¦å¯ä»¥åœ¨è¢«é”€æ¯åŽåœ¨åŒä¸€åœ°å€é‡æ–°åˆ›å»ºã€‚ + 然而,新创建的åˆçº¦æœ‰å¯èƒ½å…·æœ‰ä¸åŒçš„部署字节ç ï¼Œ + å³ä½¿åˆ›å»ºå­—节ç æ˜¯ç›¸åŒçš„(这是一个è¦æ±‚,å¦åˆ™åœ°å€ä¼šæ”¹å˜ï¼‰ã€‚ + 这是由于构造函数å¯ä»¥æŸ¥è¯¢åœ¨ä¸¤æ¬¡åˆ›å»ºä¹‹é—´å¯èƒ½å‘生å˜åŒ–的外部状æ€ï¼Œ + 并在存储之å‰å°†å…¶çº³å…¥éƒ¨ç½²å­—节ç ã€‚ -Order of Evaluation of Expressions -================================== +表达å¼è®¡ç®—é¡ºåº +================ -The evaluation order of expressions is not specified (more formally, the order -in which the children of one node in the expression tree are evaluated is not -specified, but they are of course evaluated before the node itself). It is only -guaranteed that statements are executed in order and short-circuiting for -boolean expressions is done. +表达å¼çš„计算顺åºä¸æ˜¯ç‰¹å®šçš„(更准确地说, +表达å¼æ ‘中æŸèŠ‚点的å­èŠ‚点间的计算顺åºä¸æ˜¯ç‰¹å®šçš„,但它们的结算肯定会在节点自己的结算之å‰ï¼‰ã€‚ +该规则åªèƒ½ä¿è¯è¯­å¥æŒ‰é¡ºåºæ‰§è¡Œï¼Œå¹¶å¯¹å¸ƒå°”表达å¼è¿›è¡ŒçŸ­è·¯å¤„ç†ã€‚ .. index:: ! assignment -Assignment -========== +赋值 +====== .. index:: ! assignment;destructuring -Destructuring Assignments and Returning Multiple Values -------------------------------------------------------- +解构赋值和返回多个值 +--------------------- -Solidity internally allows tuple types, i.e. a list of objects -of potentially different types whose number is a constant at -compile-time. Those tuples can be used to return multiple values at the same time. -These can then either be assigned to newly declared variables -or to pre-existing variables (or LValues in general). +Solidity 内部å…许元组 (tuple) 类型,也就是一个在编译时元素数é‡å›ºå®šçš„对象列表, +列表中的元素å¯ä»¥æ˜¯ä¸åŒç±»åž‹çš„对象。这些元组å¯ä»¥ç”¨æ¥åŒæ—¶è¿”回多个数值, +也å¯ä»¥ç”¨å®ƒä»¬æ¥åŒæ—¶èµ‹å€¼ç»™å¤šä¸ªæ–°å£°æ˜Žçš„å˜é‡æˆ–者既存的å˜é‡ï¼ˆæˆ–通常的 LValues): -Tuples are not proper types in Solidity, they can only be used to form syntactic -groupings of expressions. +在Solidity中,元组ä¸æ˜¯é€‚当的类型,它们åªèƒ½è¢«ç”¨æ¥æž„建表达å¼çš„语法分组。 .. code-block:: solidity @@ -344,38 +311,47 @@ groupings of expressions. } function g() public { - // Variables declared with type and assigned from the returned tuple, - // not all elements have to be specified (but the number must match). + // 用类型声明的å˜é‡ï¼Œå¹¶ä»Žè¿”回的元组中分é…, + // ä¸æ˜¯æ‰€æœ‰çš„元素都必须被指定(但数é‡å¿…须匹é…)。 (uint x, , uint y) = f(); - // Common trick to swap values -- does not work for non-value storage types. + // 交æ¢æ•°å€¼çš„常è§æŠ€å·§ -- 对éžæ•°å€¼å­˜å‚¨ç±»åž‹ä¸èµ·ä½œç”¨ã€‚ (x, y) = (y, x); - // Components can be left out (also for variable declarations). - (index, , ) = f(); // Sets the index to 7 + // 元素å¯ä»¥ä¸ä½¿ç”¨ï¼ˆä¹Ÿé€‚用于å˜é‡å£°æ˜Žï¼‰ã€‚ + (index, , ) = f(); // å°†index设置为 7 } } -It is not possible to mix variable declarations and non-declaration assignments, -i.e. the following is not valid: ``(x, uint y) = (1, 2);`` +ä¸å¯èƒ½æ··åˆä½¿ç”¨å£°æ˜Žå’Œéžå£°æ˜Žå˜é‡èµ‹å€¼ã€‚ +例如,下é¢çš„方法是无效的。 ``(x, uint y) = (1, 2);``。 .. note:: - Prior to version 0.5.0 it was possible to assign to tuples of smaller size, either - filling up on the left or on the right side (which ever was empty). This is - now disallowed, so both sides have to have the same number of components. + 在0.5.0版本之å‰ï¼Œç»™å…·æœ‰æ›´å°‘元素数的元组赋值都是å¯èƒ½çš„, + è¦ä¹ˆåœ¨å·¦è¾¹å¡«å……,è¦ä¹ˆåœ¨å³è¾¹å¡«å……(无论哪个是空的)。 + 现在这是ä¸å…许的,所以两边必须有相åŒæ•°é‡çš„元素。 .. 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 -Complications for Arrays and Structs ------------------------------------- +数组和结构体的å¤æ‚情况 +---------------------- +<<<<<<< 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 -In the example below the call to ``g(x)`` has no effect on ``x`` because it creates -an independent copy of the storage value in memory. However, ``h(x)`` successfully modifies ``x`` -because only a reference and not a copy is passed. +在下é¢çš„例å­ä¸­ï¼Œè°ƒç”¨ ``g(x)`` 对 ``x`` 没有影å“, +因为它在内存中创建了一个独立的存储值的副本。然而, ``h(x)`` æˆåŠŸåœ°ä¿®æ”¹äº† ``x``, +因为传递了一个引用而ä¸æ˜¯ä¸€ä¸ªæ‹·è´ã€‚ .. code-block:: solidity @@ -403,38 +379,31 @@ because only a reference and not a copy is passed. .. _default-value: -Scoping and Declarations -======================== +作用域和声明 +============== + +一个被声明的å˜é‡å°†æœ‰ä¸€ä¸ªåˆå§‹é»˜è®¤å€¼ï¼Œå…¶å­—节表示为所有的零。 +å˜é‡çš„ "默认值" 是任何类型的典型 "零状æ€"。 +例如, ``bool`` 的默认值是 ``false``。 +``uint`` 或 ``int`` 类型的默认值是 ``0``。 +对于é™æ€å¤§å°çš„数组和 ``bytes1`` 到 ``bytes32``, +æ¯ä¸ªå•ç‹¬çš„元素将被åˆå§‹åŒ–为与其类型相应的默认值。 +对于动æ€å¤§å°çš„数组, ``bytes`` å’Œ ``string``,默认值是一个空数组或字符串。 +对于 ``enum`` 类型,默认值是其第一个æˆå‘˜ã€‚ + +Solidity 中的作用域规则éµå¾ªäº† C99(与其他很多语言一样): +å˜é‡å°†ä¼šä»Žå®ƒä»¬è¢«å£°æ˜Žä¹‹åŽå¯è§ï¼Œç›´åˆ°ä¸€å¯¹ ``{ }`` å—的结æŸã€‚ +这一规则有个例外,在 for 循环语å¥ä¸­åˆå§‹åŒ–çš„å˜é‡ï¼Œå…¶å¯è§æ€§ä»…ç»´æŒåˆ° for 循环的结æŸã€‚ + +类似于å‚æ•°çš„å˜é‡ï¼ˆå‡½æ•°å‚æ•°ã€ä¿®æ”¹å™¨å‚æ•°ã€æ•èŽ·ï¼ˆcatch)å‚æ•°......) +在åŽé¢çš„代ç å—中是å¯è§çš„--对于函数和修改器å‚数,在函数/修改器的主体中, +对于æ•èŽ·å‚数,在æ•èŽ·å—中。 + +在代ç å—之外声明的å˜é‡ï¼Œä¾‹å¦‚函数ã€åˆçº¦ã€ç”¨æˆ·å®šä¹‰çš„类型等, +甚至在声明之å‰å°±å·²ç»å¯è§ã€‚ +è¿™æ„味ç€æ‚¨å¯ä»¥åœ¨å£°æ˜Žä¹‹å‰ä½¿ç”¨çŠ¶æ€å˜é‡ï¼Œå¹¶é€’归地调用函数。 -A variable which is declared will have an initial default -value whose byte-representation is all zeros. -The "default values" of variables are the typical "zero-state" -of whatever the type is. For example, the default value for a ``bool`` -is ``false``. The default value for the ``uint`` or ``int`` -types is ``0``. For statically-sized arrays and ``bytes1`` to -``bytes32``, each individual -element will be initialized to the default value corresponding -to its type. For dynamically-sized arrays, ``bytes`` -and ``string``, the default value is an empty array or string. -For the ``enum`` type, the default value is its first member. - -Scoping in Solidity follows the widespread scoping rules of C99 -(and many other languages): Variables are visible from the point right after their declaration -until the end of the smallest ``{ }``-block that contains the declaration. -As an exception to this rule, variables declared in the -initialization part of a for-loop are only visible until the end of the for-loop. - -Variables that are parameter-like (function parameters, modifier parameters, -catch parameters, ...) are visible inside the code block that follows - -the body of the function/modifier for a function and modifier parameter and the catch block -for a catch parameter. - -Variables and other items declared outside of a code block, for example functions, contracts, -user-defined types, etc., are visible even before they were declared. This means you can -use state variables before they are declared and call functions recursively. - -As a consequence, the following examples will compile without warnings, since -the two variables have the same name but disjoint scopes. +因此,下é¢çš„例å­åœ¨ç¼–译时ä¸ä¼šå‡ºçŽ°è­¦å‘Šï¼Œå› ä¸ºè¿™ä¸¤ä¸ªå˜é‡çš„å字虽然相åŒï¼Œä½†ä½œç”¨åŸŸä¸åŒã€‚ .. code-block:: solidity @@ -454,15 +423,15 @@ the two variables have the same name but disjoint scopes. } } -As a special example of the C99 scoping rules, note that in the following, -the first assignment to ``x`` will actually assign the outer and not the inner variable. -In any case, you will get a warning about the outer variable being shadowed. +作为 C99 作用域规则的特例,请注æ„在下边的例å­é‡Œï¼Œ +第一次对 ``x`` 的赋值实际上将赋给外层å˜é‡è€Œä¸æ˜¯å†…层å˜é‡ã€‚ +在任何情况下,您都会得到一个关于外部å˜é‡è¢«å½±å°„(译者注:就是说被在内部作用域中由一个åŒåå˜é‡æ‰€æ›¿ä»£ï¼‰çš„警告。 .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.5.0 <0.9.0; - // This will report a warning + // è¿™å°†æŠ¥å‘Šä¸€ä¸ªè­¦å‘Šä¿¡æ¯ contract C { function f() pure public returns (uint) { uint x = 1; @@ -475,16 +444,15 @@ In any case, you will get a warning about the outer variable being shadowed. } .. warning:: - Before version 0.5.0 Solidity followed the same scoping rules as - JavaScript, that is, a variable declared anywhere within a function would be in scope - for the entire function, regardless where it was declared. The following example shows a code snippet that used - to compile but leads to an error starting from version 0.5.0. + 在0.5.0版本之å‰ï¼ŒSolidityéµå¾ªä¸ŽJavaScript相åŒçš„作用域规则, + 也就是说,在一个函数中的任何地方声明的å˜é‡éƒ½ä¼šåœ¨æ•´ä¸ªå‡½æ•°çš„作用域中,ä¸ç®¡å®ƒæ˜¯åœ¨å“ªé‡Œå£°æ˜Žã€‚ + 下é¢çš„例å­æ˜¾ç¤ºäº†ä¸€ä¸ªæ›¾ç»å¯ä»¥ç¼–译的代ç ç‰‡æ®µï¼Œä½†ä»Ž0.5.0版本开始导致了一个错误。 .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.5.0 <0.9.0; - // This will not compile + // 这将无法编译 contract C { function f() pure public returns (uint) { x = 2; @@ -497,20 +465,22 @@ In any case, you will get a warning about the outer variable being shadowed. .. index:: ! safe math, safemath, checked, unchecked .. _unchecked: -Checked or Unchecked Arithmetic -=============================== +检查或ä¸æ£€æŸ¥çš„算术 +================== -An overflow or underflow is the situation where the resulting value of an arithmetic operation, -when executed on an unrestricted integer, falls outside the range of the result type. +上溢或下溢是指算术è¿ç®—的结果值,当对一个ä¸å—é™åˆ¶çš„整数执行时,超出了结果类型的范围。 -Prior to Solidity 0.8.0, arithmetic operations would always wrap in case of -under- or overflow leading to widespread use of libraries that introduce -additional checks. +在Solidity 0.8.0之å‰ï¼Œç®—术è¿ç®—总是在下溢或上溢的情况下被包起æ¥ï¼Œ +这导致广泛使用引入é¢å¤–检查的库。 -Since Solidity 0.8.0, all arithmetic operations revert on over- and underflow by default, -thus making the use of these libraries unnecessary. +从Solidity 0.8.0开始,在默认情况下所有的算术è¿ç®—都会在上溢和下溢时还原, +从而使这些库的使用å˜å¾—没有必è¦ã€‚ +<<<<<<< HEAD +为了获得以å‰çš„行为,å¯ä»¥ä½¿ç”¨ä¸€ä¸ª ``未检查(unchecked)`` 区å—。 +======= To obtain the previous behavior, an ``unchecked`` block can be used: +>>>>>>> english/develop .. code-block:: solidity @@ -518,159 +488,137 @@ To obtain the previous behavior, an ``unchecked`` block can be used: pragma solidity ^0.8.0; contract C { function f(uint a, uint b) pure public returns (uint) { - // This subtraction will wrap on underflow. + // 这个å‡æ³•å°†åœ¨ä¸‹æº¢æ—¶è¢«åŒ…èµ·æ¥ã€‚ unchecked { return a - b; } } function g(uint a, uint b) pure public returns (uint) { - // This subtraction will revert on underflow. + // 这个å‡æ³•åœ¨ä¸‹æº¢æ—¶å°†è¢«è¿˜åŽŸã€‚ return a - b; } } -The call to ``f(2, 3)`` will return ``2**256-1``, while ``g(2, 3)`` will cause -a failing assertion. +调用 ``f(2, 3)`` 将返回 ``2**256-1``,而 ``g(2, 3)`` 将导致一个失败的断言。 -The ``unchecked`` block can be used everywhere inside a block, but not as a replacement -for a block. It also cannot be nested. +``unchecked`` 代ç å—å¯ä»¥åœ¨ä»£ç å—内的任何地方使用,但ä¸èƒ½æ›¿ä»£ä»£ç å—。 +它也ä¸èƒ½è¢«åµŒå¥—。 -The setting only affects the statements that are syntactically inside the block. -Functions called from within an ``unchecked`` block do not inherit the property. +该设置åªå½±å“到在语法上ä½äºŽä»£ç å—内的语å¥ã€‚ +从 ``unchecked`` 代ç å—内调用的函数ä¸ç»§æ‰¿è¯¥å±žæ€§ã€‚ .. note:: - To avoid ambiguity, you cannot use ``_;`` inside an ``unchecked`` block. + 为了é¿å…歧义,您ä¸èƒ½åœ¨ä¸€ä¸ª ``unchecked`` 代ç å—内使用 ``_;``。 -The following operators will cause a failing assertion on overflow or underflow -and will wrap without an error if used inside an unchecked block: +以下è¿ç®—符在上溢或下溢时将导致一个失败的断言, +如果在一个未检查的代ç å—内使用,将被包裹而ä¸ä¼šå‡ºçŽ°é”™è¯¯ã€‚ -``++``, ``--``, ``+``, binary ``-``, unary ``-``, ``*``, ``/``, ``%``, ``**`` +``++``, ``--``, ``+``, 二进制 ``-``, å•è¿›åˆ¶ ``-``, ``*``, ``/``, ``%``, ``**`` -``+=``, ``-=``, ``*=``, ``/=``, ``%=`` +``+=``, ``-=``, ``*=``, ``/=``, ``%=`` .. warning:: - It is not possible to disable the check for division by zero - or modulo by zero using the ``unchecked`` block. + ä¸èƒ½ä½¿ç”¨ ``unchecked`` 代ç å—æ¥ç¦æ­¢æ£€æŸ¥é™¤ä»¥0或对0å–余数。 .. note:: - Bitwise operators do not perform overflow or underflow checks. - This is particularly visible when using bitwise shifts (``<<``, ``>>``, ``<<=``, ``>>=``) in - place of integer division and multiplication by a power of 2. - For example ``type(uint256).max << 3`` does not revert even though ``type(uint256).max * 8`` would. + ä½æ“作符ä¸æ‰§è¡Œä¸Šæº¢æˆ–下溢检查。 + 这在使用ä½æ“作符移ä½ï¼ˆ ``<<`` , ``>>``, ``<<=``, ``>>=``)æ¥ä»£æ›¿æ•´æ•°é™¤æ³•å’Œ2的幂次方时尤其明显。 + 例如 ``type(uint256).max << 3`` ä¸ä¼šæ¢å¤æ“作,尽管 ``type(uint256).max * 8`` 会æ¢å¤æ“作。 .. note:: - The second statement in ``int x = type(int).min; -x;`` will result in an overflow - because the negative range can hold one more value than the positive range. + ``int x = type(int).min; -x;`` 中的第二æ¡è¯­å¥å°†å¯¼è‡´æº¢å‡ºï¼Œ + 因为负数范围å¯ä»¥æ¯”正数范围多容纳一个值。 -Explicit type conversions will always truncate and never cause a failing assertion -with the exception of a conversion from an integer to an enum type. +明确的类型转æ¢å°†æ€»æ˜¯æˆªæ–­ï¼Œå¹¶ä¸”永远ä¸ä¼šå¯¼è‡´å¤±è´¥çš„断言,但从整数到枚举类型的转æ¢é™¤å¤–。 .. index:: ! exception, ! throw, ! assert, ! require, ! revert, ! errors .. _assert-and-require: -Error handling: Assert, Require, Revert and Exceptions +错误处ç†ï¼šAssert, Require, Revert and Exceptions ====================================================== -Solidity uses state-reverting exceptions to handle errors. -Such an exception undoes all changes made to the -state in the current call (and all its sub-calls) and -flags an error to the caller. +Solidity 使用状æ€æ¢å¤å¼‚常æ¥å¤„ç†é”™è¯¯ã€‚ +è¿™ç§å¼‚常将撤消对当å‰è°ƒç”¨ï¼ˆåŠå…¶æ‰€æœ‰å­è°ƒç”¨ï¼‰ä¸­çš„状æ€æ‰€åšçš„所有更改, +并且还å‘调用者标记错误。 -When exceptions happen in a sub-call, they "bubble up" (i.e., -exceptions are rethrown) automatically unless they are caught in -a ``try/catch`` statement. Exceptions to this rule are ``send`` -and the low-level functions ``call``, ``delegatecall`` and -``staticcall``: they return ``false`` as their first return value in case -of an exception instead of "bubbling up". +当异常å‘生在å­è°ƒç”¨ä¸­æ—¶ï¼Œå®ƒä»¬ä¼šè‡ªåŠ¨ "冒泡"(也就是说,异常被é‡æ–°æŠ›å‡ºï¼‰ï¼Œ +除éžå®ƒä»¬è¢« ``try/catch`` 语å¥æ•èŽ·ã€‚这个规则的例外是 ``send`` +和低级函数 ``call``, ``delegatecall`` å’Œ ``staticcall``: +它们在å‘生异常时返回 ``false`` 作为第一个返回值而ä¸æ˜¯ "冒泡"。 .. warning:: - The low-level functions ``call``, ``delegatecall`` and - ``staticcall`` return ``true`` as their first return value - if the account called is non-existent, as part of the design - of the EVM. Account existence must be checked prior to calling if needed. - -Exceptions can contain error data that is passed back to the caller -in the form of :ref:`error instances `. -The built-in errors ``Error(string)`` and ``Panic(uint256)`` are -used by special functions, as explained below. ``Error`` is used for "regular" error conditions -while ``Panic`` is used for errors that should not be present in bug-free code. - -Panic via ``assert`` and Error via ``require`` ----------------------------------------------- - -The convenience functions ``assert`` and ``require`` can be used to check for conditions and throw an exception -if the condition is not met. - -The ``assert`` function creates an error of type ``Panic(uint256)``. -The same error is created by the compiler in certain situations as listed below. - -Assert should only be used to test for internal -errors, and to check invariants. Properly functioning code should -never create a Panic, not even on invalid external input. -If this happens, then there -is a bug in your contract which you should fix. Language analysis -tools can evaluate your contract to identify the conditions and -function calls which will cause a Panic. - -A Panic exception is generated in the following situations. -The error code supplied with the error data indicates the kind of panic. - -#. 0x00: Used for generic compiler inserted panics. -#. 0x01: If you call ``assert`` with an argument that evaluates to false. -#. 0x11: If an arithmetic operation results in underflow or overflow outside of an ``unchecked { ... }`` block. -#. 0x12; If you divide or modulo by zero (e.g. ``5 / 0`` or ``23 % 0``). -#. 0x21: If you convert a value that is too big or negative into an enum type. -#. 0x22: If you access a storage byte array that is incorrectly encoded. -#. 0x31: If you call ``.pop()`` on an empty array. -#. 0x32: If you access an array, ``bytesN`` or an array slice at an out-of-bounds or negative index (i.e. ``x[i]`` where ``i >= x.length`` or ``i < 0``). -#. 0x41: If you allocate too much memory or create an array that is too large. -#. 0x51: If you call a zero-initialized variable of internal function type. - -The ``require`` function either creates an error without any data or -an error of type ``Error(string)``. It -should be used to ensure valid conditions -that cannot be detected until execution time. -This includes conditions on inputs -or return values from calls to external contracts. + 如果被调用的账户ä¸å­˜åœ¨ï¼Œä½Žçº§å‡½æ•° ``call``, ``delegatecall`` å’Œ ``staticcall`` + 的第一个返回值为 ``true``,这是EVM设计的一部分。 + 如果需è¦çš„è¯ï¼Œå¿…须在调用之å‰æ£€æŸ¥è´¦æˆ·æ˜¯å¦å­˜åœ¨ã€‚ + +异常å¯ä»¥åŒ…å«é”™è¯¯æ•°æ®ï¼Œä»¥ :ref:`错误实例 ` çš„å½¢å¼ä¼ å›žç»™è°ƒç”¨è€…。 +内置的错误 ``Error(string)`` å’Œ ``Panic(uint256)`` 被特殊函数使用, +解释如下。 ``Error`` 用于 "常规" 错误æ¡ä»¶ï¼Œè€Œ ``Panic`` 用于在无错误代ç ä¸­ä¸åº”该出现的错误。 + +通过 ``assert`` 引起Panic异常和通过 ``require`` 引起Error异常 +------------------------------------------------------------- + +å¿«æ·å‡½æ•° ``assert`` å’Œ ``require`` å¯ä»¥ç”¨æ¥æ£€æŸ¥æ¡ä»¶ï¼Œå¦‚æžœä¸ç¬¦åˆæ¡ä»¶å°±æŠ›å‡ºä¸€ä¸ªå¼‚常。 + +``assert`` 函数创建了一个 ``Panic(uint256)`` 类型的错误。 +在æŸäº›æƒ…况下,编译器也会产生åŒæ ·çš„错误,如下所述。 + +Assert应该åªç”¨äºŽæµ‹è¯•å†…部错误,以åŠæ£€æŸ¥ä¸å˜é‡ã€‚ +正确è¿è¡Œçš„代ç ä¸åº”该创建一个Panic异常,甚至在无效的外部输入时也ä¸åº”该。 +如果å‘生这ç§æƒ…况,那么您的åˆçº¦ä¸­å°±æœ‰ä¸€ä¸ªé”™è¯¯ï¼Œæ‚¨åº”该修å¤å®ƒã€‚ +语言分æžå·¥å…·å¯ä»¥è¯„估您的åˆçº¦ï¼Œä»¥ç¡®å®šä¼šå¯¼è‡´Panic异常的æ¡ä»¶å’Œå‡½æ•°è°ƒç”¨ã€‚ + +在下列情况下会产生一个Panic异常。 +与错误数æ®ä¸€èµ·æ供的错误代ç è¡¨æ˜ŽPanic异常的ç§ç±»ã€‚ + +#. 0x00: 用于一般的编译器æ’å…¥Panic异常的情况。 +#. 0x01: 如果您带å‚数调用 ``assert`` 时结果是false。 +#. 0x11: 如果一个算术è¿ç®—在一个 ``unchecked { ... }`` 代ç å—之外导致下溢或上溢。 +#. 0x12: 如果您对0åšé™¤æ³•æˆ–者å–余(例如 ``5 / 0`` 或者 ``23 % 0`` )。 +#. 0x21: 如果您把一个太大的或负数的值转æ¢æˆä¸€ä¸ªæžšä¸¾ç±»åž‹ã€‚ +#. 0x22: 如果您访问一个编ç ä¸æ­£ç¡®çš„存储字节数组。 +#. 0x31: 如果您在一个空数组上调用 ``.pop()``。 +#. 0x32: 如果您访问一个数组, ``bytesN`` æˆ–ä¸€ä¸ªæ•°ç»„åˆ‡ç‰‡ç´¢å¼•è¶…å‡ºæ•°ç»„é•¿åº¦æˆ–è´Ÿç´¢å¼•ï¼ˆå³ ``x[i]``,其中 ``i >= x.length`` 或 ``i < 0`` )。 +#. 0x41: 如果您分é…了太多的内存空间或创建了一个太大的数组。 +#. 0x51: 如果您调用一个零åˆå§‹åŒ–的内部函数类型的å˜é‡ã€‚ + +``require`` 函数è¦ä¹ˆåˆ›é€ ä¸€ä¸ªæ²¡æœ‰ä»»ä½•æ•°æ®çš„错误, +è¦ä¹ˆåˆ›é€ ä¸€ä¸ª ``Error(string)`` 类型的错误。 +它应该被用æ¥ç¡®ä¿åœ¨æ‰§è¡Œä¹‹å‰æ— æ³•æ£€æµ‹åˆ°çš„有效æ¡ä»¶ã€‚ +这包括对输入的æ¡ä»¶æˆ–调用外部åˆçº¦çš„返回值。 .. note:: - It is currently not possible to use custom errors in combination - with ``require``. Please use ``if (!condition) revert CustomError();`` instead. + ç›®å‰ä¸èƒ½å°†è‡ªå®šä¹‰é”™è¯¯ä¸Ž ``require`` 结åˆä½¿ç”¨ã€‚ + 请使用 ``if (!condition) revert CustomError();`` 代替。 -An ``Error(string)`` exception (or an exception without data) is generated -by the compiler -in the following situations: +在下列情况下,编译器会产生一个 ``Error(string)`` 异常(或者没有数æ®çš„异常)。 -#. Calling ``require(x)`` where ``x`` evaluates to ``false``. -#. If you use ``revert()`` or ``revert("description")``. -#. If you perform an external function call targeting a contract that contains no code. -#. If your contract receives Ether via a public function without - ``payable`` modifier (including the constructor and the fallback function). -#. If your contract receives Ether via a public getter function. +#. 调用 ``require(x)``,其中 ``x`` 的值为 ``false``。 +#. 如果您使用 ``revert()`` 或 ``revert("错误æè¿°")``。 +#. 如果您执行一个外部函数调用,目标是一个ä¸åŒ…å«ä»£ç çš„åˆçº¦ã€‚ +#. 如果您的åˆçº¦é€šè¿‡ä¸€ä¸ªæ²¡æœ‰ ``payable`` 修饰符的公开函数(包括构造函数和备用函数)接收以太。 +#. 如果您的åˆçº¦é€šè¿‡ä¸€ä¸ªå…¬å…±çš„getter函数接收以太。 -For the following cases, the error data from the external call -(if provided) is forwarded. This means that it can either cause -an ``Error`` or a ``Panic`` (or whatever else was given): +对于以下情况,æ¥è‡ªå¤–部调用的错误数æ®ï¼ˆå¦‚æžœæ供的è¯ï¼‰ä¼šè¢«è½¬å‘。 +è¿™æ„味ç€å®ƒæ—¢å¯ä»¥å¼•èµ· ``Error`` 异常,也å¯ä»¥å¼•èµ· ``Panic`` 异常(或æ供的其他什么错误)。 -#. If a ``.transfer()`` fails. -#. If you call a function via a message call but it does not finish - properly (i.e., it runs out of gas, has no matching function, or - throws an exception itself), except when a low level operation - ``call``, ``send``, ``delegatecall``, ``callcode`` or ``staticcall`` - is used. The low level operations never throw exceptions but - indicate failures by returning ``false``. -#. If you create a contract using the ``new`` keyword but the contract - creation :ref:`does not finish properly`. +#. 如果 ``.transfer()`` 失败。 +#. 如果您通过消æ¯è°ƒç”¨ä¸€ä¸ªå‡½æ•°ï¼Œä½†å®ƒä¸èƒ½æ­£å¸¸å®Œæˆ + (å³ï¼Œè€—尽了气体,没有匹é…的函数,或自己抛出一个异常), + 除éžä½¿ç”¨ä½Žçº§æ“作 ``call``, ``send``, ``delegatecall``, ``callcode`` + 或 ``staticcall``。低级æ“作从ä¸æŠ›å‡ºå¼‚常,但通过返回 ``false`` 表示失败。 +#. 如果您使用 ``new`` 关键字创建一个åˆçº¦ï¼Œ + 但åˆçº¦åˆ›å»º :ref:`æ²¡æœ‰æ­£å¸¸å®Œæˆ `。 -You can optionally provide a message string for ``require``, but not for ``assert``. +您å¯ä»¥é€‰æ‹©ä¸º ``require`` æ供一个信æ¯å­—符串,但ä¸èƒ½ä¸º ``assert`` æ供。 .. note:: - If you do not provide a string argument to ``require``, it will revert - with empty error data, not even including the error selector. + 如果您没有给 ``require`` æ供一个字符串å‚数,它将以空的错误数æ®è¿›è¡Œè¿˜åŽŸï¼Œ + 甚至ä¸åŒ…括错误选择器。 -The following example shows how you can use ``require`` to check conditions on inputs -and ``assert`` for internal error checking. +下é¢çš„例å­æ˜¾ç¤ºäº†å¦‚何使用 ``require`` æ¥æ£€æŸ¥è¾“入的æ¡ä»¶ +å’Œ ``assert`` 进行内部错误检查。 .. code-block:: solidity :force: @@ -683,59 +631,65 @@ and ``assert`` for internal error checking. 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; } } -Internally, Solidity performs a revert operation (instruction -``0xfd``). This causes -the EVM to revert all changes made to the state. The reason for reverting -is that there is no safe way to continue execution, because an expected effect -did not occur. Because we want to keep the atomicity of transactions, the -safest action is to revert all changes and make the whole transaction -(or at least call) without effect. +在内部, Solidity 会执行æ¢å¤æ“作(指令 ``0xfd`` )。 +这会导致 EVM æ¢å¤å¯¹çŠ¶æ€æ‰€åšçš„所有更改。æ¢å¤çš„原因是ä¸èƒ½ç»§ç»­å®‰å…¨åœ°æ‰§è¡Œï¼Œ +因为没有实现预期的效果,还因为我们想ä¿ç•™äº¤æ˜“的原å­æ€§ï¼Œ +所以最安全的åšæ³•æ˜¯æ¢å¤æ‰€æœ‰æ›´æ”¹å¹¶ä½¿æ•´ä¸ªäº¤æ˜“(或至少是调用)ä¸äº§ç”Ÿæ•ˆæžœã€‚ -In both cases, the caller can react on such failures using ``try``/``catch``, but -the changes in the callee will always be reverted. +在这两ç§æƒ…况下,调用者å¯ä»¥ä½¿ç”¨ ``try``/ ``catch`` 对这ç§å¤±è´¥åšå‡ºå¤„ç†ï¼Œ +但被调用者的å˜åŒ–将总是被æ¢å¤ã€‚ .. note:: - Panic exceptions used to use the ``invalid`` opcode before Solidity 0.8.0, - which consumed all gas available to the call. - Exceptions that use ``require`` used to consume all gas until before the Metropolis release. + 在Solidity 0.8.0之å‰ï¼ŒPanic异常曾使用 ``invalid`` æ“作ç ï¼Œ + 它消耗了所有å¯ç”¨äºŽè°ƒç”¨çš„气体。在Metropoliså‘布之å‰ï¼Œ + 使用 ``require`` 的异常会消耗所有气体。 .. _revert-statement: ``revert`` ---------- -A direct revert can be triggered using the ``revert`` statement and the ``revert`` function. +å¯ä»¥ä½¿ç”¨ ``revert`` 语å¥å’Œ ``revert`` 函数æ¥è§¦å‘直接æ¢å¤ã€‚ -The ``revert`` statement takes a custom error as direct argument without parentheses: +``revert`` 语å¥å°†ä¸€ä¸ªè‡ªå®šä¹‰çš„错误作为直接å‚数,没有括å·ï¼š 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"); -The error data will be passed back to the caller and can be caught there. -Using ``revert()`` causes a revert without any error data while ``revert("description")`` -will create an ``Error(string)`` error. +错误数æ®å°†è¢«ä¼ å›žç»™è°ƒç”¨è€…,å¯ä»¥åœ¨é‚£é‡Œæ•èŽ·ã€‚ +使用 ``revert()`` 会导致没有任何错误数æ®çš„还原, +而 ``revert("description")`` 将创建一个 ``Error(string)`` 错误。 -Using a custom error instance will usually be much cheaper than a string description, -because you can use the name of the error to describe it, which is encoded in only -four bytes. A longer description can be supplied via NatSpec which does not incur -any costs. +使用一个自定义的错误实例通常会比字符串æ述便宜得多, +因为您å¯ä»¥ä½¿ç”¨é”™è¯¯çš„å称æ¥æ述它,它的编ç åªæœ‰å››ä¸ªå­—节。 +å¯ä»¥é€šè¿‡NatSpecæ供更长的æ述,这ä¸ä¼šäº§ç”Ÿä»»ä½•è´¹ç”¨ã€‚ -The following example shows how to use an error string and a custom error instance -together with ``revert`` and the equivalent ``require``: +下é¢çš„例å­æ˜¾ç¤ºäº†å¦‚何将一个错误字符串和一个自定义的错误实例 +与 ``revert`` 和相应的 ``require`` 一起使用。 .. code-block:: solidity @@ -748,12 +702,12 @@ together with ``revert`` and the equivalent ``require``: function buy(uint amount) public payable { if (amount > msg.value / 2 ether) revert("Not enough Ether provided."); - // Alternative way to do it: + // å¦ä¸€ç§æ–¹æ³•ï¼š require( amount <= msg.value / 2 ether, "Not enough Ether provided." ); - // Perform the purchase. + // 执行购买。 } function withdraw() public { if (msg.sender != owner) @@ -763,39 +717,37 @@ together with ``revert`` and the equivalent ``require``: } } -The two ways ``if (!condition) revert(...);`` and ``require(condition, ...);`` are -equivalent as long as the arguments to ``revert`` and ``require`` do not have side-effects, -for example if they are just strings. +``if (!condition) revert(...);`` å’Œ ``require(condition, ...);`` 这两ç§æ–¹å¼æ˜¯ç­‰ä»·çš„, +åªè¦ ``revert`` å’Œ ``require`` çš„å‚数没有副作用,比如说它们åªæ˜¯å­—符串。 .. note:: - The ``require`` function is evaluated just as any other function. - This means that all arguments are evaluated before the function itself is executed. - In particular, in ``require(condition, f())`` the function ``f`` is executed even if - ``condition`` is true. + ``require`` 函数和其他函数一样。这æ„味ç€åœ¨æ‰§è¡Œå‡½æ•°æœ¬èº«ä¹‹å‰ï¼Œæ‰€æœ‰å‚数都会被评估。 + 特别是,在 ``require(condition, f())`` 中,å³ä½¿ ``condition`` 为真, + 函数 ``f`` 也被执行。 -The provided string is :ref:`abi-encoded ` as if it were a call to a function ``Error(string)``. -In the above example, ``revert("Not enough Ether provided.");`` returns the following hexadecimal as error return data: +æ供的字符串是 :ref:`ABIç¼–ç  ` 之åŽçš„,就åƒè°ƒç”¨ä¸€ä¸ªå‡½æ•° ``Error(string)`` 一样。 +在上é¢çš„例å­ä¸­ï¼Œ ``revert("Not enough Ether provided.");`` 返回以下å六进制作为错误返回数æ®ï¼š .. code:: - 0x08c379a0 // Function selector for Error(string) - 0x0000000000000000000000000000000000000000000000000000000000000020 // Data offset - 0x000000000000000000000000000000000000000000000000000000000000001a // String length - 0x4e6f7420656e6f7567682045746865722070726f76696465642e000000000000 // String data + 0x08c379a0 // Error(string) 的函数选择器 + 0x0000000000000000000000000000000000000000000000000000000000000020 // æ•°æ®çš„å移é‡ï¼ˆ32) + 0x000000000000000000000000000000000000000000000000000000000000001a // 字符串长度(26) + 0x4e6f7420656e6f7567682045746865722070726f76696465642e000000000000 // 字符串数æ®ï¼ˆ"Not enough Ether provided." çš„ ASCII ç¼–ç ï¼Œ26字节) -The provided message can be retrieved by the caller using ``try``/``catch`` as shown below. +调用者å¯ä»¥ä½¿ç”¨ ``try`` / ``catch`` 检索所æ供的消æ¯ï¼Œå¦‚下所示。 .. note:: - There used to be a keyword called ``throw`` with the same semantics as ``revert()`` which - was deprecated in version 0.4.13 and removed in version 0.5.0. + 以å‰æœ‰ä¸€ä¸ªå« ``throw`` 的关键字,其语义与 ``revert()`` 相åŒï¼Œ + 在0.4.13版本中被弃用,在0.5.0版本中被删除。 .. _try-catch: -``try``/``catch`` ------------------ +``try`` / ``catch`` +--------------------- -A failure in an external call can be caught using a try/catch statement, as follows: +外部调用的失败å¯ä»¥ç”¨ try/catch 语å¥æ¥æ•èŽ·ï¼Œå¦‚下所示: .. code-block:: solidity @@ -808,94 +760,77 @@ A failure in an external call can be caught using a try/catch statement, as foll DataFeed feed; uint errorCount; function rate(address token) public returns (uint value, bool success) { - // Permanently disable the mechanism if there are - // more than 10 errors. + // 如果有10个以上的错误,就永久åœç”¨è¯¥æœºåˆ¶ã€‚ require(errorCount < 10); try feed.getData(token) returns (uint v) { return (v, true); } catch Error(string memory /*reason*/) { - // This is executed in case - // revert was called inside getData - // and a reason string was provided. + // 如果在getData中调用revert, + // 并且æ供了一个原因字符串, + // 则执行该命令。 errorCount++; return (0, false); } catch Panic(uint /*errorCode*/) { - // This is executed in case of a panic, - // i.e. a serious error like division by zero - // or overflow. The error code can be used - // to determine the kind of error. + // 在å‘生Panic异常的情况下执行, + // å³å‡ºçŽ°ä¸¥é‡çš„错误,如除以零或溢出。 + // 错误代ç å¯ä»¥ç”¨æ¥ç¡®å®šé”™è¯¯çš„ç§ç±»ã€‚ errorCount++; return (0, false); } catch (bytes memory /*lowLevelData*/) { - // This is executed in case revert() was used. + // 在使用revert()的情况下,会执行这个命令。 errorCount++; return (0, false); } } } -The ``try`` keyword has to be followed by an expression representing an external function call -or a contract creation (``new ContractName()``). -Errors inside the expression are not caught (for example if it is a complex expression -that also involves internal function calls), only a revert happening inside the external -call itself. The ``returns`` part (which is optional) that follows declares return variables -matching the types returned by the external call. In case there was no error, -these variables are assigned and the contract's execution continues inside the -first success block. If the end of the success block is reached, execution continues after the ``catch`` blocks. +``try`` 关键字åŽé¢å¿…须有一个表达å¼ï¼Œä»£è¡¨å¤–部函数调用或åˆçº¦å»ºï¼ˆ ``new ContractName()`` )。 +表达å¼ä¸­çš„错误ä¸ä¼šè¢«æ•èŽ·ï¼ˆä¾‹å¦‚,如果它是一个å¤æ‚的表达å¼ï¼Œä¹Ÿæ¶‰åŠåˆ°å†…部函数调用), +åªæœ‰å¤–部调用本身å‘生æ¢å¤ã€‚ +接下æ¥çš„ ``returns`` 部分(是å¯é€‰çš„)声明了与外部调用返回的类型相匹é…的返回å˜é‡ã€‚ +如果没有错误,这些å˜é‡å°†è¢«åˆ†é…,åˆçº¦æ‰§è¡Œå°†åœ¨ç¬¬ä¸€ä¸ªæˆåŠŸä»£ç å—内继续。 +如果到达æˆåŠŸä»£ç å—的末端,则在 ``catch`` å—之åŽç»§ç»­æ‰§è¡Œã€‚ -Solidity supports different kinds of catch blocks depending on the -type of error: +Solidity æ ¹æ®é”™è¯¯çš„类型,支æŒä¸åŒç§ç±»çš„æ•èŽ·å—: -- ``catch Error(string memory reason) { ... }``: This catch clause is executed if the error was caused by ``revert("reasonString")`` or - ``require(false, "reasonString")`` (or an internal error that causes such an - exception). +- ``catch Error(string memory reason) { ... }``: 这个catchå­å¥ä¼šè¢«æ‰§è¡Œï¼Œ + 如果错误是由 ``revert("reasonString")`` 或 ``require(false, "reasonString")`` 造æˆçš„ + (或内部错误造æˆçš„)。 -- ``catch Panic(uint errorCode) { ... }``: If the error was caused by a panic, i.e. by a failing ``assert``, division by zero, - invalid array access, arithmetic overflow and others, this catch clause will be run. +- ``catch Panic(uint errorCode) { ... }``: 如果错误是由Panic异常引起的, + 例如由失败的 ``assert``ã€é™¤ä»¥0ã€æ— æ•ˆçš„数组访问ã€ç®—术溢出和其他原因引起的,这个catchå­å¥å°†è¢«è¿è¡Œã€‚ -- ``catch (bytes memory lowLevelData) { ... }``: This clause is executed if the error signature - does not match any other clause, if there was an error while decoding the error - message, or - if no error data was provided with the exception. - The declared variable provides access to the low-level error data in that case. +- ``catch (bytes memory lowLevelData) { ... }``: 如果错误签å与其他å­å¥ä¸åŒ¹é…, + 或者在解ç é”™è¯¯ä¿¡æ¯æ—¶å‡ºçŽ°äº†é”™è¯¯ï¼Œæˆ–者没有与异常一起æ供错误数æ®ï¼Œ + 那么这个å­å¥å°±ä¼šè¢«æ‰§è¡Œã€‚在这ç§æƒ…况下,声明的å˜é‡æ供了对低级错误数æ®çš„访问。 -- ``catch { ... }``: If you are not interested in the error data, you can just use - ``catch { ... }`` (even as the only catch clause) instead of the previous clause. +- ``catch { ... }``: 如果您对错误数æ®ä¸æ„Ÿå…´è¶£ï¼Œæ‚¨å¯ä»¥ç›´æŽ¥ä½¿ç”¨ + ``catch { ... }`` (甚至作为唯一的catchå­å¥ï¼‰æ¥ä»£æ›¿å‰é¢çš„å­å¥ã€‚ -It is planned to support other types of error data in the future. -The strings ``Error`` and ``Panic`` are currently parsed as is and are not treated as identifiers. +计划在未æ¥æ”¯æŒå…¶ä»–类型的错误数æ®ã€‚字符串 ``Error`` å’Œ ``Panic`` ç›®å‰æ˜¯æŒ‰åŽŸæ ·è§£æžçš„,ä¸ä½œä¸ºæ ‡è¯†ç¬¦å¤„ç†ã€‚ -In order to catch all error cases, you have to have at least the clause -``catch { ...}`` or the clause ``catch (bytes memory lowLevelData) { ... }``. +为了æ•æ‰æ‰€æœ‰çš„错误情况,您至少è¦æœ‰ ``catch { ...}`` 或 ``catch (bytes memory lowLevelData) { ... }`` å­å¥ã€‚ -The variables declared in the ``returns`` and the ``catch`` clause are only -in scope in the block that follows. +在 ``returns`` å’Œ ``catch`` å­å¥ä¸­å£°æ˜Žçš„å˜é‡åªåœ¨åŽé¢çš„代ç å—中有作用域。 .. note:: - If an error happens during the decoding of the return data - inside a try/catch-statement, this causes an exception in the currently - executing contract and because of that, it is not caught in the catch clause. - If there is an error during decoding of ``catch Error(string memory reason)`` - and there is a low-level catch clause, this error is caught there. + 如果在 try/catch 语å¥å†…部的返回数æ®è§£ç è¿‡ç¨‹ä¸­å‘生错误, + 这将导致当å‰æ‰§è¡Œçš„åˆçº¦å‡ºçŽ°å¼‚常,正因为如此,它ä¸ä¼šåœ¨catchå­å¥ä¸­è¢«æ•èŽ·ã€‚ + 如果在 ``catch Error(string memory reason)`` 的解ç è¿‡ç¨‹ä¸­å‡ºçŽ°é”™è¯¯ï¼Œ + 并且有一个低级的catchå­å¥ï¼Œé‚£ä¹ˆè¿™ä¸ªé”™è¯¯å°±ä¼šåœ¨é‚£é‡Œè¢«æ•èŽ·ã€‚ .. note:: - If execution reaches a catch-block, then the state-changing effects of - the external call have been reverted. If execution reaches - the success block, the effects were not reverted. - If the effects have been reverted, then execution either continues - in a catch block or the execution of the try/catch statement itself - reverts (for example due to decoding failures as noted above or - due to not providing a low-level catch clause). + 如果执行到一个catch代ç å—,那么外部调用的状æ€æ”¹å˜æ•ˆæžœå·²ç»è¢«æ¢å¤ã€‚ + 如果执行到了æˆåŠŸä»£ç å—,那么这些影å“就没有被还原。 + 如果影å“å·²ç»è¢«è¿˜åŽŸï¼Œé‚£ä¹ˆæ‰§è¡Œè¦ä¹ˆåœ¨catch代ç å—中继续, + è¦ä¹ˆtry/catch语å¥çš„执行本身被还原(例如由于上é¢æ到的解ç å¤±è´¥æˆ–者由于没有æ供低级别的catchå­å¥ï¼‰ã€‚ .. note:: - The reason behind a failed call can be manifold. Do not assume that - the error message is coming directly from the called contract: - The error might have happened deeper down in the call chain and the - called contract just forwarded it. Also, it could be due to an - out-of-gas situation and not a deliberate error condition: - The caller always retains at least 1/64th of the gas in a call and thus - even if the called contract goes out of gas, the caller still - has some gas left. + 调用失败背åŽçš„原因å¯èƒ½æ˜¯å¤šæ–¹é¢çš„。ä¸è¦è®¤ä¸ºé”™è¯¯ä¿¡æ¯æ˜¯ç›´æŽ¥æ¥è‡ªè¢«è°ƒç”¨çš„åˆçº¦ï¼š + 错误å¯èƒ½å‘生在调用链的更深处,被调用的åˆçº¦åªæ˜¯è½¬å‘了它。 + å¦å¤–,这å¯èƒ½æ˜¯ç”±äºŽæ¶ˆè€—完气体值的情况,而ä¸æ˜¯æ•…æ„的错误状况。 + 调用方总是ä¿ç•™è°ƒç”¨ä¸­è‡³å°‘1/64的气体值, + 因此,å³ä½¿è¢«è°ƒç”¨åˆçº¦æ²¡æœ‰æ°”体了,调用方ä»ç„¶æœ‰ä¸€äº›æ°”体。 diff --git a/docs/examples/blind-auction.rst b/docs/examples/blind-auction.rst index 47e19033f9ae..24a588e8cf9b 100644 --- a/docs/examples/blind-auction.rst +++ b/docs/examples/blind-auction.rst @@ -1,72 +1,74 @@ .. index:: auction;blind, auction;open, blind auction, open auction -************* -Blind Auction -************* +**************** +盲æ‹ï¼ˆç§˜å¯†ç«žä»·ï¼‰ +**************** -In this section, we will show how easy it is to create a completely blind -auction contract on Ethereum. We will start with an open auction where -everyone can see the bids that are made and then extend this contract into a -blind auction where it is not possible to see the actual bid until the bidding -period ends. +在本节中,我们将展示如何轻æ¾åœ°åœ¨ä»¥å¤ªåŠä¸Šåˆ›å»ºä¸€ä¸ªç›²æ‹çš„åˆçº¦ã€‚ +我们将从一个公开æ‹å–开始,æ¯ä¸ªäººéƒ½å¯ä»¥çœ‹åˆ°å‡ºä»·ï¼Œ +然åŽå°†æ­¤åˆçº¦æ‰©å±•åˆ°ç›²æ‹åˆçº¦ï¼Œ 在竞标期结æŸä¹‹å‰æ— æ³•çœ‹åˆ°å®žé™…出价。 .. _simple_auction: -Simple Open Auction +简å•çš„公开æ‹å– =================== +<<<<<<< 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 // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.4; contract SimpleAuction { - // Parameters of the auction. Times are either - // absolute unix timestamps (seconds since 1970-01-01) - // or time periods in seconds. + // æ‹å–çš„å‚数。 + // 时间是 unix çš„ç»å¯¹æ—¶é—´æˆ³ï¼ˆè‡ª1970-01-01以æ¥çš„秒数) + // 或以秒为å•ä½çš„时间段。 address payable public beneficiary; uint public auctionEndTime; - // Current state of the auction. + // æ‹å–的当å‰çŠ¶æ€ã€‚ address public highestBidder; uint public highestBid; - // Allowed withdrawals of previous bids + // å…许å–回以å‰çš„竞标。 mapping(address => uint) pendingReturns; - // Set to true at the end, disallows any change. - // By default initialized to `false`. + // æ‹å–结æŸåŽè®¾ä¸º `true`,将ç¦æ­¢æ‰€æœ‰çš„å˜æ›´ + // 默认åˆå§‹åŒ–为 `false`。 bool ended; - // Events that will be emitted on changes. + // å˜åŒ–时将会å‘出的事件。 event HighestBidIncreased(address bidder, uint amount); event AuctionEnded(address winner, uint amount); - // Errors that describe failures. + // æ述失败的错误信æ¯ã€‚ - // The triple-slash comments are so-called natspec - // comments. They will be shown when the user - // is asked to confirm a transaction or - // when an error is displayed. + // 三斜线的注释是所谓的 natspec 注释。 + // 当用户被è¦æ±‚确认一个交易或显示一个错误时,它们将被显示。 - /// The auction has already ended. + /// ç«žæ‹å·²ç»ç»“æŸã€‚ error AuctionAlreadyEnded(); - /// There is already a higher or equal bid. + /// å·²ç»æœ‰ä¸€ä¸ªæ›´é«˜çš„或相等的出价。 error BidNotHighEnough(uint highestBid); - /// The auction has not ended yet. + /// ç«žæ‹è¿˜æ²¡æœ‰ç»“æŸã€‚ error AuctionNotYetEnded(); - /// The function auctionEnd has already been called. + /// 函数 auctionEnd å·²ç»è¢«è°ƒç”¨ã€‚ error AuctionEndAlreadyCalled(); - /// Create a simple auction with `biddingTime` - /// seconds bidding time on behalf of the - /// beneficiary address `beneficiaryAddress`. + /// 以å—ç›Šè€…åœ°å€ `beneficiaryAddress` 创建一个简å•çš„æ‹å–, + /// æ‹å–时长为 `_biddingTime`。 constructor( uint biddingTime, address payable beneficiaryAddress @@ -75,36 +77,43 @@ to receive their Ether - contracts cannot activate themselves. auctionEndTime = block.timestamp + biddingTime; } - /// Bid on the auction with the value sent - /// together with this transaction. - /// The value will only be refunded if the - /// auction is not won. + /// 对æ‹å–进行出价,具体的出价éšäº¤æ˜“一起å‘é€ã€‚ + /// 如果没有在æ‹å–中胜出,则返还出价。 function bid() external payable { - // No arguments are necessary, all - // information is already part of - // the transaction. The keyword payable - // is required for the function to - // be able to receive Ether. - - // Revert the call if the bidding - // period is over. + // å‚æ•°ä¸æ˜¯å¿…è¦çš„。因为所有的信æ¯å·²ç»åŒ…å«åœ¨äº†äº¤æ˜“中。 + // 关键字 `payable` 是函数能够接收以太å¸çš„å¿…è¦æ¡ä»¶ã€‚ + + // 如果æ‹å–已结æŸï¼Œæ’¤é”€å‡½æ•°çš„调用。 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; @@ -112,20 +121,20 @@ to receive their Ether - contracts cannot activate themselves. emit HighestBidIncreased(msg.sender, msg.value); } - /// Withdraw a bid that was overbid. + /// 撤回出价过高的竞标。 function withdraw() external returns (bool) { uint amount = pendingReturns[msg.sender]; if (amount > 0) { - // It is important to set this to zero because the recipient - // can call this function again as part of the receiving call - // before `send` returns. + // 将其设置为0是很é‡è¦çš„, + // 因为接收者å¯ä»¥åœ¨ `send` 返回之å‰å†æ¬¡è°ƒç”¨è¿™ä¸ªå‡½æ•° + // 作为接收调用的一部分。 pendingReturns[msg.sender] = 0; - // msg.sender is not of type `address payable` and must be - // explicitly converted using `payable(msg.sender)` in order - // use the member function `send()`. + // msg.sender ä¸å±žäºŽ `address payable` 类型, + // 必须使用 `payable(msg.sender)` 明确转æ¢ï¼Œ + // 以便使用æˆå‘˜å‡½æ•° `send()`。 if (!payable(msg.sender).send(amount)) { - // No need to call throw here, just reset the amount owing + // 这里ä¸éœ€æŠ›å‡ºå¼‚常,åªéœ€é‡ç½®æœªä»˜æ¬¾ pendingReturns[msg.sender] = amount; return false; } @@ -133,54 +142,51 @@ to receive their Ether - contracts cannot activate themselves. return true; } - /// End the auction and send the highest bid - /// to the beneficiary. + /// 结æŸæ‹å–,并把最高的出价å‘é€ç»™å—益人。 function auctionEnd() external { - // It is a good guideline to structure functions that interact - // with other contracts (i.e. they call functions or send Ether) - // into three phases: - // 1. checking conditions - // 2. performing actions (potentially changing conditions) - // 3. interacting with other contracts - // If these phases are mixed up, the other contract could call - // back into the current contract and modify the state or cause - // effects (ether payout) to be performed multiple times. - // If functions called internally include interaction with external - // contracts, they also have to be considered interaction with - // external contracts. - - // 1. Conditions + // 对于å¯ä¸Žå…¶ä»–åˆçº¦äº¤äº’的函数(æ„味ç€å®ƒä¼šè°ƒç”¨å…¶ä»–函数或å‘é€ä»¥å¤ªå¸ï¼‰ï¼Œ + // 一个好的指导方针是将其结构分为三个阶段: + // 1. 检查æ¡ä»¶ + // 2. 执行动作 (å¯èƒ½ä¼šæ”¹å˜æ¡ä»¶) + // 3. 与其他åˆçº¦äº¤äº’ + // 如果这些阶段相混åˆï¼Œå…¶ä»–çš„åˆçº¦å¯èƒ½ä¼šå›žè°ƒå½“å‰åˆçº¦å¹¶ä¿®æ”¹çŠ¶æ€ï¼Œ + // 或者导致æŸäº›æ•ˆæžœï¼ˆæ¯”如支付以太å¸ï¼‰å¤šæ¬¡ç”Ÿæ•ˆã€‚ + // 如果åˆçº¦å†…调用的函数包å«äº†ä¸Žå¤–部åˆçº¦çš„交互, + // 则它也会被认为是与外部åˆçº¦æœ‰äº¤äº’的。 + + // 1. æ¡ä»¶ if (block.timestamp < auctionEndTime) revert AuctionNotYetEnded(); if (ended) revert AuctionEndAlreadyCalled(); - // 2. Effects + // 2. å½±å“ ended = true; emit AuctionEnded(highestBidder, highestBid); - // 3. Interaction + // 3. 交互 beneficiary.transfer(highestBid); } } -Blind Auction -============= +盲æ‹ï¼ˆç§˜å¯†ç«žæ‹ï¼‰ +================ -The previous open auction is extended to a blind auction in the following. The -advantage of a blind auction is that there is no time pressure towards the end -of the bidding period. Creating a blind auction on a transparent computing -platform might sound like a contradiction, but cryptography comes to the -rescue. +之å‰çš„公开æ‹å–接下æ¥å°†è¢«æ‰©å±•ä¸ºç›²ç›®æ‹å–。 +盲æ‹çš„好处是,在竞价期å³å°†ç»“æŸæ—¶æ²¡æœ‰æ—¶é—´åŽ‹åŠ›ã€‚ +在一个é€æ˜Žçš„计算平å°ä¸Šåˆ›å»ºä¸€ä¸ªç›²æ‹å¯èƒ½å¬èµ·æ¥æ˜¯ä¸€ä¸ªçŸ›ç›¾ï¼Œä½†åŠ å¯†æŠ€æœ¯å¯ä»¥å®žçŽ°å®ƒã€‚ -During the **bidding period**, a bidder does not actually send their bid, but -only a hashed version of it. Since it is currently considered practically -impossible to find two (sufficiently long) values whose hash values are equal, -the bidder commits to the bid by that. After the end of the bidding period, -the bidders have to reveal their bids: They send their values unencrypted, and -the contract checks that the hash value is the same as the one provided during -the bidding period. +在 **竞标期间**,竞标者实际上并没有å‘é€ä»–们的出价, +而åªæ˜¯å‘é€ä¸€ä¸ªå“ˆå¸Œç‰ˆæœ¬çš„出价。 由于目å‰å‡ ä¹Žä¸å¯èƒ½æ‰¾åˆ°ä¸¤ä¸ªï¼ˆè¶³å¤Ÿé•¿çš„)值, +其哈希值是相等的,因此竞标者å¯é€šè¿‡è¯¥æ–¹å¼æ交报价。 在竞标结æŸåŽï¼Œ +竞标者必须公开他们的出价:他们å‘é€æœªåŠ å¯†çš„值, +åˆçº¦æ£€æŸ¥å‡ºä»·çš„哈希值是å¦ä¸Žç«žæ ‡æœŸé—´æ供的值相åŒã€‚ +<<<<<<< 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 @@ -192,7 +198,12 @@ the reveal phase, some bids might be **invalid**, and this is on purpose (it even provides an explicit flag to place invalid bids with high-value transfers): Bidders can confuse competition by placing several high or low invalid bids. +>>>>>>> english/develop +下é¢çš„åˆçº¦é€šè¿‡æŽ¥å—任何大于最高出价的值æ¥è§£å†³è¿™ä¸ªé—®é¢˜ã€‚ +当然,因为这åªèƒ½åœ¨æ­ç¤ºé˜¶æ®µè¿›è¡Œæ£€æŸ¥ï¼Œæœ‰äº›å‡ºä»·å¯èƒ½æ˜¯ **无效** 的, +而这是有目的的(它甚至æ供了一个明确的标志,以便在高价值的转移中进行无效的出价): +竞标者å¯ä»¥é€šè¿‡è®¾ç½®å‡ ä¸ªæˆ–高或低的无效出价æ¥è¿·æƒ‘竞争对手。 .. code-block:: solidity :force: @@ -215,26 +226,25 @@ invalid bids. address public highestBidder; uint public highestBid; - // Allowed withdrawals of previous bids + // å…许å–回以å‰çš„竞标。 mapping(address => uint) pendingReturns; event AuctionEnded(address winner, uint highestBid); - // Errors that describe failures. + // æ述失败的错误信æ¯ã€‚ - /// The function has been called too early. - /// Try again at `time`. + /// 该函数被过早调用。 + /// 在 `time` 时间å†è¯•ä¸€æ¬¡ã€‚ error TooEarly(uint time); - /// The function has been called too late. - /// It cannot be called after `time`. + /// 该函数被过晚调用。 + /// 它ä¸èƒ½åœ¨ `time` 时间之åŽè¢«è°ƒç”¨ã€‚ error TooLate(uint time); - /// The function auctionEnd has already been called. + /// 函数 auctionEnd å·²ç»è¢«è°ƒç”¨ã€‚ error AuctionEndAlreadyCalled(); - // Modifiers are a convenient way to validate inputs to - // functions. `onlyBefore` is applied to `bid` below: - // The new function body is the modifier's body where - // `_` is replaced by the old function body. + // 使用 修饰符(modifier) å¯ä»¥æ›´ä¾¿æ·çš„校验函数的入å‚。 + // `onlyBefore` 会被用于åŽé¢çš„ `bid` 函数: + // 新的函数体是由 modifier 本身的函数体,其中`_`被旧的函数体所å–代。 modifier onlyBefore(uint time) { if (block.timestamp >= time) revert TooLate(time); _; @@ -254,15 +264,13 @@ invalid bids. revealEnd = biddingEnd + revealTime; } - /// Place a blinded bid with `blindedBid` = - /// keccak256(abi.encodePacked(value, fake, secret)). - /// The sent ether is only refunded if the bid is correctly - /// revealed in the revealing phase. The bid is valid if the - /// ether sent together with the bid is at least "value" and - /// "fake" is not true. Setting "fake" to true and sending - /// not the exact amount are ways to hide the real bid but - /// still make the required deposit. The same address can - /// place multiple bids. + /// å¯ä»¥é€šè¿‡ `_blindedBid` = keccak256(value, fake, secret) + /// 设置一个盲æ‹ã€‚ + /// åªæœ‰åœ¨å‡ºä»·æŠ«éœ²é˜¶æ®µè¢«æ­£ç¡®æŠ«éœ²ï¼Œå·²å‘é€çš„以太å¸æ‰ä¼šè¢«é€€è¿˜ã€‚ + /// 如果与出价一起å‘é€çš„以太å¸è‡³å°‘为 "value" 且 "fake" ä¸ä¸ºçœŸï¼Œåˆ™å‡ºä»·æœ‰æ•ˆã€‚ + /// å°† "fake" 设置为 true , + /// 然åŽå‘é€æ»¡è¶³è®¢é‡‘金é¢ä½†åˆä¸ä¸Žå‡ºä»·ç›¸åŒçš„金é¢æ˜¯éšè—实际出价的方法。 + /// åŒä¸€ä¸ªåœ°å€å¯ä»¥æ”¾ç½®å¤šä¸ªå‡ºä»·ã€‚ function bid(bytes32 blindedBid) external payable @@ -274,9 +282,8 @@ invalid bids. })); } - /// Reveal your blinded bids. You will get a refund for all - /// correctly blinded invalid bids and for all bids except for - /// the totally highest. + /// 披露你的盲æ‹å‡ºä»·ã€‚ + /// 对于所有正确披露的无效出价以åŠé™¤æœ€é«˜å‡ºä»·ä»¥å¤–的所有出价,您都将获得退款。 function reveal( uint[] calldata values, bool[] calldata fakes, @@ -297,8 +304,8 @@ invalid bids. (uint value, bool fake, bytes32 secret) = (values[i], fakes[i], secrets[i]); if (bidToCheck.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) { - // Bid was not actually revealed. - // Do not refund deposit. + // 出价未能正确披露。 + // ä¸è¿”还订金。 continue; } refund += bidToCheck.deposit; @@ -306,29 +313,27 @@ invalid bids. if (placeBid(msg.sender, value)) refund -= value; } - // Make it impossible for the sender to re-claim - // the same deposit. + // 使å‘é€è€…ä¸å¯èƒ½å†æ¬¡è®¤é¢†åŒä¸€ç¬”订金。 bidToCheck.blindedBid = bytes32(0); } payable(msg.sender).transfer(refund); } - /// Withdraw a bid that was overbid. + /// 撤回出价过高的竞标。 function withdraw() external { uint amount = pendingReturns[msg.sender]; if (amount > 0) { - // It is important to set this to zero because the recipient - // can call this function again as part of the receiving call - // before `transfer` returns (see the remark above about - // conditions -> effects -> interaction). + // 这里很é‡è¦ï¼Œé¦–å…ˆè¦è®¾é›¶å€¼ã€‚ + // 因为,作为接收调用的一部分, + // 接收者å¯ä»¥åœ¨ `transfer` 返回之å‰é‡æ–°è°ƒç”¨è¯¥å‡½æ•°ã€‚ + //(å¯æŸ¥çœ‹ä¸Šé¢å…³äºŽ æ¡ä»¶ -> å½±å“ -> 交互 的标注) pendingReturns[msg.sender] = 0; payable(msg.sender).transfer(amount); } } - /// End the auction and send the highest bid - /// to the beneficiary. + /// 结æŸæ‹å–,并把最高的出价å‘é€ç»™å—益人。 function auctionEnd() external onlyAfter(revealEnd) @@ -339,9 +344,8 @@ invalid bids. beneficiary.transfer(highestBid); } - // This is an "internal" function which means that it - // can only be called from the contract itself (or from - // derived contracts). + // 这是一个 "internal" 函数, + // æ„味ç€å®ƒåªèƒ½åœ¨æœ¬åˆçº¦ï¼ˆæˆ–继承åˆçº¦ï¼‰å†…被调用。 function placeBid(address bidder, uint value) internal returns (bool success) { @@ -349,7 +353,7 @@ invalid bids. return false; } if (highestBidder != address(0)) { - // Refund the previously highest bidder. + // 返还之å‰çš„最高出价 pendingReturns[highestBidder] += highestBid; } highestBid = value; diff --git a/docs/examples/micropayment.rst b/docs/examples/micropayment.rst index 50f28005bfd6..b3777dca80fe 100644 --- a/docs/examples/micropayment.rst +++ b/docs/examples/micropayment.rst @@ -1,84 +1,92 @@ -******************** -Micropayment Channel -******************** +********** +å¾®æ”¯ä»˜é€šé“ +********** -In this section, we will learn how to build an example implementation -of a payment channel. It uses cryptographic signatures to make -repeated transfers of Ether between the same parties secure, instantaneous, and -without transaction fees. For the example, we need to understand how to -sign and verify signatures, and setup the payment channel. +在这一节中,我们将学习如何建立一个支付通é“的实施实例。 +它使用加密签å,使以太å¸åœ¨åŒä¸€å½“事人之间的é‡å¤è½¬ç§»å˜å¾—安全ã€å³æ—¶ï¼Œå¹¶ä¸”没有交易费用。 +对于这个例å­ï¼Œæˆ‘们需è¦äº†è§£å¦‚何签å和验è¯ç­¾å,并设置支付通é“。 -Creating and verifying signatures -================================= +创建和验è¯ç­¾å +============== -Imagine Alice wants to send some Ether to Bob, i.e. -Alice is the sender and Bob is the recipient. +想象一下,Alice想å‘é€ä¸€äº›ä»¥å¤ªç»™Bob, +å³Alice是å‘é€æ–¹ï¼ŒBob是接收方。 -Alice only needs to send cryptographically signed messages off-chain -(e.g. via email) to Bob and it is similar to writing checks. +Alice åªéœ€è¦åœ¨é“¾ä¸‹å‘é€ç»è¿‡åŠ å¯†ç­¾åçš„ä¿¡æ¯ +(例如通过电å­é‚®ä»¶)ç»™Bob,它类似于写支票。 -Alice and Bob use signatures to authorize transactions, which is possible with smart contracts on Ethereum. -Alice will build a simple smart contract that lets her transmit Ether, but instead of calling a function herself -to initiate a payment, she will let Bob do that, and therefore pay the transaction fee. +Aliceå’ŒBob使用签åæ¥æŽˆæƒäº¤æ˜“,这在以太åŠçš„智能åˆçº¦ä¸­æ˜¯å¯ä»¥å®žçŽ°çš„。 +Alice将建立一个简å•çš„智能åˆçº¦ï¼Œè®©å¥¹ä¼ è¾“以太å¸ï¼Œä½†å¥¹ä¸ä¼šè‡ªå·±è°ƒç”¨ä¸€ä¸ªå‡½æ•°æ¥å¯åŠ¨ä»˜æ¬¾ï¼Œ +而是让Bobæ¥åšï¼Œä»Žè€Œæ”¯ä»˜äº¤æ˜“费用。 -The contract will work as follows: +该åˆçº¦å°†æŒ‰ä»¥ä¸‹æ–¹å¼è¿ä½œï¼š - 1. Alice deploys the ``ReceiverPays`` contract, attaching enough Ether to cover the payments that will be made. - 2. Alice authorizes a payment by signing a message with her private key. - 3. Alice sends the cryptographically signed message to Bob. The message does not need to be kept secret - (explained later), and the mechanism for sending it does not matter. - 4. Bob claims his payment by presenting the signed message to the smart contract, it verifies the - authenticity of the message and then releases the funds. + 1. Alice部署了 ``ReceiverPays`` åˆçº¦ï¼Œé™„加了足够的以太å¸æ¥æ”¯ä»˜å°†è¦è¿›è¡Œçš„付款。 + 2. Alice通过用她的ç§é’¥ç­¾ç½²ä¸€ä¸ªæ¶ˆæ¯æ¥æŽˆæƒä»˜æ¬¾ã€‚ + 3. Aliceå°†ç»è¿‡åŠ å¯†ç­¾åçš„ä¿¡æ¯å‘é€ç»™Bob。该信æ¯ä¸éœ€è¦ä¿å¯†ï¼ˆåŽé¢ä¼šè§£é‡Šï¼‰ï¼Œè€Œä¸”å‘é€æœºåˆ¶ä¹Ÿä¸é‡è¦ã€‚ + 4. Bob通过å‘智能åˆçº¦å‘é€ç­¾åçš„ä¿¡æ¯æ¥ç´¢å–他的付款,åˆçº¦éªŒè¯äº†ä¿¡æ¯çš„真实性,然åŽé‡Šæ”¾èµ„金。 -Creating the signature ----------------------- +创建签å +-------- -Alice does not need to interact with the Ethereum network -to sign the transaction, the process is completely offline. -In this tutorial, we will sign messages in the browser -using `web3.js `_ and -`MetaMask `_, using the method described in `EIP-712 `_, -as it provides a number of other security benefits. +Aliceä¸éœ€è¦ä¸Žä»¥å¤ªåŠç½‘络交互æ¥ç­¾ç½²äº¤æ˜“,这个过程是完全离线的。 +在本教程中,我们将使用 `web3.js `_ å’Œ +`MetaMask `_ 在æµè§ˆå™¨ä¸­ç­¾ç½²ä¿¡æ¯ã€‚ +使用 `EIP-712 `_ 中æ述的方法, +因为它æ供了许多其他安全优势。 .. code-block:: javascript - /// Hashing first makes things easier + /// 先进行哈希è¿ç®—使事情å˜å¾—更容易 var hash = web3.utils.sha3("message to sign"); web3.eth.personal.sign(hash, web3.eth.defaultAccount, function () { console.log("Signed"); }); .. note:: - The ``web3.eth.personal.sign`` prepends the length of the - message to the signed data. Since we hash first, the message - will always be exactly 32 bytes long, and thus this length - prefix is always the same. + ``web3.eth.personal.sign`` 把信æ¯çš„长度加到签åæ•°æ®ä¸­ã€‚ + 由于我们先进行哈希è¿ç®—,消æ¯çš„长度总是正好是32字节, + 因此这个长度å‰ç¼€æ€»æ˜¯ç›¸åŒçš„。 -What to Sign +签署内容 ------------ -For a contract that fulfils payments, the signed message must include: - - 1. The recipient's address. - 2. The amount to be transferred. - 3. Protection against replay attacks. - -A replay attack is when a signed message is reused to claim -authorization for a second action. To avoid replay attacks -we use the same technique as in Ethereum transactions themselves, -a so-called nonce, which is the number of transactions sent by -an account. The smart contract checks if a nonce is used multiple times. - -Another type of replay attack can occur when the owner -deploys a ``ReceiverPays`` smart contract, makes some -payments, and then destroys the contract. Later, they decide -to deploy the ``RecipientPays`` smart contract again, but the -new contract does not know the nonces used in the previous -deployment, so the attacker can use the old messages again. - -Alice can protect against this attack by including the -contract's address in the message, and only messages containing -the contract's address itself will be accepted. You can find -an example of this in the first two lines of the ``claimPayment()`` -function of the full contract at the end of this section. +<<<<<<< HEAD +对于履行付款的åˆåŒï¼Œç­¾ç½²çš„ä¿¡æ¯å¿…须包括: +======= +For a contract that fulfills payments, the signed message must include: +>>>>>>> english/develop + + 1. 收件人的钱包地å€ã€‚ + 2. è¦è½¬ç§»çš„金é¢ã€‚ + 3. é‡æ”¾æ”»å‡»çš„ä¿æŠ¤ã€‚ + +é‡æ”¾æ”»å‡»æ˜¯æŒ‡ä¸€ä¸ªå·²ç­¾ç½²çš„ä¿¡æ¯è¢«é‡å¤ä½¿ç”¨ï¼Œä»¥èŽ·å¾—对第二次交易的授æƒã€‚ +为了é¿å…é‡æ”¾æ”»å‡»ï¼Œæˆ‘们使用与以太åŠäº¤æ˜“本身相åŒçš„技术, +å³æ‰€è°“çš„nonce,它是一个账户å‘é€çš„交易数é‡ã€‚ +智能åˆçº¦ä¼šæ£€æŸ¥ä¸€ä¸ªnonce是å¦è¢«å¤šæ¬¡ä½¿ç”¨ã€‚ + +å¦ä¸€ç§ç±»åž‹çš„é‡æ”¾æ”»å‡»å¯èƒ½å‘生在所有者部署 ``ReceiverPays`` åˆçº¦æ—¶ï¼Œ +先进行了一些支付,然åŽé”€æ¯è¯¥åˆçº¦ã€‚åŽæ¥ï¼Œ +他们决定å†æ¬¡éƒ¨ç½² ``RecipientPays`` åˆçº¦ï¼Œ +但新的åˆçº¦ä¸çŸ¥é“以å‰åˆçº¦ä¸­ä½¿ç”¨çš„nonces,所以攻击者å¯ä»¥å†æ¬¡ä½¿ç”¨æ—§çš„ä¿¡æ¯ã€‚ + +Aliceå¯ä»¥é€šè¿‡åœ¨æ¶ˆæ¯ä¸­åŒ…å«åˆçº¦çš„地å€æ¥é˜²æ­¢è¿™ç§æ”»å‡»ï¼Œ +并且åªæœ‰åŒ…å«åˆçº¦åœ°å€æœ¬èº«çš„消æ¯æ‰ä¼šè¢«æŽ¥å—。 +您å¯ä»¥åœ¨æœ¬èŠ‚末尾的完整åˆçº¦çš„ ``claimPayment()`` 函数的å‰ä¸¤è¡Œæ‰¾åˆ°è¿™ä¸ªä¾‹å­ã€‚ + +<<<<<<< HEAD +组装å‚æ•° +--------- + +既然我们已ç»ç¡®å®šäº†è¦åœ¨ç­¾åä¿¡æ¯ä¸­åŒ…å«å“ªäº›ä¿¡æ¯ï¼Œ +我们准备把信æ¯æ”¾åœ¨ä¸€èµ·ï¼Œè¿›è¡Œå“ˆå¸Œè¿ç®—,然åŽç­¾å。 +简å•èµ·è§ï¼Œæˆ‘们把数æ®è¿žæŽ¥èµ·æ¥ã€‚ +`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 ----------------- @@ -89,13 +97,14 @@ we concatenate the data. The `ethereumjs-abi >>>>>> english/develop .. code-block:: javascript - // recipient is the address that should be paid. - // amount, in wei, specifies how much ether should be sent. - // nonce can be any unique number to prevent replay attacks - // contractAddress is used to prevent cross-contract replay attacks + // recipient, 是应该被支付的地å€ã€‚ + // amount,å•ä½æ˜¯ wei, 指定应该å‘é€å¤šå°‘ether。 + // nonce, å¯ä»¥æ˜¯ä»»ä½•å”¯ä¸€çš„数字,以防止é‡æ”¾æ”»å‡»ã€‚ + // contractAddress, 用于防止跨åˆçº¦çš„é‡æ”¾æ”»å‡»ã€‚ function signPayment(recipient, amount, nonce, contractAddress, callback) { var hash = "0x" + abi.soliditySHA3( ["address", "uint256", "uint256", "address"], @@ -105,72 +114,104 @@ Here is a JavaScript function that creates the proper signature for the ``Receiv web3.eth.personal.sign(hash, web3.eth.defaultAccount, callback); } -Recovering the Message Signer in Solidity ------------------------------------------ - -In general, ECDSA signatures consist of two parameters, -``r`` and ``s``. Signatures in Ethereum include a third -parameter called ``v``, that you can use to verify which -account's private key was used to sign the message, and -the transaction's sender. Solidity provides a built-in -function :ref:`ecrecover ` that -accepts a message along with the ``r``, ``s`` and ``v`` parameters -and returns the address that was used to sign the message. - -Extracting the Signature Parameters ------------------------------------ - -Signatures produced by web3.js are the concatenation of ``r``, -``s`` and ``v``, so the first step is to split these parameters -apart. You can do this on the client-side, but doing it inside -the smart contract means you only need to send one signature -parameter rather than three. Splitting apart a byte array into -its constituent parts is a mess, so we use -:doc:`inline assembly ` to do the job in the ``splitSignature`` -function (the third function in the full contract at the end of this section). - -Computing the Message Hash +在Solidity中æ¢å¤ä¿¡æ¯ç­¾å者 -------------------------- -The smart contract needs to know exactly what parameters were signed, and so it -must recreate the message from the parameters and use that for signature verification. -The functions ``prefixed`` and ``recoverSigner`` do this in the ``claimPayment`` function. +一般æ¥è¯´ï¼ŒECDSAçš„ç­¾å由两个å‚数组æˆï¼Œ ``r`` å’Œ ``s``。 +以太åŠçš„ç­¾å包括第三个å‚æ•° ``v`` ,您å¯ä»¥ç”¨å®ƒæ¥éªŒè¯æ˜¯å“ªä¸ªè´¦æˆ·çš„ç§é’¥è¢«ç”¨æ¥ç­¾ç½²ä¿¡æ¯ï¼Œ +以åŠä½œä¸ºäº¤æ˜“çš„å‘é€è€…。Solidity æ供了一个内置函数 +:ref:`ecrecover `, +它接å—一个消æ¯ä»¥åŠ ``r``, ``s`` å’Œ ``v`` å‚数,然åŽè¿”回用于签署该消æ¯çš„地å€ã€‚ + +æå–ç­¾åå‚æ•° +------------ + +web3.js 产生的签å是 ``r``, ``s`` å’Œ ``v`` 的拼接的, +所以第一步是把这些å‚数分开。您å¯ä»¥åœ¨å®¢æˆ·ç«¯è¿™æ ·åšï¼Œ +但在智能åˆçº¦å†…这样åšæ„味ç€ä½ åªéœ€è¦å‘é€ä¸€ä¸ªç­¾åå‚数而ä¸æ˜¯ä¸‰ä¸ªã€‚ +将一个字节数组分割æˆå®ƒçš„组æˆéƒ¨åˆ†æ˜¯å¾ˆéº»çƒ¦çš„, +所以我们在 ``splitSignature`` 函数中使用 +:doc:`inline assembly ` 完æˆè¿™é¡¹å·¥ä½œï¼ˆæœ¬èŠ‚末尾的完整åˆçº¦ä¸­çš„第三个函数)。 -The full contract ------------------ + +计算信æ¯å“ˆå¸Œå€¼ +-------------- + +智能åˆçº¦éœ€è¦ç¡®åˆ‡åœ°çŸ¥é“哪些å‚数用于签å, +因此它必须通过å‚æ•°é‡æ–°åˆ›å»ºæ¶ˆæ¯ï¼Œå¹¶ä½¿ç”¨è¯¥æ¶ˆæ¯è¿›è¡Œç­¾å验è¯ã€‚ +在 ``claimPayment`` 函数中,函数 ``prefixed`` å’Œ ``recoverSigner`` åšäº†è¿™ä»¶äº‹ã€‚ + + +完整的åˆçº¦ +---------- .. code-block:: solidity :force: // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; - // This will report a warning due to deprecated selfdestruct +<<<<<<< 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; - // this recreates the message that was signed on the client + // 这将é‡æ–°åˆ›å»ºåœ¨å®¢æˆ·ç«¯ä¸Šç­¾åçš„ä¿¡æ¯ã€‚ bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this))); - require(recoverSigner(message, signature) == owner); - payable(msg.sender).transfer(amount); } - /// destroy the contract and reclaim the leftover funds. +<<<<<<< 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); } - /// signature methods. + /// ç­¾å方法。 function splitSignature(bytes memory sig) internal pure @@ -179,11 +220,11 @@ The full contract require(sig.length == 65); assembly { - // first 32 bytes, after the length prefix. + // å‰32个字节,在长度å‰ç¼€ä¹‹åŽã€‚ r := mload(add(sig, 32)) - // second 32 bytes. + // 第二个32字节。 s := mload(add(sig, 64)) - // final byte (first byte of the next 32 bytes). + // 最åŽä¸€ä¸ªå­—节(下一个32字节的第一个字节)。 v := byte(0, mload(add(sig, 96))) } @@ -196,82 +237,75 @@ The full contract returns (address) { (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig); - return ecrecover(message, v, r, s); } - /// builds a prefixed hash to mimic the behavior of eth_sign. + /// 构建一个å‰ç¼€å“ˆå¸Œå€¼ï¼Œä»¥æ¨¡ä»¿ eth_sign 的行为。 function prefixed(bytes32 hash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } } -Writing a Simple Payment Channel -================================ +编写一个简å•çš„支付通é“åˆçº¦ +============================ -Alice now builds a simple but complete implementation of a payment -channel. Payment channels use cryptographic signatures to make -repeated transfers of Ether securely, instantaneously, and without transaction fees. +Alice现在建立了一个简å•ä½†å®Œæ•´çš„支付通é“的实现。 +支付通é“使用加密签åæ¥å®‰å…¨ã€å³æ—¶åœ°é‡å¤è½¬ç§»ä»¥å¤ªå¸ï¼Œ +并且没有交易费用。 -What is a Payment Channel? --------------------------- +什么是支付通é“? +---------------- -Payment channels allow participants to make repeated transfers of Ether -without using transactions. This means that you can avoid the delays and -fees associated with transactions. We are going to explore a simple -unidirectional payment channel between two parties (Alice and Bob). It involves three steps: +支付通é“å…许å‚与者在ä¸ä½¿ç”¨äº¤æ˜“的情况下é‡å¤è½¬ç§»ä»¥å¤ªå¸ã€‚ +è¿™æ„味ç€ï¼Œä½ å¯ä»¥é¿å…与交易相关的延迟和费用。 +我们将探讨两方(Aliceå’ŒBob)之间一个简å•çš„å•å‘支付通é“。它涉åŠä¸‰ä¸ªæ­¥éª¤ï¼š - 1. Alice funds a smart contract with Ether. This "opens" the payment channel. - 2. Alice signs messages that specify how much of that Ether is owed to the recipient. This step is repeated for each payment. - 3. Bob "closes" the payment channel, withdrawing his portion of the Ether and sending the remainder back to the sender. + 1. Alice用以太å¸ä¸ºæ™ºèƒ½åˆçº¦æ供资金。这就 "打开" 了支付通é“。 + 2. Alice签署信æ¯ï¼Œè¯´æ˜Žæ¬ æŽ¥æ”¶è€…多少以太å¸ã€‚这个步骤对æ¯ä¸€ç¬”付款都è¦é‡å¤è¿›è¡Œã€‚ + 3. Bob "关闭" 支付通é“,å–出他的那部分以太å¸ï¼Œå¹¶å°†å‰©ä½™éƒ¨åˆ†å‘回给å‘é€æ–¹ã€‚ .. note:: - Only steps 1 and 3 require Ethereum transactions, step 2 means that the sender - transmits a cryptographically signed message to the recipient via off chain - methods (e.g. email). This means only two transactions are required to support - any number of transfers. - -Bob is guaranteed to receive his funds because the smart contract escrows the -Ether and honours a valid signed message. The smart contract also enforces a -timeout, so Alice is guaranteed to eventually recover her funds even if the -recipient refuses to close the channel. It is up to the participants in a payment -channel to decide how long to keep it open. For a short-lived transaction, -such as paying an internet café for each minute of network access, the payment -channel may be kept open for a limited duration. On the other hand, for a -recurring payment, such as paying an employee an hourly wage, the payment channel -may be kept open for several months or years. - -Opening the Payment Channel ---------------------------- - -To open the payment channel, Alice deploys the smart contract, attaching -the Ether to be escrowed and specifying the intended recipient and a -maximum duration for the channel to exist. This is the function -``SimplePaymentChannel`` in the contract, at the end of this section. - -Making Payments + åªæœ‰æ­¥éª¤1å’Œ3需è¦ä»¥å¤ªåŠäº¤æ˜“,æ„味ç€æ­¥éª¤2中å‘é€æ–¹å¯ä»¥é€šè¿‡é“¾ä¸‹æ–¹æ³•ï¼ˆå¦‚电å­é‚®ä»¶ï¼‰ + å‘接收方å‘é€åŠ å¯†ç­¾åçš„ä¿¡æ¯ã€‚è¿™æ„味ç€åªéœ€è¦ä¸¤ä¸ªäº¤æ˜“å°±å¯ä»¥æ”¯æŒä»»ä½•æ•°é‡çš„转移。 + +Bobä¿è¯ä¼šæ”¶åˆ°ä»–的资金,因为智能åˆçº¦æ‰˜ç®¡äº†ä»¥å¤ªå¸ï¼Œ +并兑现了一个有效的签åä¿¡æ¯ã€‚智能åˆçº¦ä¹Ÿå¼ºåˆ¶æ‰§è¡Œè¶…时, +所以å³ä½¿æŽ¥æ”¶è€…æ‹’ç»å…³é—­é€šé“,Alice也能ä¿è¯æœ€ç»ˆæ”¶å›žå¥¹çš„资金。 +由支付通é“çš„å‚与者决定ä¿æŒé€šé“的开放时间。对于一个短暂的交易, +如å‘网å§æ”¯ä»˜æ¯åˆ†é’Ÿçš„网络访问费,支付通é“å¯ä»¥ä¿æŒæœ‰é™çš„开放时间。 +å¦ä¸€æ–¹é¢ï¼Œå¯¹äºŽç»å¸¸æ€§çš„支付,如å‘雇员支付æ¯å°æ—¶çš„工资, +支付渠é“å¯èƒ½ä¼šä¿æŒå¼€æ”¾å‡ ä¸ªæœˆæˆ–几年。 + +å¼€é€šæ”¯ä»˜æ¸ é“ +------------ + +为了开通支付通é“,Alice部署了智能åˆçº¦ï¼Œ +添加了è¦æ‰˜ç®¡çš„以太å¸ï¼Œå¹¶æŒ‡å®šäº†é¢„期接收者和通é“存在的最长时间。 +这就是本节末尾åˆåŒä¸­çš„函数 ``SimplePaymentChannel``。 + +进行支付 --------------- -Alice makes payments by sending signed messages to Bob. -This step is performed entirely outside of the Ethereum network. -Messages are cryptographically signed by the sender and then transmitted directly to the recipient. +Alice通过å‘Bobå‘é€ç­¾åä¿¡æ¯è¿›è¡Œæ”¯ä»˜ã€‚ +这一步骤完全在以太åŠç½‘络之外进行。 +消æ¯ç”±å‘é€æ–¹åŠ å¯†ç­¾å,然åŽç›´æŽ¥ä¼ é€ç»™æŽ¥æ”¶æ–¹ã€‚ + +æ¯æ¡ä¿¡æ¯åŒ…括以下信æ¯ï¼š -Each message includes the following information: + * 智能åˆçº¦çš„地å€ï¼Œç”¨äºŽé˜²æ­¢è·¨åˆçº¦é‡æ”¾æ”»å‡»ã€‚ + * 到目å‰ä¸ºæ­¢ï¼Œæ¬ æŽ¥æ”¶æ–¹çš„以太å¸çš„总金é¢ã€‚ - * The smart contract's address, used to prevent cross-contract replay attacks. - * The total amount of Ether that is owed to the recipient so far. +一个支付通é“åªå…³é—­ä¸€æ¬¡ï¼Œå°±æ˜¯åœ¨ä¸€ç³»åˆ—转账结æŸåŽã€‚ +正因为如此,所å‘é€çš„ç­¾åä¿¡æ¯ä¸­åªæœ‰ä¸€ä¸ªèƒ½è¢«èµŽå›žã€‚ +这就是为什么æ¯æ¡ç­¾åä¿¡æ¯éƒ½æŒ‡å®šäº†ä¸€ä¸ªç´¯è®¡çš„以太å¸æ¬ æ¬¾æ€»é¢ï¼Œ +而ä¸æ˜¯å•ä¸ªå°é¢æ”¯ä»˜çš„金é¢ã€‚接收方自然会选择最新的签åä¿¡æ¯æ¥èµŽå›žï¼Œ +因为那是总é¢æœ€é«˜çš„ç­¾åä¿¡æ¯ã€‚æ¯ä¸ªç­¾åä¿¡æ¯çš„nonceä¸å†éœ€è¦äº†ï¼Œ +因为智能åˆçº¦åªå…‘现一个签åä¿¡æ¯ã€‚ +智能åˆçº¦çš„地å€ä»ç„¶è¢«ç”¨æ¥é˜²æ­¢ä¸€ä¸ªæ”¯ä»˜æ¸ é“çš„ç­¾åä¿¡æ¯è¢«ç”¨äºŽå¦ä¸€ä¸ªæ¸ é“。 -A payment channel is closed just once, at the end of a series of transfers. -Because of this, only one of the messages sent is redeemed. This is why -each message specifies a cumulative total amount of Ether owed, rather than the -amount of the individual micropayment. The recipient will naturally choose to -redeem the most recent message because that is the one with the highest total. -The nonce per-message is not needed anymore, because the smart contract only -honours a single message. The address of the smart contract is still used -to prevent a message intended for one payment channel from being used for a different channel. +下é¢æ˜¯ç»è¿‡ä¿®æ”¹çš„JavaScript代ç ï¼Œç”¨äºŽå¯¹ä¸Šä¸€èŠ‚中的信æ¯è¿›è¡ŒåŠ å¯†ç­¾å: -Here is the modified JavaScript code to cryptographically sign a message from the previous section: .. code-block:: javascript @@ -290,8 +324,8 @@ Here is the modified JavaScript code to cryptographically sign a message from th ); } - // contractAddress is used to prevent cross-contract replay attacks. - // amount, in wei, specifies how much Ether should be sent. + // contractAddress, 是用æ¥é˜²æ­¢è·¨åˆåŒçš„é‡æ”¾æ”»å‡»ã€‚ + // amount,å•ä½æ˜¯wei,指定了应该å‘é€å¤šå°‘以太。 function signPayment(contractAddress, amount, callback) { var message = constructPaymentMessage(contractAddress, amount); @@ -299,42 +333,57 @@ Here is the modified JavaScript code to cryptographically sign a message from th } -Closing the Payment Channel ---------------------------- +å…³é—­æ”¯ä»˜é€šé“ +------------ +<<<<<<< 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 -destroys the contract, sending any remaining Ether back to Alice. To +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. - -The smart contract must verify that the message contains a valid signature from the sender. -The process for doing this verification is the same as the process the recipient uses. -The Solidity functions ``isValidSignature`` and ``recoverSigner`` work just like their -JavaScript counterparts in the previous section, with the latter function borrowed from the ``ReceiverPays`` contract. - -Only the payment channel recipient can call the ``close`` function, -who naturally passes the most recent payment message because that message -carries the highest total owed. If the sender were allowed to call this function, -they could provide a message with a lower amount and cheat the recipient out of what they are owed. - +>>>>>>> english/develop + +智能åˆçº¦å¿…须验è¯è¯¥æ¶ˆæ¯æ˜¯å¦åŒ…å«å‘é€è€…的有效签å。 +进行这ç§éªŒè¯çš„过程与接收者使用签å的过程相åŒã€‚ +Solidity函数 ``isValidSignature`` å’Œ ``recoverSigner`` çš„å·¥ä½œæ–¹å¼ +与上一节中的JavaScript对应函数一样,而åŽè€…的函数是从 ``ReceiverPays`` åˆçº¦ä¸­å€Ÿç”¨çš„。 + +åªæœ‰æ”¯ä»˜é€šé“的接收者å¯ä»¥è°ƒç”¨ ``close`` 函数, +他们自然会传递最新的支付信æ¯ï¼Œå› ä¸ºè¯¥ä¿¡æ¯å¸¦æœ‰æœ€é«˜çš„欠款总é¢ã€‚ +如果å…许å‘é€è€…调用这个函数,他们å¯ä»¥æ供一个金é¢è¾ƒä½Žçš„ç­¾å消æ¯ï¼Œ +骗å–接收者的欠款。 + +<<<<<<< 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 rest via a ``selfdestruct``. +and the sender is sent the remaining funds via a ``transfer``. You can see the ``close`` function in the full contract. +>>>>>>> english/develop -Channel Expiration -------------------- +通é“到期 +-------- -Bob can close the payment channel at any time, but if they fail to do so, -Alice needs a way to recover her escrowed funds. An *expiration* time was set -at the time of contract deployment. Once that time is reached, Alice can call -``claimTimeout`` to recover her funds. You can see the ``claimTimeout`` function in the full contract. +Bobå¯ä»¥åœ¨ä»»ä½•æ—¶å€™å…³é—­æ”¯ä»˜é€šé“,但如果他们没有这样åšï¼Œ +Alice需è¦ä¸€ä¸ªæ–¹æ³•æ¥æ”¶å›žå¥¹çš„托管资金。在åˆåŒéƒ¨ç½²çš„时候,设置了一个 *到期时间*。 +一旦达到这个时间,Aliceå¯ä»¥è°ƒç”¨ ``claimTimeout`` æ¥æ”¶å›žå¥¹çš„资金。 +您å¯ä»¥åœ¨å®Œæ•´çš„åˆçº¦ä¸­çœ‹åˆ° ``claimTimeout`` 函数。 -After this function is called, Bob can no longer receive any Ether, -so it is important that Bob closes the channel before the expiration is reached. +在这个函数被调用åŽï¼ŒBobä¸èƒ½å†æŽ¥æ”¶ä»»ä½•ä»¥å¤ªã€‚ +所以Bob必须在过期å‰å…³é—­é€šé“,这一点很é‡è¦ã€‚ -The full contract +完整的åˆçº¦ ----------------- .. code-block:: solidity @@ -342,11 +391,32 @@ The full contract // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; - // This will report a warning due to deprecated selfdestruct +<<<<<<< HEAD + // 这将报告一个由于废弃的 selfdestruct 而产生的警告 contract SimplePaymentChannel { - 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. + 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 @@ -356,30 +426,58 @@ The full contract 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 { + 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); } - /// the sender can extend the expiration at any time +<<<<<<< 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 { + 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) @@ -388,14 +486,22 @@ The full contract returns (bool) { bytes32 message = prefixed(keccak256(abi.encodePacked(this, amount))); +<<<<<<< HEAD + // 检查签å是å¦æ¥è‡ªä»˜æ¬¾æ–¹ã€‚ + return recoverSigner(message, signature) == sender; + } + + /// 下é¢çš„所有功能是å–自 '创建和验è¯ç­¾å' 的章节。 + +======= // 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 @@ -404,14 +510,13 @@ The full contract require(sig.length == 65); assembly { - // first 32 bytes, after the length prefix + // å‰32个字节,在长度å‰ç¼€ä¹‹åŽã€‚ r := mload(add(sig, 32)) - // second 32 bytes + // 第二个32字节。 s := mload(add(sig, 64)) - // final byte (first byte of the next 32 bytes) + // 最åŽä¸€ä¸ªå­—节(下一个32字节的第一个字节)。 v := byte(0, mload(add(sig, 96))) } - return (v, r, s); } @@ -421,11 +526,10 @@ The full contract returns (address) { (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig); - return ecrecover(message, v, r, s); } - /// builds a prefixed hash to mimic the behavior of eth_sign. + /// 构建一个å‰ç¼€å“ˆå¸Œå€¼ï¼Œä»¥æ¨¡ä»¿eth_sign的行为。 function prefixed(bytes32 hash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } @@ -433,34 +537,33 @@ The full contract .. note:: - The function ``splitSignature`` does not use all security - checks. A real implementation should use a more rigorously tested library, - such as openzepplin's `version `_ of this code. + 函数 ``splitSignature`` 并没有使用所有的安全检查。 + 真正的实现应该使用更严格的测试库,例如openzepplinçš„ + `这个版本 `_ + 的这个代ç ã€‚ -Verifying Payments ------------------- +验è¯ä»˜æ¬¾ +-------- -Unlike in the previous section, messages in a payment channel aren't -redeemed right away. The recipient keeps track of the latest message and -redeems it when it's time to close the payment channel. This means it's -critical that the recipient perform their own verification of each message. -Otherwise there is no guarantee that the recipient will be able to get paid -in the end. +ä¸åŒä¸Žä¸Šä¸€èŠ‚,支付通é“中的信æ¯ä¸ä¼šé©¬ä¸Šè¢«å…‘æ¢ã€‚ +接收者会跟踪最新的信æ¯ï¼Œå¹¶åœ¨å…³é—­æ”¯ä»˜é€šé“的时候赎回它。 +è¿™æ„味ç€æŽ¥æ”¶è€…对æ¯æ¡ä¿¡æ¯è¿›è¡Œè‡ªè¡ŒéªŒè¯æ˜¯è‡³å…³é‡è¦çš„。 +å¦åˆ™å°±ä¸èƒ½ä¿è¯æŽ¥æ”¶è€…最终能够得到付款。 -The recipient should verify each message using the following process: +接收者应使用以下程åºéªŒè¯æ¯æ¡ä¿¡æ¯ï¼š - 1. Verify that the contract address in the message matches the payment channel. - 2. Verify that the new total is the expected amount. - 3. Verify that the new total does not exceed the amount of Ether escrowed. - 4. Verify that the signature is valid and comes from the payment channel sender. + 1. 验è¯ç­¾åä¿¡æ¯ä¸­çš„åˆçº¦åœ°å€æ˜¯å¦ä¸Žæ”¯ä»˜é€šé“相符。 + 2. 验è¯æ–°çš„总é¢æ˜¯å¦ä¸ºé¢„期的数é¢ã€‚ + 3. 确认新的总é¢ä¸è¶…过代管的以太å¸æ•°é¢ã€‚ + 4. 验è¯ç­¾å是å¦æœ‰æ•ˆï¼Œæ˜¯å¦æ¥è‡ªäºŽæ”¯ä»˜é€šé“çš„å‘é€æ–¹ã€‚ -We'll use the `ethereumjs-util `_ -library to write this verification. The final step can be done a number of ways, -and we use JavaScript. The following code borrows the ``constructPaymentMessage`` function from the signing **JavaScript code** above: +我们将使用 `ethereumjs-util `_ +库æ¥ç¼–写这个验è¯ã€‚最åŽä¸€æ­¥å¯ä»¥ç”¨å¤šç§æ–¹å¼å®Œæˆï¼Œæˆ‘们使用JavaScript。 +下é¢çš„代ç å€Ÿç”¨äº†ä¸Šé¢ **JavaScript代ç ** 中加密签åçš„ ``constructPaymentMessage`` 函数。 .. code-block:: javascript - // this mimics the prefixing behavior of the eth_sign JSON-RPC method. + // 这模拟了eth_sign çš„JSON-RPC构建å‰ç¼€çš„方法。 function prefixed(hash) { return ethereumjs.ABI.soliditySHA3( ["string", "bytes32"], diff --git a/docs/examples/modular.rst b/docs/examples/modular.rst index 9ae2849cb4d8..0abcdf63e368 100644 --- a/docs/examples/modular.rst +++ b/docs/examples/modular.rst @@ -1,9 +1,20 @@ .. index:: contract;modular, modular contract -***************** -Modular Contracts -***************** +*********** +模å—化åˆçº¦ +*********** +<<<<<<< HEAD +用模å—化的方法æ¥æž„建您的åˆçº¦ï¼Œå¯ä»¥å¸®åŠ©å‡å°‘å¤æ‚性,æ高å¯è¯»æ€§ï¼Œ +这将有助于在开å‘和代ç å®¡æŸ¥ä¸­å‘现错误和æ¼æ´žã€‚ +如果您å•ç‹¬æŒ‡å®šä¸”控制æ¯ä¸ªæ¨¡å—的行为,您必须考虑的相互作用åªæ˜¯æ¨¡å—之间的相互作用, +而ä¸æ˜¯åˆçº¦çš„其他æ¯ä¸ªçµæ´»æ¨¡å—函数。 +在下é¢çš„例å­ä¸­ï¼Œåˆçº¦ä½¿ç”¨ ``Balances`` :ref:`库 ` çš„ ``move`` 方法 +æ¥æ£€æŸ¥åœ°å€ä¹‹é—´å‘é€çš„ä½™é¢æ˜¯å¦ç¬¦åˆæ‚¨çš„期望。通过这ç§æ–¹å¼ï¼Œ ``Balances`` 库æ供了一个独立的组件, +å¯ä»¥æ­£ç¡®åœ°è·Ÿè¸ªè´¦æˆ·çš„ä½™é¢ã€‚ +å¾ˆå®¹æ˜“éªŒè¯ ``Balances`` 库永远ä¸ä¼šäº§ç”Ÿè´Ÿçš„ä½™é¢æˆ–溢出, +所有余é¢çš„总和在åˆçº¦çš„有效期内是一个ä¸å˜çš„é‡ã€‚ +======= A modular approach to building your contracts helps you reduce the complexity and improve the readability which will help to identify bugs and vulnerabilities during development and code review. @@ -16,6 +27,7 @@ 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 a2651af23882..aea51f1e4a99 100644 --- a/docs/examples/safe-remote.rst +++ b/docs/examples/safe-remote.rst @@ -1,9 +1,20 @@ .. index:: purchase, remote purchase, escrow ******************** -Safe Remote Purchase +安全的远程购买 ******************** +<<<<<<< HEAD +ç›®å‰ï¼Œè¿œç¨‹è´­ä¹°å•†å“需è¦å¤šæ–¹ç›¸äº’信任。最简å•çš„关系涉åŠä¸€ä¸ªå–家和一个买家。 +买方希望从å–方那里收到一件物å“,å–方希望得到金钱(或等价物)作为回报。 +这里é¢æœ‰é—®é¢˜çš„部分是的è¿è¾“。没有办法确定物å“是å¦åˆ°è¾¾ä¹°æ–¹æ‰‹ä¸­ã€‚ + +有多ç§æ–¹æ³•æ¥è§£å†³è¿™ä¸ªé—®é¢˜ï¼Œä½†éƒ½æœ‰è¿™æ ·æˆ–那样的ä¸è¶³ä¹‹å¤„。 +在下é¢çš„例å­ä¸­ï¼ŒåŒæ–¹éƒ½è¦æŠŠä¸¤å€ä»·å€¼äºŽç‰©å“的资金放入åˆçº¦ä¸­ä½œä¸ºæ‰˜ç®¡ã€‚ +åªè¦å‘生这ç§æƒ…况,钱就会一直é”在åˆåŒé‡Œé¢ï¼Œç›´åˆ°ä¹°æ–¹ç¡®è®¤æ”¶åˆ°ç‰©å“。 +之åŽï¼Œä¹°æ–¹ä¼šå¾—到退回的资金(他们押金的一åŠï¼‰ï¼Œå–方得到三å€çš„资金(他们的押金加上物å“的价值)。 +这背åŽçš„想法是,åŒæ–¹éƒ½æœ‰åŠ¨åŠ›åŽ»è§£å†³è¿™ä¸ªé—®é¢˜ï¼Œå¦åˆ™ä»–们的钱就会被永远é”定。 +======= Purchasing goods remotely currently requires multiple parties that need to trust each other. The simplest configuration involves a seller and a buyer. The buyer would like to receive an item from the seller and the seller would like to get some compensation, e.g. Ether, @@ -18,9 +29,9 @@ the buyer is returned the value (half of their deposit) and the seller gets thre 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 -This contract of course does not solve the problem, but gives an overview of how -you can use state machine-like constructs inside a contract. +这个åˆçº¦å½“然ä¸èƒ½è§£å†³é—®é¢˜ï¼Œä½†å®ƒæ¦‚述了如何在åˆçº¦å†…使用类似状æ€æœºçš„构造。 .. code-block:: solidity @@ -33,7 +44,7 @@ you can use state machine-like constructs inside a contract. address payable public buyer; enum State { Created, Locked, Release, Inactive } - // The state variable has a default value of the first member, `State.created` + // 状æ€å˜é‡çš„默认值是第一个æˆå‘˜ï¼Œ`State.created`。 State public state; modifier condition(bool condition_) { @@ -41,13 +52,13 @@ you can use state machine-like constructs inside a contract. _; } - /// Only the buyer can call this function. + /// åªæœ‰ä¹°æ–¹å¯ä»¥è°ƒç”¨è¿™ä¸ªå‡½æ•°ã€‚ error OnlyBuyer(); - /// Only the seller can call this function. + /// åªæœ‰å–æ–¹å¯ä»¥è°ƒç”¨è¿™ä¸ªå‡½æ•°ã€‚ error OnlySeller(); - /// The function cannot be called at the current state. + /// 在当å‰çŠ¶æ€ä¸‹ä¸èƒ½è°ƒç”¨è¯¥å‡½æ•°ã€‚ error InvalidState(); - /// The provided value has to be even. + /// æ供的值必须是å¶æ•°ã€‚ error ValueNotEven(); modifier onlyBuyer() { @@ -73,9 +84,9 @@ you can use state machine-like constructs inside a contract. event ItemReceived(); event SellerRefunded(); - // Ensure that `msg.value` is an even number. - // Division will truncate if it is an odd number. - // Check via multiplication that it wasn't an odd number. + // ç¡®ä¿ `msg.value` 是一个å¶æ•°ã€‚ + // 如果是奇数,除法会截断。 + // 通过乘法检查它ä¸æ˜¯ä¸€ä¸ªå¥‡æ•°ã€‚ constructor() payable { seller = payable(msg.sender); value = msg.value / 2; @@ -83,9 +94,8 @@ you can use state machine-like constructs inside a contract. revert ValueNotEven(); } - /// Abort the purchase and reclaim the ether. - /// Can only be called by the seller before - /// the contract is locked. + /// 终止购买并收回 ether。 + /// åªèƒ½ç”±å–方在åˆåŒé”定å‰èƒ½è°ƒç”¨ã€‚ function abort() external onlySeller @@ -93,17 +103,16 @@ you can use state machine-like constructs inside a contract. { emit Aborted(); state = State.Inactive; - // We use transfer here directly. It is - // reentrancy-safe, because it is the - // last call in this function and we - // already changed the state. + // 我们在这里直接使用 `transfer`。 + // 它å¯ä»¥å®‰å…¨åœ°é‡å…¥ã€‚ + // 因为它是这个函数中的最åŽä¸€æ¬¡è°ƒç”¨ï¼Œ + // 而且我们已ç»æ”¹å˜äº†çŠ¶æ€ã€‚ seller.transfer(address(this).balance); } - /// Confirm the purchase as buyer. - /// Transaction has to include `2 * value` ether. - /// The ether will be locked until confirmReceived - /// is called. + /// 买方确认购买。 + /// 交易必须包括 `2 * value` ether。 + /// Ether 将被é”ä½ï¼Œç›´åˆ°è°ƒç”¨ confirmReceived。 function confirmPurchase() external inState(State.Created) @@ -115,33 +124,31 @@ you can use state machine-like constructs inside a contract. state = State.Locked; } - /// Confirm that you (the buyer) received the item. - /// This will release the locked ether. + /// 确认您(买方)已ç»æ”¶åˆ°äº†è¯¥ç‰©å“。 + /// 这将释放é”定的 ether。 function confirmReceived() external onlyBuyer inState(State.Locked) { emit ItemReceived(); - // It is important to change the state first because - // otherwise, the contracts called using `send` below - // can call in again here. + // 首先改å˜çŠ¶æ€æ˜¯å¾ˆé‡è¦çš„,å¦åˆ™çš„è¯ï¼Œ + // 下é¢ä½¿ç”¨ `send` 调用的åˆçº¦å¯ä»¥åœ¨è¿™é‡Œå†æ¬¡è°ƒç”¨ã€‚ state = State.Release; buyer.transfer(value); } - /// This function refunds the seller, i.e. - /// pays back the locked funds of the seller. + /// 该功能为å–家退款, + /// å³é€€è¿˜å–家é”定的资金。 function refundSeller() external onlySeller inState(State.Release) { emit SellerRefunded(); - // It is important to change the state first because - // otherwise, the contracts called using `send` below - // can call in again here. + // 首先改å˜çŠ¶æ€æ˜¯å¾ˆé‡è¦çš„,å¦åˆ™çš„è¯ï¼Œ + // 下é¢ä½¿ç”¨ `send` 调用的åˆçº¦å¯ä»¥åœ¨è¿™é‡Œå†æ¬¡è°ƒç”¨ã€‚ state = State.Inactive; seller.transfer(3 * value); diff --git a/docs/examples/voting.rst b/docs/examples/voting.rst index de899da7abcf..dd747e5d9ebb 100644 --- a/docs/examples/voting.rst +++ b/docs/examples/voting.rst @@ -2,77 +2,63 @@ .. _voting: -****** -Voting -****** - -The following contract is quite complex, but showcases -a lot of Solidity's features. It implements a voting -contract. Of course, the main problems of electronic -voting is how to assign voting rights to the correct -persons and how to prevent manipulation. We will not -solve all problems here, but at least we will show -how delegated voting can be done so that vote counting -is **automatic and completely transparent** at the -same time. - -The idea is to create one contract per ballot, -providing a short name for each option. -Then the creator of the contract who serves as -chairperson will give the right to vote to each -address individually. - -The persons behind the addresses can then choose -to either vote themselves or to delegate their -vote to a person they trust. - -At the end of the voting time, ``winningProposal()`` -will return the proposal with the largest number -of votes. +******** +投票åˆçº¦ +******** + +下é¢çš„åˆçº¦ç›¸å½“å¤æ‚,但展示了Solidity的很多特性。 +它实现了一个投票åˆçº¦ã€‚当然, +电å­æŠ•ç¥¨çš„主è¦é—®é¢˜æ˜¯å¦‚何将投票æƒåˆ†é…给正确的人以åŠå¦‚何防止人为æ“纵。 +我们ä¸ä¼šåœ¨è¿™é‡Œè§£å†³æ‰€æœ‰çš„问题,但至少我们会展示如何进行委托投票, +与此åŒæ—¶ï¼Œä½¿è®¡ç¥¨æ˜¯ **自动且完全é€æ˜Žçš„。** + +我们的想法是为æ¯å¼ é€‰ç¥¨åˆ›å»ºä¸€ä»½åˆçº¦ï¼Œ +为æ¯ä¸ªé€‰é¡¹æ供一个简称。 +然åŽï¼Œä½œä¸ºåˆçº¦çš„创造者——å³ä¸»å¸­ï¼Œ +将给予æ¯ä¸ªåœ°å€å•ç‹¬çš„投票æƒã€‚ + +地å€åŽé¢çš„人å¯ä»¥é€‰æ‹©è‡ªå·±æŠ•ç¥¨ï¼Œæˆ–者委托给他们信任的人æ¥æŠ•ç¥¨ã€‚ + +在投票时间结æŸæ—¶ï¼Œ ``winningProposal()`` 将返回拥有最大票数的æ案。 .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; - /// @title Voting with delegation. + /// @title 委托投票 contract Ballot { - // This declares a new complex type which will - // be used for variables later. - // It will represent a single voter. + // 这声明了一个新的å¤æ‚类型,用于ç¨åŽå˜é‡ã€‚ + // 它用æ¥è¡¨ç¤ºä¸€ä¸ªé€‰æ°‘。 struct Voter { - uint weight; // weight is accumulated by delegation - bool voted; // if true, that person already voted - address delegate; // person delegated to - uint vote; // index of the voted proposal + uint weight; // 计票的æƒé‡ + bool voted; // 若为真,代表该人已投票 + address delegate; // 被委托人 + uint vote; // 投票æ案的索引 } - // This is a type for a single proposal. + // æ案的类型 struct Proposal { - bytes32 name; // short name (up to 32 bytes) - uint voteCount; // number of accumulated votes + bytes32 name; // 简称(最长32个字节) + uint voteCount; // 得票数 } address public chairperson; - - // This declares a state variable that - // stores a `Voter` struct for each possible address. + // 这声明了一个状æ€å˜é‡ï¼Œä¸ºæ¯ä¸ªå¯èƒ½çš„地å€å­˜å‚¨ä¸€ä¸ª `Voter`。 mapping(address => Voter) public voters; - // A dynamically-sized array of `Proposal` structs. + // 一个 `Proposal` 结构类型的动æ€æ•°ç»„。 Proposal[] public proposals; - /// Create a new ballot to choose one of `proposalNames`. + /// 为 `proposalNames` 中的æ¯ä¸ªæ案,创建一个新的(投票)表决 constructor(bytes32[] memory proposalNames) { chairperson = msg.sender; voters[chairperson].weight = 1; - // For each of the provided proposal names, - // create a new proposal object and add it - // to the end of the array. + // 对于æ供的æ¯ä¸ªæ案å称, + // 创建一个新的 Proposal 对象并把它添加到数组的末尾。 for (uint i = 0; i < proposalNames.length; i++) { - // `Proposal({...})` creates a temporary - // Proposal object and `proposals.push(...)` - // appends it to the end of `proposals`. + // `Proposal({...})` 创建一个临时 Proposal 对象 + // `proposals.push(...)` 将其添加到 `proposals` 的末尾 proposals.push(Proposal({ name: proposalNames[i], voteCount: 0 @@ -80,19 +66,14 @@ of votes. } } - // Give `voter` the right to vote on this ballot. - // May only be called by `chairperson`. + // 给予 `voter` 在这张选票上投票的æƒåˆ©ã€‚ + // åªæœ‰ `chairperson` å¯ä»¥è°ƒç”¨è¯¥å‡½æ•°ã€‚ function giveRightToVote(address voter) external { - // If the first argument of `require` evaluates - // to `false`, execution terminates and all - // changes to the state and to Ether balances - // are reverted. - // This used to consume all gas in old EVM versions, but - // not anymore. - // It is often a good idea to use `require` to check if - // functions are called correctly. - // As a second argument, you can also provide an - // explanation about what went wrong. + // è‹¥ `require` 的第一个å‚数的计算结果为 `false`, + // 则终止执行,撤销所有对状æ€å’Œä»¥å¤ªå¸ä½™é¢çš„改动。 + // 在旧版的 EVM 中这曾ç»ä¼šæ¶ˆè€—所有 gas,但现在ä¸ä¼šäº†ã€‚ + // 使用 `require` æ¥æ£€æŸ¥å‡½æ•°æ˜¯å¦è¢«æ­£ç¡®åœ°è°ƒç”¨ï¼Œé€šå¸¸æ˜¯ä¸ªå¥½ä¸»æ„。 + // 您也å¯ä»¥åœ¨ `require` 的第二个å‚数中æ供一个对错误情况的解释。 require( msg.sender == chairperson, "Only chairperson can give right to vote." @@ -105,53 +86,48 @@ of votes. voters[voter].weight = 1; } - /// Delegate your vote to the voter `to`. + /// 把您的投票委托给投票者 `to`。 function delegate(address to) external { - // assigns reference + // 指定引用 Voter storage sender = voters[msg.sender]; require(sender.weight != 0, "You have no right to vote"); require(!sender.voted, "You already voted."); require(to != msg.sender, "Self-delegation is disallowed."); - // Forward the delegation as long as - // `to` also delegated. - // In general, such loops are very dangerous, - // because if they run too long, they might - // need more gas than is available in a block. - // In this case, the delegation will not be executed, - // but in other situations, such loops might - // cause a contract to get "stuck" completely. + // 委托是å¯ä»¥ä¼ é€’的,åªè¦è¢«å§”托者 `to` 也设置了委托。 + // 一般æ¥è¯´ï¼Œè¿™æ ·çš„循环委托是éžå¸¸å±é™©çš„,因为如果传递的链æ¡å¤ªé•¿ï¼Œ + // å¯èƒ½éœ€è¦æ¶ˆè€—çš„gas就会超过一个区å—中的å¯ç”¨æ•°é‡ã€‚ + // è¿™ç§æƒ…况下,委托ä¸ä¼šè¢«æ‰§è¡Œã€‚ + // 但在其他情况下,如果形æˆé—­çŽ¯ï¼Œåˆ™ä¼šå¯¼è‡´åˆçº¦å®Œå…¨è¢« "å¡ä½"。 while (voters[to].delegate != address(0)) { to = voters[to].delegate; - // We found a loop in the delegation, not allowed. + // ä¸å…许闭环委托 require(to != msg.sender, "Found loop in delegation."); } Voter storage delegate_ = voters[to]; - // Voters cannot delegate to accounts that cannot vote. + // 投票者ä¸èƒ½å°†æŠ•ç¥¨æƒå§”托给ä¸èƒ½æŠ•ç¥¨çš„账户。 require(delegate_.weight >= 1); - // Since `sender` is a reference, this - // modifies `voters[msg.sender]`. + // 由于 `sender` 是一个引用, + // 因此这会修改 `voters[msg.sender]`。 sender.voted = true; sender.delegate = to; if (delegate_.voted) { - // If the delegate already voted, - // directly add to the number of votes + // 若被委托者已ç»æŠ•è¿‡ç¥¨äº†ï¼Œç›´æŽ¥å¢žåŠ å¾—票数。 proposals[delegate_.vote].voteCount += sender.weight; } else { - // If the delegate did not vote yet, - // add to her weight. + // 若被委托者还没投票,增加委托者的æƒé‡ã€‚ delegate_.weight += sender.weight; } } - /// Give your vote (including votes delegated to you) - /// to proposal `proposals[proposal].name`. + /// 把您的票(包括委托给您的票), + /// 投给æ案 `proposals[proposal].name`。 function vote(uint proposal) external { Voter storage sender = voters[msg.sender]; require(sender.weight != 0, "Has no right to vote"); @@ -159,14 +135,12 @@ of votes. sender.voted = true; sender.vote = proposal; - // If `proposal` is out of the range of the array, - // this will throw automatically and revert all - // changes. + // 如果 `proposal` 超过了数组的范围, + // 则会自动抛出异常,并æ¢å¤æ‰€æœ‰çš„改动。 proposals[proposal].voteCount += sender.weight; } - /// @dev Computes the winning proposal taking all - /// previous votes into account. + /// @dev 结åˆä¹‹å‰æ‰€æœ‰æŠ•ç¥¨çš„情况下,计算出获胜的æ案。 function winningProposal() public view returns (uint winningProposal_) { @@ -179,9 +153,8 @@ of votes. } } - // Calls winningProposal() function to get the index - // of the winner contained in the proposals array and then - // returns the name of the winner + // 调用 `winningProposal()` 函数以获å–æ案数组中获胜者的索引, + // 并以此返回获胜者的å称。 function winnerName() external view returns (bytes32 winnerName_) { @@ -190,11 +163,9 @@ of votes. } -Possible Improvements +å¯èƒ½çš„优化 ===================== -Currently, many transactions are needed to -assign the rights to vote to all participants. -Moreover, if two or more proposals have the same -number of votes, ``winningProposal()`` is not able -to register a tie. Can you think of a way to fix these issues? \ No newline at end of file +当å‰ï¼Œä¸ºäº†æŠŠæŠ•ç¥¨æƒåˆ†é…给所有å‚与者,需è¦æ‰§è¡Œå¾ˆå¤šäº¤æ˜“。 +此外,如果两个或更多的æ案有相åŒçš„票数, ``winningProposal()`` 无法登记平局。 +您能想出一个办法æ¥è§£å†³è¿™äº›é—®é¢˜å—? 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.rst b/docs/grammar.rst index 788b6d69504b..eba4f817eccc 100644 --- a/docs/grammar.rst +++ b/docs/grammar.rst @@ -1,5 +1,5 @@ **************** -Language Grammar +语法 **************** .. a4:autogrammar:: SolidityParser @@ -10,4 +10,4 @@ Language Grammar .. a4:autogrammar:: SolidityLexer :only-reachable-from: SolidityParser.sourceUnit :fragments: - :cc-to-dash: \ No newline at end of file + :cc-to-dash: diff --git a/docs/grammar/SolidityLexer.g4 b/docs/grammar/SolidityLexer.g4 index 0452f9fa0bb6..1633bc01dc26 100644 --- a/docs/grammar/SolidityLexer.g4 +++ b/docs/grammar/SolidityLexer.g4 @@ -1,7 +1,7 @@ lexer grammar SolidityLexer; /** - * Keywords reserved for future use in Solidity. + * 为将æ¥åœ¨Solidity中使用ä¿ç•™çš„关键字。 */ ReservedKeywords: 'after' | 'alias' | 'apply' | 'auto' | 'byte' | 'case' | 'copyof' | 'default' | 'define' | 'final' @@ -28,14 +28,14 @@ Do: 'do'; Else: 'else'; Emit: 'emit'; Enum: 'enum'; -Error: 'error'; // not a real keyword +Error: 'error'; // ä¸æ˜¯çœŸæ­£çš„关键字 Event: 'event'; External: 'external'; Fallback: 'fallback'; False: 'false'; Fixed: 'fixed' | ('fixed' [1-9][0-9]* 'x' [1-9][0-9]*); /** - * Bytes types of fixed length. + * 固定长度的字节类型。 */ FixedBytes: 'bytes1' | 'bytes2' | 'bytes3' | 'bytes4' | 'bytes5' | 'bytes6' | 'bytes7' | 'bytes8' | @@ -60,7 +60,7 @@ Memory: 'memory'; Modifier: 'modifier'; New: 'new'; /** - * Unit denomination for numbers. + * æ•°å­—çš„å•ä½è®¡ä»·ã€‚ */ SubDenomination: 'wei' | 'gwei' | 'ether' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years'; Override: 'override'; @@ -74,8 +74,8 @@ Return: 'return'; Returns: 'returns'; Revert: 'revert'; // not a real keyword /** - * Sized signed integer types. - * int is an alias of int256. + * 有符å·çš„整数类型。 + * int是int256的一个别å。 */ SignedIntegerType: 'int' | 'int8' | 'int16' | 'int24' | 'int32' | 'int40' | 'int48' | 'int56' | 'int64' | @@ -92,8 +92,8 @@ Ufixed: 'ufixed' | ('ufixed' [1-9][0-9]+ 'x' [1-9][0-9]+); Unchecked: 'unchecked'; Unicode: 'unicode'; /** - * Sized unsigned integer types. - * uint is an alias of uint256. + * 无符å·æ•´æ•°ç±»åž‹ã€‚ + * uint是uint256的一个别å。 */ UnsignedIntegerType: 'uint' | 'uint8' | 'uint16' | 'uint24' | 'uint32' | 'uint40' | 'uint48' | 'uint56' | 'uint64' | @@ -163,32 +163,32 @@ DoubleQuote: '"'; SingleQuote: '\''; /** - * A non-empty quoted string literal restricted to printable characters. + * 一个éžç©ºçš„带引å·çš„字符串字é¢é‡ï¼Œé™åˆ¶ä¸ºå¯æ‰“å°çš„字符。 */ NonEmptyStringLiteral: '"' DoubleQuotedStringCharacter+ '"' | '\'' SingleQuotedStringCharacter+ '\''; /** - * An empty string literal + * 一个空的字符串字é¢é‡ */ EmptyStringLiteral: '"' '"' | '\'' '\''; -// Note that this will also be used for Yul string literals. +// 请注æ„,这也将被用于Yul字符串字é¢é‡ã€‚ //@doc:inline fragment DoubleQuotedStringCharacter: DoubleQuotedPrintable | EscapeSequence; -// Note that this will also be used for Yul string literals. +// 请注æ„,这也将被用于Yul字符串字é¢é‡ã€‚ //@doc:inline fragment SingleQuotedStringCharacter: SingleQuotedPrintable | EscapeSequence; /** - * Any printable character except single quote or back slash. + * 除å•å¼•å·æˆ–å斜线外的任何å¯æ‰“å°å­—符。 */ fragment SingleQuotedPrintable: [\u0020-\u0026\u0028-\u005B\u005D-\u007E]; /** - * Any printable character except double quote or back slash. + * 除åŒå¼•å·æˆ–å斜线外的任何å¯æ‰“å°çš„字符。 */ fragment DoubleQuotedPrintable: [\u0020-\u0021\u0023-\u005B\u005D-\u007E]; /** - * Escape sequence. - * Apart from common single character escape sequences, line breaks can be escaped - * as well as four hex digit unicode escapes \\uXXXX and two digit hex escape sequences \\xXX are allowed. + * 转义åºåˆ—。 + * 除了常è§çš„å•å­—符转义åºåˆ—外,还å¯ä»¥è½¬ä¹‰æ¢è¡Œï¼Œ + * 以åŠå…许四个å六进制数字的unicode转义\\uXXXX和两个å六进制数字的转义åºåˆ—\\xXX。 */ fragment EscapeSequence: '\\' ( @@ -197,7 +197,7 @@ fragment EscapeSequence: | 'x' HexCharacter HexCharacter ); /** - * A single quoted string literal allowing arbitrary unicode characters. + * å•å¼•å·å­—符串字é¢é‡ï¼Œå…许任æ„çš„unicode字符。 */ UnicodeStringLiteral: 'unicode' (('"' DoubleQuotedUnicodeStringCharacter* '"') | ('\'' SingleQuotedUnicodeStringCharacter* '\'')); //@doc:inline @@ -205,13 +205,13 @@ fragment DoubleQuotedUnicodeStringCharacter: ~["\r\n\\] | EscapeSequence; //@doc:inline fragment SingleQuotedUnicodeStringCharacter: ~['\r\n\\] | EscapeSequence; -// Note that this will also be used for Yul hex string literals. +// 注æ„,这也将用于Yulå六进制字符串字é¢é‡ã€‚ /** - * Hex strings need to consist of an even number of hex digits that may be grouped using underscores. + * å六进制字符串需è¦åŒ…å«å¶æ•°ä¸ªå六进制数字,å¯ä»¥ä½¿ç”¨ä¸‹åˆ’线分组。 */ HexString: 'hex' (('"' EvenHexDigits? '"') | ('\'' EvenHexDigits? '\'')); /** - * Hex numbers consist of a prefix and an arbitrary number of hex digits that may be delimited by underscores. + * å六进制数字由å‰ç¼€å’Œå¯ä»¥ç”¨ä¸‹åˆ’线分隔的任æ„æ•°é‡çš„å六进制数字组æˆã€‚ */ HexNumber: '0' 'x' HexDigits; //@doc:inline @@ -222,17 +222,16 @@ fragment EvenHexDigits: HexCharacter HexCharacter ('_'? HexCharacter HexCharacte fragment HexCharacter: [0-9A-Fa-f]; /** - * Scanned but not used by any rule, i.e, disallowed. - * solc parser considers number starting with '0', not immediately followed by '.' or 'x' as - * octal, even if non octal digits '8' and '9' are present. + * 已扫æ,但未被任何规则使用,å³ä¸å…许。 + * solc 解æžå™¨è®¤ä¸ºä»¥'0'开头,åŽé¢æ²¡æœ‰ç´§è·Ÿ'.'或'x'的数字为八进制数 + * å³ä½¿å­˜åœ¨éžå…«è¿›åˆ¶æ•°å­—'8'å’Œ'9'。 */ OctalNumber: '0' DecimalDigits ('.' DecimalDigits)?; /** - * A decimal number literal consists of decimal digits that may be delimited by underscores and - * an optional positive or negative exponent. - * If the digits contain a decimal point, the literal has fixed point type. + * 一个å进制数字的字é¢é‡ç”±å进制数字组æˆï¼Œå¯ä»¥ç”¨ä¸‹åˆ’线和一个å¯é€‰çš„正负指数æ¥åˆ†éš”。 + * 如果这些数字包å«ä¸€ä¸ªå°æ•°ç‚¹ï¼Œåˆ™è¯¥æ•°å­—具有定点类型。 */ DecimalNumber: (DecimalDigits | (DecimalDigits? '.' DecimalDigits)) ([eE] '-'? DecimalDigits)?; //@doc:inline @@ -240,14 +239,14 @@ fragment DecimalDigits: [0-9] ('_'? [0-9])* ; /** - * This is needed to avoid successfully parsing a number followed by a string with no whitespace between. + * 需è¦è¿™æ ·åšæ˜¯ä¸ºäº†é¿å…æˆåŠŸè§£æžä¸€ä¸ªæ•°å­—åŽé¢çš„字符串,而字符串之间没有空白。 */ DecimalNumberFollowedByIdentifier: DecimalNumber Identifier; /** - * An identifier in solidity has to start with a letter, a dollar-sign or an underscore and - * may additionally contain numbers after the first symbol. + * solidity中的标识符必须以字æ¯ï¼Œç¾Žå…ƒç¬¦å·æˆ–下划线开头, + * 并且å¯ä»¥åœ¨ç¬¬ä¸€ä¸ªç¬¦å·ä¹‹åŽå†åŒ…å«æ•°å­—。 */ Identifier: IdentifierStart IdentifierPart*; //@doc:inline @@ -292,20 +291,20 @@ YulTrue: 'true'; YulHex: 'hex'; /** - * Builtin functions in the EVM Yul dialect. + * EVM Yul语言的内置函数。 */ 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; @@ -317,9 +316,8 @@ YulComma: ','; YulArrow: '->'; /** - * Yul identifiers consist of letters, dollar signs, underscores and numbers, but may not start with a number. - * In inline assembly there cannot be dots in user-defined identifiers. Instead see yulPath for expressions - * consisting of identifiers with dots. + * Yul标识符由字æ¯ï¼Œç¾Žå…ƒç¬¦å·ï¼Œä¸‹åˆ’线和数字组æˆï¼Œä½†ä¸èƒ½ä»¥æ•°å­—开头。 + * 在内è”程åºä¸­ï¼Œç”¨æˆ·å®šä¹‰çš„标识符中ä¸èƒ½æœ‰åœ†ç‚¹ã€‚相å,对于由带点的标识符组æˆçš„表达å¼ï¼Œè¯·å‚阅yulPath。 */ YulIdentifier: YulIdentifierStart YulIdentifierPart*; //@doc:inline @@ -327,17 +325,17 @@ fragment YulIdentifierStart: [a-zA-Z$_]; //@doc:inline fragment YulIdentifierPart: [a-zA-Z0-9$_]; /** - * Hex literals in Yul consist of a prefix and one or more hexadecimal digits. + * Yul中的å六进制字由一个å‰ç¼€å’Œä¸€ä¸ªæˆ–多个å六进制数字组æˆã€‚ */ YulHexNumber: '0' 'x' [0-9a-fA-F]+; /** - * Decimal literals in Yul may be zero or any sequence of decimal digits without leading zeroes. + * Yul中的å°æ•°å­—é¢é‡å¯ä»¥æ˜¯é›¶æˆ–任何ä¸å«å‰å¯¼é›¶çš„å°æ•°ä½åºåˆ—。 */ YulDecimalNumber: '0' | ([1-9] [0-9]*); /** - * String literals in Yul consist of one or more double-quoted or single-quoted strings - * that may contain escape sequences and printable characters except unescaped line breaks or - * unescaped double-quotes or single-quotes, respectively. + * Yul中的字符串字é¢é‡ç”±ä¸€ä¸ªæˆ–多个åŒå¼•å·æˆ–å•å¼•å·å­—符串组æˆï¼Œ + * 这些字符串å¯èƒ½åŒ…å«è½¬ä¹‰åºåˆ—å’Œå¯æ‰“å°å­—符 + * 未转义的æ¢è¡Œç¬¦æˆ–未转义的åŒå¼•å·æˆ–å•å¼•å·é™¤å¤–。 */ YulStringLiteral: '"' DoubleQuotedStringCharacter* '"' @@ -352,8 +350,8 @@ YulLINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN) ; mode PragmaMode; /** - * Pragma token. Can contain any kind of symbol except a semicolon. - * Note that currently the solidity parser only allows a subset of this. + * 编译指示令牌。å¯ä»¥åŒ…å«é™¤åˆ†å·ä»¥å¤–的任何类型的符å·ã€‚ + * 注æ„,目å‰solidity解æžå™¨åªå…许它的一个å­é›†ã€‚ */ //@doc:name pragma-token //@doc:no-diagram diff --git a/docs/grammar/SolidityParser.g4 b/docs/grammar/SolidityParser.g4 index 4a756029c2ef..47c6c559c6cf 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -1,13 +1,13 @@ /** - * Solidity is a statically typed, contract-oriented, high-level language for implementing smart contracts on the Ethereum platform. + * Solidity是一ç§é™æ€ç±»åž‹çš„,é¢å‘åˆçº¦çš„高级语言,用于在Ethereumå¹³å°ä¸Šå®žçŽ°æ™ºèƒ½åˆçº¦ã€‚ */ parser grammar SolidityParser; options { tokenVocab=SolidityLexer; } /** - * On top level, Solidity allows pragmas, import directives, and - * definitions of contracts, interfaces, libraries, structs, enums and constants. + * 在顶层,Solidityå…许pragmas,导入语å¥ï¼Œ + * 以åŠåˆçº¦ï¼ŒæŽ¥å£ï¼Œåº“,结构,枚举和常é‡çš„定义。 */ sourceUnit: ( pragmaDirective @@ -29,7 +29,7 @@ sourceUnit: ( pragmaDirective: Pragma PragmaToken+ PragmaSemicolon; /** - * Import directives import identifiers from different files. + * 导入指令 从ä¸åŒçš„文件中导入标识符。 */ importDirective: Import ( @@ -41,30 +41,30 @@ importDirective: //@doc:name aliases importAliases: symbol=identifier (As alias=identifier)?; /** - * Path of a file to be imported. + * è¦å¯¼å…¥çš„文件的路径。 */ path: NonEmptyStringLiteral; /** - * List of aliases for symbols to be imported. + * è¦å¯¼å…¥çš„符å·çš„别å列表。 */ symbolAliases: LBrace aliases+=importAliases (Comma aliases+=importAliases)* RBrace; /** - * Top-level definition of a contract. + * åˆçº¦çš„顶层定义。 */ contractDefinition: Abstract? Contract name=identifier inheritanceSpecifierList? LBrace contractBodyElement* RBrace; /** - * Top-level definition of an interface. + * 接å£çš„顶层定义。 */ interfaceDefinition: Interface name=identifier inheritanceSpecifierList? LBrace contractBodyElement* RBrace; /** - * Top-level definition of a library. + * 一个库åˆçº¦çš„顶层定义。 */ libraryDefinition: Library name=identifier LBrace contractBodyElement* RBrace; @@ -73,16 +73,16 @@ inheritanceSpecifierList: Is inheritanceSpecifiers+=inheritanceSpecifier (Comma inheritanceSpecifiers+=inheritanceSpecifier)*?; /** - * Inheritance specifier for contracts and interfaces. - * Can optionally supply base constructor arguments. + * åˆçº¦å’ŒæŽ¥å£çš„继承指定器。 + * å¯ä»¥æœ‰é€‰æ‹©åœ°æ供基本构造函数å‚数。 */ inheritanceSpecifier: name=identifierPath arguments=callArgumentList?; /** - * Declarations that can be used in contracts, interfaces and libraries. + * å¯ä»¥åœ¨åˆçº¦ï¼ŒæŽ¥å£å’Œåº“中使用的声明。 * - * Note that interfaces and libraries may not contain constructors, interfaces may not contain state variables - * and libraries may not contain fallback, receive functions nor non-constant state variables. + * 注æ„,接å£å’Œåº“ä¸èƒ½åŒ…å«æž„造函数,接å£ä¸èƒ½åŒ…å«çŠ¶æ€å˜é‡ï¼Œ + * 库ä¸èƒ½åŒ…å«fallback,receive函数和éžæ’定状æ€å˜é‡ã€‚ */ contractBodyElement: constructorDefinition @@ -100,34 +100,33 @@ contractBodyElement: //@doc:inline namedArgument: name=identifier Colon value=expression; /** - * Arguments when calling a function or a similar callable object. - * The arguments are either given as comma separated list or as map of named arguments. + * 调用一个函数或类似的å¯è°ƒç”¨å¯¹è±¡æ—¶çš„å‚数。 + * å‚æ•°è¦ä¹ˆä»¥é€—å·åˆ†éš”的列表形å¼ç»™å‡ºï¼Œè¦ä¹ˆä»¥å‘½åå‚数的映射形å¼ç»™å‡ºã€‚ */ callArgumentList: LParen ((expression (Comma expression)*)? | LBrace (namedArgument (Comma namedArgument)*)? RBrace) RParen; /** - * Qualified name. + * åˆæ ¼çš„å称。 */ identifierPath: identifier (Period identifier)*; /** - * Call to a modifier. If the modifier takes no arguments, the argument list can be skipped entirely - * (including opening and closing parentheses). + * 对一个修改器的调用。如果修改器ä¸éœ€è¦å‚数,å‚数列表å¯ä»¥å®Œå…¨è·³è¿‡ï¼ˆåŒ…括开头和结尾的括å·ï¼‰ã€‚ */ modifierInvocation: identifierPath callArgumentList?; /** - * Visibility for functions and function types. + * 函数和函数类型的å¯è§æ€§ã€‚ */ visibility: Internal | External | Private | Public; /** - * A list of parameters, such as function arguments or return values. + * 一个å‚数的列表,如函数å‚数或返回值。 */ parameterList: parameters+=parameterDeclaration (Comma parameters+=parameterDeclaration)*; //@doc:inline parameterDeclaration: type=typeName location=dataLocation? name=identifier?; /** - * Definition of a constructor. - * Must always supply an implementation. - * Note that specifying internal or public visibility is deprecated. + * 一个构造函数的定义。 + * 必须始终æ供一个实现。 + * 请注æ„,指定内部或公共å¯è§æ€§å·²è¢«åºŸå¼ƒã€‚ */ constructorDefinition locals[boolean payableSet = false, boolean visibilitySet = false] @@ -142,20 +141,26 @@ locals[boolean payableSet = false, boolean visibilitySet = false] body=block; /** - * State mutability for function types. - * The default mutability 'non-payable' is assumed if no mutability is specified. + * 函数类型的状æ€å¯å˜æ€§ã€‚ + * 如果没有指定å¯å˜æ€§ï¼Œåˆ™å‡å®šé»˜è®¤çš„å¯å˜æ€§ä¸º “éžpayable“。 */ stateMutability: Pure | View | Payable; /** - * An override specifier used for functions, modifiers or state variables. - * In cases where there are ambiguous declarations in several base contracts being overridden, - * a complete list of base contracts has to be given. + *一个用于函数,修改器或状æ€å˜é‡çš„é‡è½½æŒ‡å®šç¬¦ã€‚ + * 如果在被é‡è½½çš„几个基础åˆçº¦ä¸­å­˜åœ¨ä¸æ˜Žç¡®çš„声明, + * 必须给出一个完整的基础åˆçº¦æ¸…å•ã€‚ */ 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 */ functionDefinition locals[ @@ -178,9 +183,25 @@ locals[ (Semicolon | body=block); /** +<<<<<<< HEAD + * 自由函数的定义。 + */ + freeFunctionDefinition: + Function (identifier | Fallback | Receive) + LParen (arguments=parameterList)? RParen + stateMutability? + (Returns LParen returnParameters=parameterList RParen)? + (Semicolon | body=block); + +/** + * 修改器的定义。 + * 注æ„,在修改器的主体å—中,下划线ä¸èƒ½ä½œä¸ºæ ‡è¯†ç¬¦ä½¿ç”¨ï¼Œ + * 而是作为å ä½ç¬¦è¯­å¥ï¼Œç”¨äºŽä¿®æ”¹å™¨æ‰€åº”用的函数主体。 +======= * The definition of a modifier. * Note that within the body block of a modifier, the underscore cannot be used as identifier, * but is used as placeholder statement for the body of a function to which the modifier is applied. +>>>>>>> english/develop */ modifierDefinition locals[ @@ -197,7 +218,7 @@ locals[ (Semicolon | body=block); /** - * Definition of the special fallback function. + * 特殊的fallback函数的定义。 */ fallbackFunctionDefinition locals[ @@ -220,7 +241,7 @@ locals[ (Semicolon | body=block); /** - * Definition of the special receive function. + * 特殊的receive函数的定义。 */ receiveFunctionDefinition locals[ @@ -241,25 +262,25 @@ locals[ (Semicolon | body=block); /** - * Definition of a struct. Can occur at top-level within a source unit or within a contract, library or interface. + * 结构体的定义。å¯ä»¥å‡ºçŽ°åœ¨æºä»£ç å•å…ƒçš„顶层,也å¯ä»¥å‡ºçŽ°åœ¨åˆçº¦ï¼Œåº“或接å£ä¸­ã€‚ */ structDefinition: Struct name=identifier LBrace members=structMember+ RBrace; /** - * The declaration of a named struct member. + * 一个命å的结构体æˆå‘˜çš„声明。 */ structMember: type=typeName name=identifier Semicolon; /** - * Definition of an enum. Can occur at top-level within a source unit or within a contract, library or interface. + * 一个枚举的定义。å¯ä»¥å‡ºçŽ°åœ¨æºä»£ç å•å…ƒçš„顶层,也å¯ä»¥å‡ºçŽ°åœ¨åˆçº¦ï¼Œåº“或接å£ä¸­ã€‚ */ enumDefinition: Enum name=identifier LBrace enumValues+=identifier (Comma enumValues+=identifier)* RBrace; /** - * Definition of a user defined value type. Can occur at top-level within a source unit or within a contract, library or interface. + * 用户自定义的值类型的定义。å¯ä»¥å‡ºçŽ°åœ¨æºä»£ç å•å…ƒçš„顶层,也å¯ä»¥å‡ºçŽ°åœ¨åˆçº¦ï¼Œåº“或接å£ä¸­ã€‚ */ userDefinedValueTypeDefinition: Type name=identifier Is elementaryTypeName[true] Semicolon; /** - * The declaration of a state variable. + * 一个状æ€å˜é‡çš„声明。 */ stateVariableDeclaration locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean overrideSpecifierSet = false] @@ -278,7 +299,7 @@ locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean Semicolon; /** - * The declaration of a constant variable. + * 一个常é‡å˜é‡çš„声明。 */ constantVariableDeclaration : @@ -289,11 +310,11 @@ constantVariableDeclaration Semicolon; /** - * Parameter of an event. + * 一个事件类型的å‚数。 */ eventParameter: type=typeName Indexed? name=identifier?; /** - * Definition of an event. Can occur in contracts, libraries or interfaces. + * 一个事件类型的定义。å¯ä»¥å‘生在åˆçº¦ï¼Œåº“或接å£ä¸­ã€‚ */ eventDefinition: Event name=identifier @@ -302,11 +323,11 @@ eventDefinition: Semicolon; /** - * Parameter of an error. + * 一个错误类型的å‚数。 */ errorParameter: type=typeName name=identifier?; /** - * Definition of an error. + * 错误类型定义。 */ errorDefinition: Error name=identifier @@ -314,7 +335,7 @@ errorDefinition: Semicolon; /** - * Operators that users are allowed to implement for some types with `using for`. + * å…许用户使用 `using for` 为æŸäº›ç±»åž‹å®žçŽ°çš„è¿ç®—符。 */ userDefinableOperator: BitAnd @@ -334,13 +355,20 @@ userDefinableOperator: | NotEqual; /** - * Using directive to attach library functions and free functions to types. - * Can occur within contracts and libraries and at the file level. + * 使用指令将库函数和自由函数附加到类型上。 + * å¯ä»¥åœ¨åˆçº¦å’Œåº“中以åŠæ–‡ä»¶å±‚é¢ä¸­å‡ºçŽ°ã€‚ */ -usingDirective: Using (identifierPath | (LBrace 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)?; + /** - * A type name can be an elementary type, a function type, a mapping type, a user-defined type - * (e.g. a contract or struct) or an array type. + * 一个类型å称å¯ä»¥æ˜¯ä¸€ä¸ªåŸºæœ¬ç±»åž‹ï¼Œä¸€ä¸ªå‡½æ•°ç±»åž‹ï¼Œä¸€ä¸ªæ˜ å°„类型, + * 一个用户定义的类型(如åˆçº¦ç±»åž‹æˆ–结构体类型)或一个数组类型。 */ typeName: elementaryTypeName[true] | functionTypeName | mappingType | identifierPath | typeName LBrack expression? RBrack; elementaryTypeName[boolean allowAddressPayable]: Address | {$allowAddressPayable}? Address Payable | Bool | String | Bytes | SignedIntegerType | UnsignedIntegerType | FixedBytes | Fixed | Ufixed; @@ -355,17 +383,17 @@ locals [boolean visibilitySet = false, boolean mutabilitySet = false] (Returns LParen returnParameters=parameterList RParen)?; /** - * The declaration of a single variable. + * å•ä¸€å˜é‡çš„声明。 */ variableDeclaration: type=typeName location=dataLocation? name=identifier; dataLocation: Memory | Storage | Calldata; /** - * Complex expression. - * Can be an index access, an index range access, a member access, a function call (with optional function call options), - * a type conversion, an unary or binary expression, a comparison or assignment, a ternary expression, - * a new-expression (i.e. a contract creation or the allocation of a dynamic memory array), - * a tuple, an inline array or a primary expression (i.e. an identifier, literal or type name). + * å¤æ‚的表达å¼ã€‚ + * å¯ä»¥æ˜¯ä¸€ä¸ªç´¢å¼•è®¿é—®ï¼Œä¸€ä¸ªç´¢å¼•èŒƒå›´è®¿é—®ï¼Œä¸€ä¸ªæˆå‘˜è®¿é—®ï¼Œä¸€ä¸ªå‡½æ•°è°ƒç”¨ï¼ˆæœ‰å¯é€‰çš„函数调用选项), + * 一个类型转æ¢ï¼Œä¸€ä¸ªå•æ•°æˆ–åŒæ•°è¡¨è¾¾å¼ï¼Œä¸€ä¸ªæ¯”较或赋值,一个三元表达å¼ï¼Œ + * 一个新的表达å¼ï¼ˆå³ä¸€ä¸ªåˆçº¦çš„创建或动æ€å†…存数组的分é…), + * 一个元组,一个内è”数组或一个主è¦è¡¨è¾¾å¼ï¼ˆå³ä¸€ä¸ªæ ‡è¯†ç¬¦ï¼Œå­—é¢æ„æ€æˆ–类型å)。 */ expression: expression LBrack index=expression? RBrack # IndexAccess @@ -405,12 +433,12 @@ expression: assignOp: Assign | AssignBitOr | AssignBitXor | AssignBitAnd | AssignShl | AssignSar | AssignShr | AssignAdd | AssignSub | AssignMul | AssignDiv | AssignMod; tupleExpression: LParen (expression? ( Comma expression?)* ) RParen; /** - * An inline array expression denotes a statically sized array of the common type of the contained expressions. + * 内è”数组表达å¼è¡¨ç¤ºä¸€ä¸ªé™æ€å¤§å°çš„数组,它是所å«è¡¨è¾¾å¼çš„å…±åŒç±»åž‹ã€‚ */ inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack; /** - * Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers. + * 除了常规的éžå…³é”®å­—标识符,一些关键字如 ‘from‘ å’Œ ‘error‘ 也å¯ä»¥ä½œä¸ºæ ‡è¯†ç¬¦ã€‚ */ identifier: Identifier | From | Error | Revert | Global; @@ -420,25 +448,25 @@ literalWithSubDenomination: numberLiteral SubDenomination; booleanLiteral: True | False; /** - * A full string literal consists of either one or several consecutive quoted strings. + * 一个完整的字符串字é¢é‡ç”±ä¸€ä¸ªæˆ–几个连续的引å·å­—符串组æˆã€‚ */ stringLiteral: (NonEmptyStringLiteral | EmptyStringLiteral)+; /** - * A full hex string literal that consists of either one or several consecutive hex strings. + * 一个完整的å六进制字符串字é¢é‡ç”±ä¸€ä¸ªæˆ–几个连续的å六进制字符串组æˆã€‚ */ hexStringLiteral: HexString+; /** - * A full unicode string literal that consists of either one or several consecutive unicode strings. + * 一个完整的unicode字符串字é¢é‡ç”±ä¸€ä¸ªæˆ–几个连续的unicode字符串组æˆã€‚ */ unicodeStringLiteral: UnicodeStringLiteral+; /** - * Number literals can be decimal or hexadecimal numbers with an optional unit. + * æ•°å­—å­—é¢é‡å¯ä»¥æ˜¯å¸¦å¯é€‰å•ä½çš„å进制或å六进制数字。 */ numberLiteral: DecimalNumber | HexNumber; /** - * A curly-braced block of statements. Opens its own scope. + * 带花括å·çš„语å¥å—。å¯ä»¥æ‰“开自己的作用域。 */ block: LBrace ( statement | uncheckedBlock )* RBrace; @@ -464,59 +492,58 @@ statement: //@doc:inline simpleStatement: variableDeclarationStatement | expressionStatement; /** - * If statement with optional else part. + * 带有å¯é€‰çš„else部分的If语å¥ã€‚ */ ifStatement: If LParen expression RParen statement (Else statement)?; /** - * For statement with optional init, condition and post-loop part. + * 带有å¯é€‰çš„åˆå§‹å€¼ï¼Œå¾ªçŽ¯æ¡ä»¶å’Œå¾ªçŽ¯è¯­å¥éƒ¨åˆ†çš„For语å¥ã€‚ */ forStatement: For LParen (simpleStatement | Semicolon) (expressionStatement | Semicolon) expression? RParen statement; whileStatement: While LParen expression RParen statement; doWhileStatement: Do statement While LParen expression RParen Semicolon; /** - * A continue statement. Only allowed inside for, while or do-while loops. + * 一个continue语å¥ã€‚åªå…许在forã€while或do-while循环中使用。 */ continueStatement: Continue Semicolon; /** - * A break statement. Only allowed inside for, while or do-while loops. + * 一个break语å¥ã€‚åªå…许在for,while或do-while循环中使用。 */ breakStatement: Break Semicolon; /** - * A try statement. The contained expression needs to be an external function call or a contract creation. + * 一个try语å¥ã€‚包å«çš„表达å¼éœ€è¦æ˜¯ä¸€ä¸ªå¤–部函数调用或åˆçº¦åˆ›å»ºã€‚ */ tryStatement: Try expression (Returns LParen returnParameters=parameterList RParen)? block catchClause+; /** - * The catch clause of a try statement. + * Try语å¥çš„catchå­å¥ã€‚ */ catchClause: Catch (identifier? LParen (arguments=parameterList) RParen)? block; returnStatement: Return expression? Semicolon; /** - * An emit statement. The contained expression needs to refer to an event. + * 一个å‘射语å¥ã€‚包å«çš„表达å¼éœ€è¦å¼•ç”¨ä¸€ä¸ªäº‹ä»¶ã€‚ */ emitStatement: Emit expression callArgumentList Semicolon; /** - * A revert statement. The contained expression needs to refer to an error. + * 一个æ¢å¤è¯­å¥ã€‚包å«çš„表达å¼éœ€è¦æŒ‡å‘一个错误。 */ revertStatement: Revert expression callArgumentList Semicolon; /** - * An inline assembly block. - * The contents of an inline assembly block use a separate scanner/lexer, i.e. the set of keywords and - * allowed identifiers is different inside an inline assembly block. + * 一个内è”汇编代ç å—。 + * 内è”汇编å—的内容使用一个å•ç‹¬çš„扫æ器/读å–器,也就是说,内è”汇编å—内的关键字和å…许的标识符集是ä¸åŒçš„。 */ assemblyStatement: Assembly AssemblyDialect? assemblyFlags? AssemblyLBrace yulStatement* YulRBrace; /** - * Assembly flags. - * Comma-separated list of double-quoted strings as flags. + * 内è”标志。 + * 逗å·åˆ†éš”çš„åŒå¼•å·å­—符串列表作为标志。 */ assemblyFlags: AssemblyBlockLParen AssemblyFlagString (AssemblyBlockComma AssemblyFlagString)* AssemblyBlockRParen; //@doc:inline variableDeclarationList: variableDeclarations+=variableDeclaration (Comma variableDeclarations+=variableDeclaration)*; /** - * A tuple of variable names to be used in variable declarations. - * May contain empty fields. + * 在å˜é‡å£°æ˜Žä¸­ä½¿ç”¨çš„å˜é‡å元组。 + * å¯èƒ½åŒ…å«ç©ºå­—段。 */ variableDeclarationTuple: LParen @@ -524,23 +551,22 @@ variableDeclarationTuple: (Comma (variableDeclarations+=variableDeclaration)?)* RParen; /** - * A variable declaration statement. - * A single variable may be declared without initial value, whereas a tuple of variables can only be - * declared with initial value. + * 一个å˜é‡çš„声明语å¥ã€‚ + * å•ä¸ªå˜é‡å¯ä»¥ä¸å¸¦åˆå§‹å€¼å£°æ˜Žï¼Œè€Œå˜é‡çš„元组åªèƒ½ç”¨åˆå§‹å€¼å£°æ˜Žã€‚ */ variableDeclarationStatement: ((variableDeclaration (Assign expression)?) | (variableDeclarationTuple Assign expression)) Semicolon; expressionStatement: expression Semicolon; mappingType: Mapping LParen key=mappingKeyType name=identifier? DoubleArrow value=typeName name=identifier? RParen; /** - * Only elementary types or user defined types are viable as mapping keys. + * åªæœ‰åŸºæœ¬ç±»åž‹æˆ–用户定义的类型å¯ä»¥ä½œä¸ºæ˜ å°„类型的键值。 */ mappingKeyType: elementaryTypeName[false] | identifierPath; /** - * A Yul statement within an inline assembly block. - * continue and break statements are only valid within for loops. - * leave statements are only valid within function bodies. + * 内è”汇编å—中的Yul语å¥ã€‚ + * continue å’Œ break 语å¥åªåœ¨for循环中有效。 + * 离开语å¥åªåœ¨å‡½æ•°ä½“内有效。 */ yulStatement: yulBlock @@ -558,16 +584,16 @@ yulStatement: yulBlock: YulLBrace yulStatement* YulRBrace; /** - * The declaration of one or more Yul variables with optional initial value. - * If multiple variables are declared, only a function call is a valid initial value. + * 声明一个或多个具有å¯é€‰çš„åˆå§‹å€¼çš„Yulå˜é‡ã€‚ + * 如果声明了多个å˜é‡ï¼Œåªæœ‰ä¸€ä¸ªå‡½æ•°è°ƒç”¨æ˜¯æœ‰æ•ˆçš„åˆå§‹å€¼ã€‚ */ yulVariableDeclaration: (YulLet variables+=YulIdentifier (YulAssign yulExpression)?) | (YulLet variables+=YulIdentifier (YulComma variables+=YulIdentifier)* (YulAssign yulFunctionCall)?); /** - * Any expression can be assigned to a single Yul variable, whereas - * multi-assignments require a function call on the right-hand side. + * 任何表达å¼éƒ½å¯ä»¥åˆ†é…给一个Yulå˜é‡ï¼Œ + * 而多分é…则需è¦åœ¨å³ä¾§è°ƒç”¨ä¸€ä¸ªå‡½æ•°ã€‚ */ yulAssignment: yulPath YulAssign yulExpression | (yulPath (YulComma yulPath)+) YulAssign yulFunctionCall; @@ -578,8 +604,8 @@ yulForStatement: YulFor init=yulBlock cond=yulExpression post=yulBlock body=yulB //@doc:inline yulSwitchCase: YulCase yulLiteral yulBlock; /** - * A Yul switch statement can consist of only a default-case (deprecated) or - * one or more non-default cases optionally followed by a default-case. + * Yul switch语å¥å¯ä»¥åªåŒ…括一个默认情况(已废弃) + * 或一个或多个éžé»˜è®¤æƒ…况,å¯é€‰æ‹©ç´§è·Ÿä¸€ä¸ªé»˜è®¤æƒ…况。 */ yulSwitchStatement: YulSwitch yulExpression @@ -595,13 +621,12 @@ yulFunctionDefinition: body=yulBlock; /** - * While only identifiers without dots can be declared within inline assembly, - * paths containing dots can refer to declarations outside the inline assembly block. + * 虽然åªæœ‰ä¸å¸¦ç‚¹çš„标识符å¯ä»¥åœ¨å†…è”汇编中声明, + * 但å«æœ‰ç‚¹çš„路径å¯ä»¥æŒ‡å†…è”汇编å—之外的声明。 */ yulPath: YulIdentifier (YulPeriod (YulIdentifier | YulEVMBuiltin))*; /** - * A call to a function with return values can only occur as right-hand side of an assignment or - * a variable declaration. + * 对带有返回值的函数的调用åªèƒ½ä½œä¸ºèµ‹å€¼æˆ–å˜é‡å£°æ˜Žçš„å³ä¾§å‡ºçŽ°ã€‚ */ yulFunctionCall: (YulIdentifier | YulEVMBuiltin) YulLParen (yulExpression (YulComma yulExpression)*)? YulRParen; yulBoolean: YulTrue | YulFalse; diff --git a/docs/index.rst b/docs/index.rst index 600173d65452..47878df3cb44 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,118 +1,132 @@ Solidity ======== -Solidity is an object-oriented, high-level language for implementing smart contracts. -Smart contracts are programs that govern the behavior of accounts within the Ethereum state. +.. warning:: + + You are reading a community translation of the Solidity documentation. The Solidity team + can give no guarantees on the quality and accuracy of the translations provided. + The English reference version is and will remain the only officially supported version + by the Solidity team and will always be the most accurate and most up-to-date one. + When in doubt, please always refer to the `English (original) documentation `_. + +Solidity是一门为实现智能åˆçº¦è€Œåˆ›å»ºçš„é¢å‘对象的高级编程语言。 +智能åˆçº¦æ˜¯ç®¡ç†ä»¥å¤ªåŠä¸­è´¦æˆ·è¡Œä¸ºçš„程åºã€‚ -Solidity is a `curly-bracket language `_ designed to target the Ethereum Virtual Machine (EVM). -It is influenced by C++, Python, and JavaScript. -You can find more details about which languages Solidity has been inspired by in the :doc:`language influences ` section. +Solidity 是一ç§é¢å‘以太åŠè™šæ‹Ÿæœº (EVM) çš„ `带花括å·çš„语言 `_。 +å®ƒå— C++,Python, å’Œ JavaScript çš„å½±å“。 +您å¯ä»¥åœ¨ :doc:`语言的影å“å› ç´  ` 部分中找到更多有关 Solidity å—哪些语言å¯å‘的细节。 -Solidity is statically typed, supports inheritance, libraries, and complex user-defined types, among other features. +Solidity 是é™æ€ç±»åž‹è¯­è¨€ï¼Œæ”¯æŒç»§æ‰¿ï¼Œåº“å’Œå¤æ‚的用户自定义的类型以åŠå…¶ä»–特性。 -With Solidity, you can create contracts for uses such as voting, crowdfunding, blind auctions, and multi-signature wallets. +使用 Solidity,您å¯ä»¥åˆ›å»ºç”¨äºŽæŠ•ç¥¨ã€ä¼—ç­¹ã€ç§˜å¯†ç«žä»·ï¼ˆç›²æ‹ï¼‰ä»¥åŠå¤šé‡ç­¾å钱包等用途的åˆçº¦ã€‚ -When deploying contracts, you should use the latest released version of Solidity. -Apart from exceptional cases, only the latest version receives -`security fixes `_. -Furthermore, breaking changes, as well as new features, are introduced regularly. -We currently use a 0.y.z version number `to indicate this fast pace of change `_. +当开å‘智能åˆçº¦æ—¶ï¼Œæ‚¨åº”该使用最新版本的 Solidity。 +除æŸäº›ç‰¹æ®Šæƒ…况之外,åªæœ‰æœ€æ–°ç‰ˆæœ¬æ‰ä¼šæ”¶åˆ° +`å®‰å…¨ä¿®å¤ `_。 +此外,çªç ´æ€§çš„å˜åŒ–以åŠæ–°åŠŸèƒ½ä¼šå®šæœŸå¼•å…¥ã€‚ +ç›®å‰ï¼Œæˆ‘们使用 0.y.z ç‰ˆæœ¬å· `æ¥è¡¨æ˜Žè¿™ç§å¿«é€Ÿçš„å˜åŒ– `_。 .. warning:: - Solidity recently released the 0.8.x version that introduced a lot of breaking changes. - Make sure you read :doc:`the full list <080-breaking-changes>`. + Solidity 最近å‘布了 0.8.x 版本,该版本引入了许多é‡å¤§æ›´æ–°ã€‚ + 请务必阅读 :doc:`完整列表 <080-breaking-changes>`。 -Ideas for improving Solidity or this documentation are always welcome, -read our :doc:`contributors guide ` for more details. +始终欢迎改进 Solidity 或此文档的想法, +请阅读我们的 :doc:`è´¡çŒ®è€…æŒ‡å— ` 以了解更多细节。 .. Hint:: - You can download this documentation as PDF, HTML or Epub - by clicking on the versions flyout menu in the bottom-left corner and selecting the preferred download format. + 您å¯ä»¥é€šè¿‡ç‚¹å‡»å·¦ä¸‹è§’的版本å·å¼¹å‡ºçš„èœå•æ¥é€‰æ‹©é¦–é€‰çš„ä¸‹è½½æ ¼å¼ + æ¥ä¸‹è½½è¯¥æ–‡æ¡£çš„ PDF,HTML 或 Epub æ ¼å¼ã€‚ -Getting Started +å…¥é—¨æŒ‡å— --------------- -**1. Understand the Smart Contract Basics** +**1. 了解智能åˆçº¦åŸºç¡€çŸ¥è¯†** -If you are new to the concept of smart contracts, we recommend you to get started by digging into the "Introduction to Smart Contracts" section, which covers the following: +如果您是智能åˆçº¦æ¦‚念的新手,我们建议您从深入了解 “智能åˆçº¦ä»‹ç»â€ 部分开始,包括以下内容: -* :ref:`A simple example smart contract ` written in Solidity. -* :ref:`Blockchain Basics `. -* :ref:`The Ethereum Virtual Machine `. +* 用 Solidity 编写的 :ref:`一个简å•çš„智能åˆçº¦ä¾‹å­ `。 +* :ref:`区å—链基础知识 `. +* :ref:`以太åŠè™šæ‹Ÿæœº `. -**2. Get to Know Solidity** +**2. 了解 Solidity** -Once you are accustomed to the basics, we recommend you read the :doc:`"Solidity by Example" ` -and “Language Description†sections to understand the core concepts of the language. +一旦您熟悉了基础知识,我们建议您阅读 :doc:`"Solidity 示例" ` +å’Œ “语言æ述†部分,以了解该语言的核心概念。 -**3. Install the Solidity Compiler** +**3.安装 Solidity 编译器** -There are various ways to install the Solidity compiler, -simply choose your preferred option and follow the steps outlined on the :ref:`installation page `. +有多ç§æ–¹æ³•å¯ä»¥å®‰è£… Solidity 编译器, +åªéœ€é€‰æ‹©æ‚¨å–œæ¬¢çš„选项,并按照 :ref:`å®‰è£…é¡µé¢ ` 上æ供的步骤æ“作å³å¯ã€‚ .. hint:: - You can try out code examples directly in your browser with the - `Remix IDE `_. - Remix is a web browser-based IDE that allows you to write, deploy and administer Solidity smart contracts, - without the need to install Solidity locally. + 您å¯ä»¥é€šè¿‡ `Remix IDE `_ + 在æµè§ˆå™¨ä¸­ç›´æŽ¥å°è¯•ä»£ç ç¤ºä¾‹ã€‚ + Remix 是一个基于网络æµè§ˆå™¨çš„IDE,å…许您编写,部署和管ç†Solidity智能åˆçº¦ï¼Œ + 无需在本地安装 Solidity。 .. warning:: - As humans write software, it can have bugs. - Therefore, you should follow established software development best practices when writing your smart contracts. - This includes code review, testing, audits, and correctness proofs. - Smart contract users are sometimes more confident with code than their authors, - and blockchains and smart contracts have their own unique issues to watch out for, - so before working on production code, make sure you read the :ref:`security_considerations` section. - -**4. Learn More** - -If you want to learn more about building decentralized applications on Ethereum, -the `Ethereum Developer Resources `_ can help you with further general documentation around Ethereum, -and a wide selection of tutorials, tools, and development frameworks. - + 由于人类编写的软件å¯èƒ½ä¼šå­˜åœ¨é”™è¯¯ï¼Œ + 因此在编写智能åˆçº¦æ—¶åº”éµå¾ªè½¯ä»¶å¼€å‘的最佳实践。 + 这包括代ç å®¡æŸ¥ï¼Œæµ‹è¯•ï¼Œå®¡è®¡å’Œæ­£ç¡®æ€§è¯æ˜Žã€‚ + 智能åˆçº¦ç”¨æˆ·æœ‰æ—¶å¯¹ä»£ç çš„信心甚至超过了作者, + 区å—链和智能åˆçº¦ä¹Ÿæœ‰å…¶ç‹¬ç‰¹çš„问题需è¦æ³¨æ„, + 因此在开始编写生产代ç ä¹‹å‰ï¼Œè¯·ç¡®ä¿æ‚¨å·²é˜…读 + :ref:`security_considerations` 部分。 + +**4. 了解更多** + +如果您想更深入了解如何在以太åŠä¸Šæž„建去中心化应用, +`以太åŠå¼€å‘è€…èµ„æº `_ å¯ä»¥ä¸ºæ‚¨æ供有关以太åŠçš„更多文档, +以åŠå„ç§æ•™ç¨‹ã€å·¥å…·å’Œå¼€å‘框架。 + +<<<<<<< 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: -Translations +翻译 ------------ -Community contributors help translate this documentation into several languages. -Note that they have varying degrees of completeness and up-to-dateness. -The English version stands as a reference. +社区贡献者帮助将本文档翻译æˆå¤šç§è¯­è¨€ã€‚ +请注æ„,这些翻译的完整度和åŠæ—¶æ€§å„ä¸ç›¸åŒã€‚ +因此英文版æ‰æ˜¯å‚考的标准。 -You can switch between languages by clicking on the flyout menu in the bottom-left corner -and selecting the preferred language. +您å¯ä»¥é€šè¿‡ç‚¹å‡»å·¦ä¸‹è§’的语言切æ¢å™¨æ¥åˆ‡æ¢è¯­è¨€ã€‚ +在弹出的èœå•ä¸­ï¼Œé€‰æ‹©æ‚¨éœ€è¦çš„语言å³å¯åˆ‡æ¢ã€‚ -* `Chinese `_ -* `French `_ -* `Indonesian `_ -* `Japanese `_ -* `Korean `_ -* `Persian `_ -* `Russian `_ -* `Spanish `_ -* `Turkish `_ +* `简体中文 `_ +* `法语 `_ +* `å°åº¦å°¼è¥¿äºšè¯­ `_ +* `日语 `_ +* `韩语 `_ +* `波斯语 `_ +* `俄语 `_ +* `西ç­ç‰™è¯­ `_ +* `土耳其语 `_ .. note:: - We set up a GitHub organization and translation workflow to help streamline the community efforts. - Please refer to the translation guide in the `solidity-docs org `_ - for information on how to start a new language or contribute to the community translations. + 我们建立了一个 GitHub 组织和翻译工作æµç¨‹ï¼Œä»¥å¸®åŠ©ç®€åŒ–社区的工作。 + 请å‚考 `solidity-文档 组织 `_ 中的翻译指å—, + 了解如何开å¯æ–°çš„语言翻译或为社区翻译åšå‡ºè´¡çŒ®ã€‚ -Contents +目录 ======== -:ref:`Keyword Index `, :ref:`Search Page ` +:ref:`关键字索引 `, :ref:`æœç´¢é¡µé¢ ` .. toctree:: :maxdepth: 2 - :caption: Basics + :caption: 基础知识 introduction-to-smart-contracts.rst solidity-by-example.rst @@ -120,7 +134,7 @@ Contents .. toctree:: :maxdepth: 2 - :caption: Language Description + :caption: 语言æè¿° layout-of-source-files.rst structure-of-a-contract.rst @@ -134,7 +148,7 @@ Contents .. toctree:: :maxdepth: 2 - :caption: Compiler + :caption: 编译器 using-the-compiler.rst analysing-compilation-output.rst @@ -142,7 +156,7 @@ Contents .. toctree:: :maxdepth: 2 - :caption: Internals + :caption: 内部说明 internals/layout_in_storage.rst internals/layout_in_memory.rst @@ -155,7 +169,7 @@ Contents .. toctree:: :maxdepth: 2 - :caption: Advisory content + :caption: 建议内容 security-considerations.rst bugs.rst @@ -166,7 +180,7 @@ Contents .. toctree:: :maxdepth: 2 - :caption: Additional Material + :caption: 补充ææ–™ natspec-format.rst smtchecker.rst @@ -175,7 +189,7 @@ Contents .. toctree:: :maxdepth: 2 - :caption: Resources + :caption: èµ„æº style-guide.rst common-patterns.rst diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index abafd0ad3810..9e345e9e990b 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -3,12 +3,24 @@ .. _installing-solidity: ################################ -Installing the Solidity Compiler +安装 Solidity 编译器 ################################ -Versioning +版本 ========== +<<<<<<< HEAD +Solidity 的版本éµå¾ª `语义化版本原则 `_。此外, +主版本(例如:0.x.y)的补ä¸çº§ç‰ˆæœ¬çš„å‘布ä¸ä¼šåŒ…å«é‡å¤§æ›´æ”¹ã€‚è¿™æ„味ç€ç”¨ 0.x.y 版本 +编译的代ç å¯æœ›ç”¨ 0.x.z 版本编译,其中 z > y。 + +除了å‘行版本外,我们还æä¾› **æ¯æ—¥å¼€å‘构建版本 (nightly development builds)** , +目的是使开å‘人员能够轻æ¾åœ°è¯•ç”¨å³å°†æŽ¨å‡ºçš„功能并æ供早期å馈。然而,请注æ„, +虽然æ¯æ—¥å¼€å‘构建版本通常是很稳定的,但它们包å«äº†æ¥è‡ªå¼€å‘分支的å‰æ²¿ä»£ç ï¼Œ +并ä¸ä¿è¯æ€»æ˜¯æœ‰æ•ˆçš„。尽管我们尽了最大努力, +它们ä»å¯èƒ½å«æœ‰æœªè®°å½•çš„或é‡å¤§çš„修改,这些修改ä¸ä¼šæˆä¸ºå®žé™…å‘布版本的一部分。 +它们也ä¸ä¼šç”¨äºŽç”Ÿäº§ã€‚ +======= 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 @@ -21,16 +33,27 @@ 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 -When deploying contracts, you should use the latest released version of Solidity. This -is because breaking changes, as well as new features and bug fixes are introduced regularly. -We currently use a 0.x version number `to indicate this fast pace of change `_. +当开å‘智能åˆçº¦æ—¶ï¼Œæ‚¨åº”该使用最新版本的 Solidity。这是因为é‡å¤§çš„改å˜ï¼Œ +以åŠæ–°çš„特性和错误修å¤æ˜¯å®šæœŸå¼•å…¥çš„。 +我们目å‰ä½¿ç”¨ 0.x ç‰ˆæœ¬å· `æ¥è¡¨ç¤ºè¿™ç§å¿«é€Ÿçš„å˜åŒ–çš„ `_。 Remix ===== -*We recommend Remix for small contracts and for quickly learning Solidity.* +*我们推è使用 Remix æ¥å¼€å‘简å•åˆçº¦å’Œå¿«é€Ÿå­¦ä¹  Solidity。* +<<<<<<< HEAD +`Remix å¯ä»¥åœ¨çº¿ä½¿ç”¨ `_,而无需安装任何东西。 +如果您想离线使用,å¯æŒ‰ https://github.com/ethereum/remix-live/tree/gh-pages +的页é¢è¯´æ˜Žä¸‹è½½ ``.zip`` 文件æ¥ä½¿ç”¨ã€‚ Remix 也是一个方便的选择, +å¯ä»¥åœ¨ä¸å®‰è£…多个 Solidity 版本的情况下测试æ¯æ—¥å¼€å‘构建版本。 + +本页的进一步选项详细说明了在您的计算机上安装 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. @@ -40,23 +63,29 @@ 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: npm / Node.js ============= -Use ``npm`` for a convenient and portable way to install ``solcjs``, a Solidity compiler. The -`solcjs` program has fewer features than the ways to access the compiler described -further down this page. The -:ref:`commandline-compiler` documentation assumes you are using -the full-featured compiler, ``solc``. The usage of ``solcjs`` is documented inside its own -`repository `_. +使用 ``npm`` å¯ä»¥ä¾¿æ·åœ°å®‰è£… ``solcjs`` ,它一个 Solidity 编译器。 +但该 `solcjs` 程åºçš„功能比本页下é¢æ述的访问编译器的方法è¦å°‘。 +在 :ref:`commandline-compiler` 一章中,我们å‡å®šæ‚¨ä½¿ç”¨çš„是全功能的编译器: ``solc``。 +``solcjs`` 的用法在它自己的 `代ç ä»“库 `_ 中记录。 + +注æ„: `solc-js` 项目是通过使用 Emscripten 从 C++ 版的 `solc` è¡ç”Ÿå‡ºæ¥çš„, +è¿™æ„味ç€ä¸¤è€…使用相åŒçš„编译器æºä»£ç ã€‚ +因此, `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 @@ -64,55 +93,91 @@ Please refer to the solc-js repository for instructions. .. 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. +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 -For example, You can specify release build versions in the tag for the 0.5.4 release. +<<<<<<< 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. +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 docker run ethereum/solc:stable --standard-json < input.json > output.json -Linux Packages +Linux 包 ============== -Binary packages of Solidity are available at -`solidity/releases `_. +Solidity 的二进制安装包å¯åœ¨ `solidity/releases `_ 找到。 -We also have PPAs for Ubuntu, you can get the latest stable -version using the following commands: +对于 Ubuntu ,我们也æä¾› PPAs 。通过以下命令,å¯èŽ·å–最新的稳定版本: .. code-block:: bash @@ -120,7 +185,7 @@ version using the following commands: sudo apt-get update sudo apt-get install solc -The nightly version can be installed using these commands: +您也å¯ä»¥ä½¿ç”¨ä»¥ä¸‹å‘½ä»¤å®‰è£…æ¯æ—¥å¼€å‘构建版本: .. code-block:: bash @@ -129,27 +194,33 @@ The nightly version can be installed using these commands: sudo apt-get update sudo apt-get install solc +<<<<<<< HEAD +此外,一些 Linux å‘行版æ供了他们自己的软件包。这些软件包ä¸æ˜¯ç”±æˆ‘们直接维护的, +而通常由å„自的软件包维护者ä¿æŒæœ€æ–°ã€‚ + +例如,Arch Linux 也有最新开å‘版本的软件包。 +======= Furthermore, some Linux distributions provide their own packages. These packages are not directly maintained by us but usually kept up-to-date by the respective package maintainers. For example, Arch Linux has packages for the latest development version as AUR packages: `solidity `_ and `solidity-bin `_. +>>>>>>> english/develop .. note:: Please be aware that `AUR `_ packages are user-produced content and unofficial packages. Exercise caution when using them. -There is also a `snap package `_, however, it is **currently unmaintained**. -It is installable in all the `supported Linux distros `_. To -install the latest stable version of solc: +还有一个 `snap包 `_,然而,它 **ç›®å‰æ²¡æœ‰ç»´æŠ¤** 。 +它å¯ä»¥å®‰è£…在所有 `支æŒçš„Linuxå‘行版 `_ 。通过以下命令, +安装最新的稳定版本的 solc: .. code-block:: bash sudo snap install solc -If you want to help testing the latest development version of Solidity -with the most recent changes, please use the following: +如果您想测试 develop 分支下的最新å˜æ›´ï¼Œè¯·ä½¿ç”¨ä»¥ä¸‹æ–¹å¼ï¼š .. code-block:: bash @@ -157,17 +228,14 @@ with the most recent changes, please use the following: .. note:: - The ``solc`` snap uses strict confinement. This is the most secure mode for snap packages - but it comes with limitations, like accessing only the files in your ``/home`` and ``/media`` directories. - For more information, go to `Demystifying Snap Confinement `_. - + ``solc`` snap 使用严格的é™åˆ¶ã€‚这对 snap 包æ¥è¯´æ˜¯æœ€å®‰å…¨çš„æ¨¡å¼ + 但它也有一些é™åˆ¶ï¼Œæ¯”如åªèƒ½è®¿é—® ``/home`` å’Œ ``/media`` 目录下的文件。 + 欲了解更多信æ¯ï¼Œè¯·è®¿é—® `Demystifying Snap Confinement `_。 macOS Packages ============== -We distribute the Solidity compiler through Homebrew -as a build-from-source version. Pre-built bottles are -currently not supported. +我们通过 Homebrew 作为从æºå¤´å»ºç«‹çš„版本, å‘布 Solidity 编译器,。目å‰ä¸æ”¯æŒé¢„构建。 .. code-block:: bash @@ -176,16 +244,20 @@ currently not supported. brew tap ethereum/ethereum brew install solidity -To install the most recent 0.4.x / 0.5.x version of Solidity you can also use ``brew install solidity@4`` -and ``brew install solidity@5``, respectively. +è¦å®‰è£…最新的 0.4.x/0.5.x 版本的 Solidity,您也å¯ä»¥åˆ†åˆ«ä½¿ç”¨ ``brew install solidity@4`` +å’Œ ``brew install solidity@5``。 -If you need a specific version of Solidity you can install a -Homebrew formula directly from Github. +如果您需è¦ç‰¹å®šç‰ˆæœ¬çš„ Solidity,您å¯ä»¥ç›´æŽ¥ä»Ž Github 上安装一个 Homebrew 列表。 +<<<<<<< HEAD +å‚è§ +`solidity.rb 在 Github 上的æ交情况 `_. +======= View -`solidity.rb commits on Github `_. +`solidity.rb commits on GitHub `_. +>>>>>>> english/develop -Copy the commit hash of the version you want and check it out on your machine. +å¤åˆ¶æ‚¨æƒ³è¦çš„版本的æ交哈希值,然åŽåœ¨æ‚¨çš„机器上检出该分支。 .. code-block:: bash @@ -193,23 +265,44 @@ Copy the commit hash of the version you want and check it out on your machine. cd homebrew-ethereum git checkout -Install it using ``brew``: +使用 ``brew`` 安装: .. code-block:: bash brew unlink solidity - # eg. Install 0.4.8 + # 例如,安装 0.4.8 brew install solidity.rb -Static Binaries +é™æ€äºŒè¿›åˆ¶æ–‡ä»¶ =============== -We maintain a repository containing static builds of past and current compiler versions for all -supported platforms at `solc-bin`_. This is also the location where you can find the nightly builds. - -The repository is not only a quick and easy way for end users to get binaries ready to be used -out-of-the-box but it is also meant to be friendly to third-party tools: - +我们在 `solc-bin`_ 上维护了一个包å«è¿‡åŽ»å’ŒçŽ°åœ¨ç¼–译器版本的é™æ€æž„建的资æºåº“,用于所有支æŒçš„å¹³å°ã€‚ +您也å¯ä»¥æ‰¾åˆ°æ¯æ—¥å¼€å‘构建版本。 + +该资æºåº“ä¸ä»…是一个快速且简å•çš„方法,让终端用户获得å¯ä»¥å¼€ç®±å³ç”¨çš„二进制文件, +而且它对第三方工具也很å‹å¥½ï¼š + +<<<<<<< HEAD +- 这些内容被镜åƒåˆ° https://binaries.soliditylang.org,在那里å¯ä»¥å¾ˆå®¹æ˜“地通过 HTTPS 下载, + 没有任何认è¯ã€é€ŸçŽ‡æˆ–需è¦ä½¿ç”¨gitçš„é™åˆ¶ã€‚ +- æ供的内容具有正确的 `Content-Type` 请求头和宽æ¾çš„ CORS é…置, + 因此它å¯ä»¥è¢«è¿è¡Œåœ¨æµè§ˆå™¨ä¸­çš„工具直接加载。 +- 二进制文件ä¸éœ€è¦å®‰è£…或解包(与必è¦çš„ DLLs æ†ç»‘在一起的旧版 Windows 除外)。 +- 我们努力争å–高水平的å‘åŽå…¼å®¹æ€§ã€‚文件一旦被添加,在没有æ供旧ä½ç½®çš„链接/é‡å®šå‘的情况下,ä¸ä¼šè¢«åˆ é™¤æˆ–移动。 + 它们也ä¸ä¼šè¢«ä¿®æ”¹ï¼Œè€Œä¸”应始终与原始校验相匹é…。唯一的例外是破æŸæˆ–无法使用的文件, + 如果ä¿æŒåŽŸæ ·ï¼Œæœ‰å¯èƒ½é€ æˆæ›´å¤§çš„伤害。 +- 文件是通过 HTTP å’Œ HTTPS æ供的。åªè¦æ‚¨ä»¥å®‰å…¨çš„æ–¹å¼èŽ·å¾—文件列表 + (通过 gitã€HTTPSã€IPFS 或者åªæ˜¯åœ¨æœ¬åœ°çš„缓存),并在下载åŽéªŒè¯äºŒè¿›åˆ¶æ–‡ä»¶çš„哈希值, + 您就ä¸å¿…通过HTTPS获得二进制文件。 + +在大多数情况下,åŒæ ·çš„二进制文件å¯ä»¥åœ¨ `Github 上的 Solidity å‘布页 `_ 中找到。 +ä¸åŒçš„是,我们一般ä¸æ›´æ–°Githubå·²å‘布的旧版本。这æ„味ç€å¦‚果命å规则改å˜ï¼Œæˆ‘们ä¸ä¼šé‡æ–°å‘½å, +也ä¸ä¼šä¸ºå‘布时ä¸æ”¯æŒçš„å¹³å°æ·»åŠ æž„建。这åªå‘生在 ``solc-bin`` 资æºåº“里。 + +``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 @@ -224,14 +317,15 @@ out-of-the-box but it is also meant to be friendly to third-party tools: (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 +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 @@ -248,10 +342,24 @@ Each one includes a ``list.json`` file listing the available binaries. For examp ] } -This means that: +è¿™æ„味ç€ï¼š -- You can find the binary in the same directory under the name +- 您å¯ä»¥åœ¨åŒä¸€ç›®å½•ä¸‹æ‰¾åˆ°äºŒè¿›åˆ¶æ–‡ä»¶ï¼Œå称为 `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 é‡å®šå‘。 +- 该文件也å¯åœ¨ IPFS上 找到,地å€æ˜¯ `QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS`_. +- 该文件将æ¥å¯èƒ½ä¼šå­˜å‚¨åœ¨ Swarm 上, + 地å€æ˜¯ `16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1`_. +- 您å¯ä»¥é€šè¿‡æ¯”较其keccak256哈希值æ¥éªŒè¯äºŒè¿›åˆ¶æ–‡ä»¶çš„完整性 + ``0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3``。哈希值å¯ä»¥åœ¨å‘½ä»¤è¡Œä¸Š + 使用 `sha3sum`_ æ供的 ``keccak256sum`` 工具 + 或在 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. @@ -265,43 +373,38 @@ This means that: from ethereumjs-util`_ in JavaScript. - You can also verify the integrity of the binary by comparing its sha256 hash to ``0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2``. +>>>>>>> english/develop .. warning:: - Due to the strong backwards compatibility requirement the repository contains some legacy elements - but you should avoid using them when writing new tools: - - - Use ``emscripten-wasm32/`` (with a fallback to ``emscripten-asmjs/``) instead of ``bin/`` if - you want the best performance. Until version 0.6.1 we only provided asm.js binaries. - Starting with 0.6.2 we switched to `WebAssembly builds`_ with much better performance. We have - rebuilt the older versions for wasm but the original asm.js files remain in ``bin/``. - The new ones had to be placed in a separate directory to avoid name clashes. - - Use ``emscripten-asmjs/`` and ``emscripten-wasm32/`` instead of ``bin/`` and ``wasm/`` directories - if you want to be sure whether you are downloading a wasm or an asm.js binary. - - Use ``list.json`` instead of ``list.js`` and ``list.txt``. The JSON list format contains all - the information from the old ones and more. - - Use https://binaries.soliditylang.org instead of https://solc-bin.ethereum.org. To keep things - simple we moved almost everything related to the compiler under the new ``soliditylang.org`` - domain and this applies to ``solc-bin`` too. While the new domain is recommended, the old one - is still fully supported and guaranteed to point at the same location. + 由于高度的å‘åŽå…¼å®¹æ€§è¦æ±‚,版本库包å«ä¸€äº›é—留元素,但您在编写新工具时应é¿å…使用它们: + + - 如果您想获得最佳的性能,请使用 ``emscripten-wasm32/`` (有回退功能的 ``emscripten-asmjs/``)而ä¸æ˜¯ ``bin/``。 + 在 0.6.1 版本之å‰ï¼Œæˆ‘们åªæä¾› asm.js 二进制文件。从 0.6.2 开始,我们改用 `WebAssembly builds`_,性能好得多。 + 我们已ç»ä¸ºwasmé‡å»ºäº†æ—§ç‰ˆæœ¬ï¼Œä½†åŽŸæ¥çš„asm.js文件ä»ç„¶åœ¨ ``bin/`` 下。 + 新的文件必须放在一个å•ç‹¬çš„目录中,以é¿å…å称冲çªã€‚ + - 如果您想确定下载的是 wasm 还是 asm.js 二进制文件,请使用 ``emscripten-asmjs/`` å’Œ ``emscripten-wasm32/`` + 而ä¸æ˜¯ ``bin/`` å’Œ ``wasm/`` 目录。 + - 使用 ``list.json`` 代替 ``list.js`` å’Œ ``list.txt``。JSON列表格å¼åŒ…å«äº†æ—§åˆ—表的所有信æ¯ã€‚ + - 使用 https://binaries.soliditylang.org,而ä¸æ˜¯ https://solc-bin.ethereum.org。 + 为了使事情简å•åŒ–,我们把几乎所有与编译器有关的东西都移到了新的域å ``soliditylang.org`` 下, + 这也适用于 ``solc-bin``。虽然推è使用新的域å,但旧的域åä»ç„¶è¢«å®Œå…¨æ”¯æŒï¼Œå¹¶ä¿è¯æŒ‡å‘åŒä¸€ä½ç½®ã€‚ .. warning:: - The binaries are also available at https://ethereum.github.io/solc-bin/ but this page - stopped being updated just after the release of version 0.7.2, will not receive any new releases - or nightly builds for any platform and does not serve the new directory structure, including - non-emscripten builds. + 二进制文件也å¯ä»¥åœ¨ https://ethereum.github.io/solc-bin/ 找到, + 但这个页é¢åœ¨ 0.7.2 版本å‘布åŽå°±åœæ­¢äº†æ›´æ–°ï¼Œä¸ä¼šæ”¶åˆ°ä»»ä½•å¹³å°çš„新版本或æ¯æ—¥å¼€å‘构建版本, + 也ä¸æä¾›æ–°çš„ç›®å½•ç»“æž„ï¼ŒåŒ…æ‹¬éž emscripten 的构建。 - If you are using it, please switch to https://binaries.soliditylang.org, which is a drop-in - replacement. This allows us to make changes to the underlying hosting in a transparent way and - minimize disruption. Unlike the ``ethereum.github.io`` domain, which we do not have any control - over, ``binaries.soliditylang.org`` is guaranteed to work and maintain the same URL structure - in the long-term. + 如果您正在使用它,请切æ¢åˆ° https://binaries.soliditylang.org,它是一个直接的替代。 + 这使我们能够以é€æ˜Žçš„æ–¹å¼å¯¹åº•å±‚主机进行更改,并尽é‡å‡å°‘干扰。 + 与我们无法控制的 ``ethereum.github.io`` 域åä¸åŒï¼Œ + ``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 @@ -310,13 +413,36 @@ This means that: .. _building-from-source: -Building from Source +从æºä»£ç ç¼–译 ==================== +<<<<<<< HEAD + +先决æ¡ä»¶ - 所有æ“作系统 +======= Prerequisites - All Operating Systems +>>>>>>> english/develop ------------------------------------- -The following are dependencies for all builds of Solidity: - +以下是 Solidity 构建的所有ä¾èµ–性: + +<<<<<<< HEAD + ++------------------------------------------+------------------------------+ +| 软件 | 备注 | ++==========================================+==============================+ +| `CMake`_ (在Windows上为3.21.3以上版本, | 跨平å°æž„建文件生æˆå™¨ã€‚ | +| 其他为3.13以上版) | | ++------------------------------------------+------------------------------+ +| `Boost`_ (Windows系统为 1.77 版本, | C++ 库。 | +| 其他系统1.65以上版) | | ++------------------------------------------+------------------------------+ +| `Git`_ | 用于获å–æºä»£ç çš„命令行工具。 | ++------------------------------------------+------------------------------+ +| `z3`_ (4.8.16 以上版本, å¯é€‰ï¼‰ | 与SMT检查器一起使用。 | ++------------------------------------------+------------------------------+ +| `cvc4`_ (å¯é€‰ï¼‰ | 与SMT检查器一起使用。 | ++------------------------------------------+------------------------------+ +======= +-----------------------------------+-------------------------------------------------------+ | Software | Notes | +===================================+=======================================================+ @@ -332,6 +458,7 @@ The following are dependencies for all builds of Solidity: +-----------------------------------+-------------------------------------------------------+ | `cvc4`_ (Optional) | For use with SMT checker. | +-----------------------------------+-------------------------------------------------------+ +>>>>>>> english/develop .. _cvc4: https://cvc4.cs.stanford.edu/web/ .. _Git: https://git-scm.com/download @@ -340,45 +467,53 @@ The following are dependencies for all builds of Solidity: .. _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 - Starting from 0.5.10 linking against Boost 1.70+ should work without manual intervention. + 从 0.5.10 开始,针对 Boost 1.70 以上版本的链接应该无需人工干预。 .. note:: - The default build configuration requires a specific Z3 version (the latest one at the time the - code was last updated). Changes introduced between Z3 releases often result in slightly different - (but still valid) results being returned. Our SMT tests do not account for these differences and - will likely fail with a different version than the one they were written for. This does not mean - that a build using a different version is faulty. If you pass ``-DSTRICT_Z3_VERSION=OFF`` option - to CMake, you can build with any version that satisfies the requirement given in the table above. - If you do this, however, please remember to pass the ``--no-smt`` option to ``scripts/tests.sh`` - to skip the SMT tests. + 默认的构建é…置需è¦ä¸€ä¸ªç‰¹å®šçš„ Z3 版本(在代ç æœ€åŽæ›´æ–°æ—¶çš„最新版本)。 + Z3 版本之间的å˜åŒ–常常导致返回的结果略有ä¸åŒï¼ˆä½†ä»ç„¶æœ‰æ•ˆï¼‰ã€‚ + 我们的SMT测试没有考虑到这些差异,很å¯èƒ½ä¼šåœ¨ä¸åŒçš„版本中失败,而ä¸æ˜¯ä¸ºå…¶ç¼–写的版本。 + 这并ä¸æ„味ç€ä½¿ç”¨ä¸åŒç‰ˆæœ¬çš„构建是有问题的。如果将 ``-DSTRICT_Z3_VERSION=OFF`` 选项传递给CMake, + 您å¯ä»¥ä½¿ç”¨ä»»ä½•æ»¡è¶³ä¸Šè¡¨è¦æ±‚的版本进行构建。 + 然而,如果您这样åšï¼Œè¯·è®°å¾—在 ``scripts/tests.sh`` 中传递 ``--no-smt`` 选项以跳过SMT测试。 .. note:: - By default the build is performed in *pedantic mode*, which enables extra warnings and tells the - compiler to treat all warnings as errors. - This forces developers to fix warnings as they arise, so they do not accumulate "to be fixed later". - If you are only interested in creating a release build and do not intend to modify the source code - to deal with such warnings, you can pass ``-DPEDANTIC=OFF`` option to CMake to disable this mode. - Doing this is not recommended for general use but may be necessary when using a toolchain we are - not testing with or trying to build an older version with newer tools. - If you encounter such warnings, please consider - `reporting them `_. - -Minimum Compiler Versions + 默认情况下,编译是以 *语义模å¼* 进行的,这将å¯ç”¨é¢å¤–的警告,并告诉编译器将所有警告视为错误。 + 这迫使开å‘人员在警告出现时进行修å¤ï¼Œå› æ­¤å®ƒä»¬ä¸ä¼šç´¯ç§¯åˆ°â€œä»¥åŽå†ä¿®å¤â€ã€‚ + 如果您åªå¯¹åˆ›å»ºå‘布版本感兴趣,ä¸æ‰“算修改æºä»£ç æ¥å¤„ç†è¿™äº›è­¦å‘Šï¼Œ + 您å¯ä»¥å‘CMake传递 ``-DPEDANTIC=OFF`` 选项æ¥ç¦ç”¨è¿™ç§æ¨¡å¼ã€‚ + 一般情况下ä¸å»ºè®®è¿™æ ·åšï¼Œä½†åœ¨ä½¿ç”¨æˆ‘们没有测试过的工具链或试图用较新的工具构建旧版本时, + å¯èƒ½éœ€è¦è¿™æ ·åšã€‚ + 如果您é‡åˆ°è¿™ç§è­¦å‘Šï¼Œè¯·è€ƒè™‘ `报告它们 `_。 + +最å°ç¼–译器版本 ^^^^^^^^^^^^^^^^^^^^^^^^^ -The following C++ compilers and their minimum versions can build the Solidity codebase: +以下C++编译器åŠå…¶æœ€å°ç‰ˆæœ¬å¯æž„建 Solidity 代ç åº“: -- `GCC `_, version 8+ -- `Clang `_, version 7+ -- `MSVC `_, version 2019+ +- `GCC `_, 8以上版本 +- `Clang `_, 7以上版本 +- `MSVC `_, 2019以上版本 -Prerequisites - macOS +先决æ¡ä»¶ - 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 @@ -387,22 +522,34 @@ 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 sudo xcodebuild -license accept -Our OS X build script uses `the Homebrew `_ -package manager for installing external dependencies. -Here's how to `uninstall Homebrew -`_, -if you ever want to start again from scratch. +我们的 OS X 构建脚本使用 `the Homebrew `_ +软件包管ç†å™¨æ¥å®‰è£…外部ä¾èµ–。 +如果您想从头开始的è¯ï¼Œä»¥ä¸‹æ˜¯å¦‚何 `å¸è½½Homebrew +`_。 -Prerequisites - Windows ------------------------ -You need to install the following dependencies for Windows builds of Solidity: +先决æ¡ä»¶ - Windows +----------------------- +您需è¦ä¸º Solidity çš„ Windows 版本安装以下ä¾èµ–软件包: + +<<<<<<< HEAD ++-----------------------------------+------------------------+ +| 软件 | 备注 | ++===================================+========================+ +| `Visual Studio 2019 Build Tools`_ | C++ 编译器 | ++-----------------------------------+------------------------+ +| `Visual Studio 2019`_ (å¯é€‰ï¼‰ | C++ 编译器和开å‘环境。 | ++-----------------------------------+------------------------+ +| `Boost`_ (1.77版本) | C++ 库文件。 | ++-----------------------------------+------------------------+ +======= +-----------------------------------+-------------------------------------------------------+ | Software | Notes | +===================================+=======================================================+ @@ -412,16 +559,15 @@ You need to install the following dependencies for Windows builds of Solidity: +-----------------------------------+-------------------------------------------------------+ | `Boost`_ (version 1.77+) | C++ libraries. | +-----------------------------------+-------------------------------------------------------+ +>>>>>>> english/develop -If you already have one IDE and only need the compiler and libraries, -you could install Visual Studio 2019 Build Tools. +如果您已ç»æœ‰ä¸€ä¸ª IDE 并且åªéœ€è¦ç¼–译器和库文件。您å¯ä»¥å®‰è£… Visual Studio 2019 构建工具。 -Visual Studio 2019 provides both IDE and necessary compiler and libraries. -So if you have not got an IDE and prefer to develop Solidity, Visual Studio 2019 -may be a choice for you to get everything setup easily. +Visual Studio 2019 åŒæ—¶æä¾›IDE和必è¦çš„编译器和库。 +所以,如果您没有一个 IDE,并且想è¦å¼€å‘ Solidity, +那么 Visual Studio 2019 将是一个å¯ä»¥ä½¿æ‚¨è½»æ¾èŽ·å¾—一切设置的选择。 -Here is the list of components that should be installed -in Visual Studio 2019 Build Tools or Visual Studio 2019: +以下是应在 Visual Studio 2019 构建工具或 Visual Studio 2019 中安装的组件列表: * Visual Studio C++ core features * VC++ 2019 v141 toolset (x86,x64) @@ -432,50 +578,63 @@ in Visual Studio 2019 Build Tools or Visual Studio 2019: .. _Visual Studio 2019: https://www.visualstudio.com/vs/ .. _Visual Studio 2019 Build Tools: https://visualstudio.microsoft.com/vs/older-downloads/#visual-studio-2019-and-other-products -We have a helper script which you can use to install all required external dependencies: +我们有一个辅助脚本,您å¯ä»¥ç”¨å®ƒæ¥å®‰è£…所有需è¦çš„外部ä¾èµ–: .. code-block:: bat scripts\install_deps.ps1 -This will install ``boost`` and ``cmake`` to the ``deps`` subdirectory. +这将安装 ``boost`` å’Œ ``cmake`` 到 ``deps`` å­ç›®å½•ã€‚ -Clone the Repository +克隆代ç åº“ -------------------- -To clone the source code, execute the following command: +执行以下命令,克隆æºä»£ç ï¼š .. code-block:: bash 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: + 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). + (not the "Source code" provided by GitHub). +>>>>>>> english/develop -Command-Line Build +命令行构建 ------------------ -**Be sure to install External Dependencies (see above) before build.** +**请确ä¿åœ¨æž„建å‰å®‰è£…外部ä¾èµ–项(è§ä¸Šæ–‡ï¼‰ã€‚** -Solidity project uses CMake to configure the build. -You might want to install `ccache`_ to speed up repeated builds. -CMake will pick it up automatically. -Building Solidity is quite similar on Linux, macOS and other Unices: +Solidity 项目使用 CMake æ¥é…置构建。 +您å¯èƒ½æƒ³å®‰è£… `ccache`_ 以加快é‡å¤æž„建的速度。CMake 会自动使用它。 +在 Linuxã€macOS 和其他 Unix 系统上构建 Solidity æ–¹å¼éƒ½å·®ä¸å¤šï¼š .. _ccache: https://ccache.dev/ @@ -485,18 +644,18 @@ Building Solidity is quite similar on Linux, macOS and other Unices: cd build cmake .. && make -or even easier on Linux and macOS, you can run: +或者在 Linux å’Œ macOS 上有更简å•çš„æ–¹å¼ï¼Œæ‚¨å¯ä»¥è¿è¡Œï¼š .. code-block:: bash - #note: this will install binaries solc and soltest at usr/local/bin + #注æ„:这将在 usr/local/bin 安装 solc å’Œ soltest 的二进制文件。 ./scripts/build.sh .. warning:: - BSD builds should work, but are untested by the Solidity team. + BSD 构建应该也å¯ä»¥å·¥ä½œï¼Œä½†æ˜¯ Solidity 团队没有测试过。 -And for Windows: +对于 Windows 执行: .. code-block:: bash @@ -504,81 +663,85 @@ And for Windows: cd build cmake -G "Visual Studio 16 2019" .. -In case you want to use the version of boost installed by ``scripts\install_deps.ps1``, you will -additionally need to pass ``-DBoost_DIR="deps\boost\lib\cmake\Boost-*"`` and ``-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded`` -as arguments to the call to ``cmake``. +如果您想使用由 ``scripts\install_deps.ps1`` 安装的 boost 版本, +您需è¦é¢å¤–传递 ``-DBoost_DIR="deps\boost\lib\cmake\Boost-*"`` å’Œ ``-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded`` +作为å‚æ•°ç»™ ``cmake`` 调用。 -This should result in the creation of **solidity.sln** in that build directory. -Double-clicking on that file should result in Visual Studio firing up. We suggest building -**Release** configuration, but all others work. +这将会导致在构建目录中创建 **solidity.sln** 文件。 +åŒå‡»è¯¥æ–‡ä»¶ï¼ŒVisual Studio 就会å¯åŠ¨ã€‚ +我们建议创建 **Release** é…置,但其他的é…置也å¯ä»¥ã€‚ -Alternatively, you can build for Windows on the command-line, like so: +或者,您å¯ä»¥åœ¨å‘½ä»¤è¡Œä¸Šä¸º Windows 构建,åƒè¿™æ ·ï¼š .. code-block:: bash cmake --build . --config Release -CMake Options +CMake 选项 ============= -If you are interested what CMake options are available run ``cmake .. -LH``. +如果您对CMakeçš„å¯é€‰é¡¹æ„Ÿå…´è¶£ï¼Œå¯ä»¥è¿è¡Œ ``cmake ... -LH``。 .. _smt_solvers_build: -SMT Solvers +SMT 解算器 ----------- -Solidity can be built against SMT solvers and will do so by default if -they are found in the system. Each solver can be disabled by a ``cmake`` option. +Solidity å¯ä»¥é’ˆå¯¹ SMT 解算器进行构建,如果它们在系统中被å‘现, +将默认为是这样åšçš„。æ¯ä¸ªè§£ç®—器都å¯ä»¥é€šè¿‡ ``cmake`` 选项ç¦ç”¨ã€‚ -*Note: In some cases, this can also be a potential workaround for build failures.* +*注æ„:在æŸäº›æƒ…况下,这也å¯ä»¥æ˜¯æž„建失败åŽï¼Œå¯èƒ½çš„å˜é€šæ–¹æ³•ã€‚* -Inside the build folder you can disable them, since they are enabled by default: +在构建文件夹内,您å¯ä»¥ç¦ç”¨å®ƒä»¬ï¼Œå› ä¸ºå®ƒä»¬æ˜¯é»˜è®¤å¯ç”¨çš„: .. code-block:: bash - # disables only Z3 SMT Solver. + # åªç¦ç”¨Z3 SMT解算器。 cmake .. -DUSE_Z3=OFF - # disables only CVC4 SMT Solver. + # åªç¦ç”¨CVC4 SMT解算器。 cmake .. -DUSE_CVC4=OFF - # disables both Z3 and CVC4 + # åŒæ—¶ç¦ç”¨Z3å’ŒCVC4 cmake .. -DUSE_CVC4=OFF -DUSE_Z3=OFF -The Version String in Detail +版本å·å­—符串详解 ============================ -The Solidity version string contains four parts: +Solidity 版本å包å«å››éƒ¨åˆ†ï¼š -- the version number -- pre-release tag, usually set to ``develop.YYYY.MM.DD`` or ``nightly.YYYY.MM.DD`` -- commit in the format of ``commit.GITHASH`` -- platform, which has an arbitrary number of items, containing details about the platform and compiler +- ç‰ˆæœ¬å· +- 预å‘布版本标签,通常为 ``develop.YYYY.MM.DD`` 或者 ``nightly.YYYY.MM.DD`` +- 以 ``commit.GITHASH`` æ ¼å¼å±•ç¤ºçš„æäº¤å· +- 由若干æ¡å¹³å°ã€ç¼–译器详细信æ¯æž„æˆçš„å¹³å°æ ‡è¯† -If there are local modifications, the commit will be postfixed with ``.mod``. +如果有本地修改,æ交将会有åŽç¼€ ``.mod``。 -These parts are combined as required by SemVer, where the Solidity pre-release tag equals to the SemVer pre-release -and the Solidity commit and platform combined make up the SemVer build metadata. +这些部分按照 Semver çš„è¦æ±‚æ¥ç»„åˆï¼Œ 其中 Solidity 预å‘布版标签等价于 Semver 预å‘布版标签, +而 Solidity æ交å·å’Œå¹³å°æ ‡è¯†åˆ™ç»„æˆSemver的构建元数æ®ã€‚ -A release example: ``0.4.8+commit.60cc1668.Emscripten.clang``. +å‘布版样例: ``0.4.8+commit.60cc1668.Emscripten.clang``。 -A pre-release example: ``0.4.9-nightly.2017.1.17+commit.6ecb4aa3.Emscripten.clang`` +预å‘布版样例: ``0.4.9-nightly.2017.1.17+commit.6ecb4aa3.Emscripten.clang``。 -Important Information About Versioning +关于版本管ç†çš„é‡è¦ä¿¡æ¯ ====================================== -After a release is made, the patch version level is bumped, because we assume that only -patch level changes follow. When changes are merged, the version should be bumped according -to SemVer and the severity of the change. Finally, a release is always made with the version -of the current nightly build, but without the ``prerelease`` specifier. +在版本å‘布之åŽï¼Œè¡¥ä¸ç‰ˆæœ¬å·ä¼šå¢žåŠ ï¼Œå› ä¸ºæˆ‘们å‡å®šæŽ¥ä¸‹æ¥åªæœ‰è¡¥ä¸çº§åˆ«çš„å˜æ›´ã€‚ +当å˜æ›´è¢«åˆå¹¶åŽï¼Œç‰ˆæœ¬åº”è¯¥æ ¹æ® Semver å’Œå˜æ›´çš„é‡è¦ç¨‹åº¦æ¥æå‡ã€‚ +最åŽï¼Œå‘行版本总是与当å‰æ¯æ—¥å¼€å‘构建版本本的版本å·ä¸€è‡´ï¼Œä½†æ²¡æœ‰ ``prerelease`` 指示符。 + -Example: +示例: -1. The 0.4.0 release is made. -2. The nightly build has a version of 0.4.1 from now on. -3. Non-breaking changes are introduced --> no change in version. -4. A breaking change is introduced --> version is bumped to 0.5.0. -5. The 0.5.0 release is made. +<<<<<<< HEAD +1. 0.4.0 版本å‘布。 +2. 从现在开始,æ¯æ™šæž„建一个 0.4.1 版本。 +3. 引入éžé‡å¤§å˜æ›´ —— ä¸æ”¹å˜ç‰ˆæœ¬å·ã€‚ +4. 引入é‡å¤§å˜æ›´ —— 版本å·æå‡åˆ° 0.5.0。 +5. 0.5.0 版本å‘布。 +该方å¼ä¸Ž :ref:`version pragma ` 一起è¿è¡Œè‰¯å¥½ã€‚ +======= This behavior works well with the :ref:`version pragma `. +>>>>>>> english/develop diff --git a/docs/internals/layout_in_calldata.rst b/docs/internals/layout_in_calldata.rst index aef27b1531c3..4239ce3b95a8 100644 --- a/docs/internals/layout_in_calldata.rst +++ b/docs/internals/layout_in_calldata.rst @@ -1,16 +1,13 @@ .. index: calldata layout -******************* -Layout of Call Data -******************* +*********************** +调用数æ®çš„存储结构 +*********************** -The input data for a function call is assumed to be in the format defined by the :ref:`ABI -specification `. Among others, the ABI specification requires arguments to be padded to multiples of 32 -bytes. The internal function calls use a different convention. - -Arguments for the constructor of a contract are directly appended at the end of the -contract's code, also in ABI encoding. The constructor will access them through a hard-coded offset, and -not by using the ``codesize`` opcode, since this of course changes when appending -data to the code. +一个函数调用的输入数æ®çš„æ ¼å¼è¢«è®¤ä¸ºä¼šéµå¾ª :ref:`ABI规范 ` 所定义的格å¼ã€‚ +其中,ABI规范è¦æ±‚å‚数被填充为32字节的å€æ•°ã€‚而内部函数调用会使用ä¸åŒè§„则。 +åˆçº¦çš„构造函数的å‚数直接附加在åˆçº¦çš„字节ç æœ«å°¾ï¼Œ +也是ABIç¼–ç çš„。构造函数将通过一个硬编ç çš„å移é‡æ¥è®¿é—®å®ƒä»¬ï¼Œ +而ä¸æ˜¯é€šè¿‡ä½¿ç”¨ ``codesize`` æ“作ç ï¼Œå› ä¸ºåœ¨å‘代ç è¿½åŠ æ•°æ®æ—¶å®ƒä¼šå‘生改å˜ã€‚ diff --git a/docs/internals/layout_in_memory.rst b/docs/internals/layout_in_memory.rst index 8c20b625284e..a138215d7e19 100644 --- a/docs/internals/layout_in_memory.rst +++ b/docs/internals/layout_in_memory.rst @@ -2,52 +2,47 @@ .. index: memory layout **************** -Layout in Memory +内存中的存储结构 **************** -Solidity reserves four 32-byte slots, with specific byte ranges (inclusive of endpoints) being used as follows: +Solidityä¿ç•™äº†å››ä¸ª32字节的æ’槽,具体的字节范围(包括端点)使用如下: -- ``0x00`` - ``0x3f`` (64 bytes): scratch space for hashing methods -- ``0x40`` - ``0x5f`` (32 bytes): currently allocated memory size (aka. free memory pointer) -- ``0x60`` - ``0x7f`` (32 bytes): zero slot +- ``0x00`` - ``0x3f`` (64字节): 用于哈希方法的临时空间 +- ``0x40`` - ``0x5f`` (32字节): 当å‰åˆ†é…的内存大å°ï¼ˆåˆç§°ç©ºé—²å†…存指针)。 +- ``0x60`` - ``0x7f`` (32字节): 0 值æ’槽 -Scratch space can be used between statements (i.e. within inline assembly). The zero slot -is used as initial value for dynamic memory arrays and should never be written to -(the free memory pointer points to ``0x80`` initially). +临时空间å¯ä»¥åœ¨è¯­å¥ä¹‹é—´ä½¿ç”¨ï¼ˆå³åœ¨å†…è”汇编之中)。 +0 值æ’槽则用æ¥å¯¹åŠ¨æ€å†…存数组进行åˆå§‹åŒ–,且永远ä¸ä¼šå†™å…¥æ•°æ® +(因而å¯ç”¨çš„åˆå§‹å†…存指针为 ``0x80``)。 -Solidity always places new objects at the free memory pointer and -memory is never freed (this might change in the future). +Solidity 总会把新对象ä¿å­˜åœ¨ç©ºé—²å†…存指针的ä½ç½®ï¼Œ +所以这段内存实际上从æ¥ä¸ä¼šç©ºé—²ï¼ˆåœ¨æœªæ¥å¯èƒ½ä¼šä¿®æ”¹è¿™ä¸ªæœºåˆ¶ï¼‰ã€‚ -Elements in memory arrays in Solidity always occupy multiples of 32 bytes (this -is even true for ``bytes1[]``, but not for ``bytes`` and ``string``). -Multi-dimensional memory arrays are pointers to memory arrays. The length of a -dynamic array is stored at the first slot of the array and followed by the array -elements. +Solidity中内存数组中的元素总是å æ®32字节的å€æ•° +(对于 ``bytes1[]`` æ¥è¯´ä¹Ÿæ˜¯å¦‚此,但对于 ``bytes`` å’Œ ``string`` æ¥è¯´ä¸æ˜¯è¿™æ ·ï¼‰ã€‚ +多维内存数组是指å‘内存数组的指针. 一个动æ€æ•°ç»„的长度被存储在数组的第一个槽里,åŽé¢æ˜¯æ•°ç»„元素。 .. warning:: - There are some operations in Solidity that need a temporary memory area - larger than 64 bytes and therefore will not fit into the scratch space. - They will be placed where the free memory points to, but given their - short lifetime, the pointer is not updated. The memory may or may not - be zeroed out. Because of this, one should not expect the free memory - to point to zeroed out memory. + 在Solidity中,有一些æ“作需è¦ä¸€ä¸ªå¤§äºŽ64字节的临时内存区域, + 因此将ä¸é€‚åˆæ”¾åœ¨é»˜è®¤çš„临时空间中。它们将被放置在空闲内存指å‘çš„ä½ç½®ï¼Œ + 但由于这ç§æ•°æ®çš„生命周期较短,这个指针ä¸ä¼šå³æ—¶æ›´æ–°ã€‚ + 这部分内存å¯èƒ½ä¼šè¢«æ¸…零也å¯èƒ½ä¸ä¼šã€‚ + 所以我们ä¸åº”该期望这些所谓的空闲内存总会被清零。 - While it may seem like a good idea to use ``msize`` to arrive at a - definitely zeroed out memory area, using such a pointer non-temporarily - without updating the free memory pointer can have unexpected results. + 虽然使用 ``msize`` æ¥åˆ°è¾¾ä¸€ä¸ªç»å¯¹æ¸…零的内存区域似乎是个好主æ„, + 但在ä¸æ›´æ–°ç©ºé—²å†…存指针的情况下,éžä¸´æ—¶æ€§åœ°ä½¿ç”¨è¿™æ ·çš„指针会产生æ„想ä¸åˆ°çš„结果。 -Differences to Layout in Storage +与存储结构的区别 ================================ -As described above the layout in memory is different from the layout in -:ref:`storage`. Below there are some examples. +如上所述,内存中的存储结构与 :ref:`存储(storage) ` 中的存储结构是ä¸åŒçš„。 +下é¢æ˜¯ä¸€äº›ä¾‹å­ã€‚ -Example for Difference in Arrays +åœ¨æ•°ç»„ä¸­çš„å·®å¼‚çš„ä¾‹å­ -------------------------------- -The following array occupies 32 bytes (1 slot) in storage, but 128 -bytes (4 items with 32 bytes each) in memory. +下é¢çš„数组在存储中å ç”¨32字节(1个槽),但在内存中å ç”¨128字节(4项,æ¯ä¸ª32字节)。 .. code-block:: solidity @@ -55,11 +50,11 @@ bytes (4 items with 32 bytes each) in memory. -Example for Difference in Struct Layout +åœ¨ç»“æž„ä½“ä¸­å­˜å‚¨ç»“æž„å·®å¼‚çš„ä¾‹å­ --------------------------------------- -The following struct occupies 96 bytes (3 slots of 32 bytes) in storage, -but 128 bytes (4 items with 32 bytes each) in memory. +以下结构体在存储中å ç”¨96字节(3个32字节的槽), +但在内存中å ç”¨128字节(4项,æ¯ä¸ª32字节)。 .. code-block:: solidity diff --git a/docs/internals/layout_in_storage.rst b/docs/internals/layout_in_storage.rst index 7afcfc2ac5c0..4159f4c07779 100644 --- a/docs/internals/layout_in_storage.rst +++ b/docs/internals/layout_in_storage.rst @@ -1,103 +1,92 @@ .. index:: storage, state variable, mapping ************************************ -Layout of State Variables in Storage +存储中的状æ€å˜é‡å‚¨å­˜ç»“æž„ ************************************ .. _storage-inplace-encoding: -State variables of contracts are stored in storage in a compact way such -that multiple values sometimes use the same storage slot. -Except for dynamically-sized arrays and mappings (see below), data is stored -contiguously item after item starting with the first state variable, -which is stored in slot ``0``. For each variable, -a size in bytes is determined according to its type. -Multiple, contiguous items that need less than 32 bytes are packed into a single -storage slot if possible, according to the following rules: +åˆçº¦çš„状æ€å˜é‡ä»¥ä¸€ç§ç´§å‡‘çš„æ–¹å¼å­˜å‚¨ï¼Œ +这样多个值有时会使用åŒä¸€ä¸ªå­˜å‚¨æ§½ã€‚ +除了动æ€å¤§å°çš„数组和映射(è§ä¸‹æ–‡ï¼‰ä¹‹å¤–, +æ•°æ®æ˜¯è¢«é€é¡¹å­˜å‚¨çš„,从第一个状æ€å˜é‡å¼€å§‹ï¼Œ +它被存储在槽 ``0`` 中。对于æ¯ä¸ªå˜é‡ï¼Œ +æ ¹æ®å®ƒçš„类型确定一个字节的大å°ã€‚如果å¯èƒ½çš„è¯ï¼Œéœ€è¦å°‘于32字节的多个连续项目被打包到一个存储槽中, +æ ¹æ®ä»¥ä¸‹è§„则: -- The first item in a storage slot is stored lower-order aligned. -- Value types use only as many bytes as are necessary to store them. -- If a value type does not fit the remaining part of a storage slot, it is stored in the next storage slot. -- Structs and array data always start a new slot and their items are packed tightly according to these rules. -- Items following struct or array data always start a new storage slot. +- 存储æ’槽的第一项会以低ä½å¯¹é½ï¼ˆå³å³å¯¹é½ï¼‰çš„æ–¹å¼å‚¨å­˜ã€‚ +- 值类型åªä½¿ç”¨å­˜å‚¨å®ƒä»¬æ‰€éœ€çš„字节数。 +- 如果一个值类型ä¸é€‚åˆä¸€ä¸ªå­˜å‚¨æ§½çš„剩余部分,它将被存储在下一个存储槽。 +- 结构和数组数æ®æ€»æ˜¯ä»Žä¸€ä¸ªæ–°çš„存储槽开始,它们的项根æ®è¿™äº›è§„则被紧密地打包。 +- 结构或数组数æ®ä¹‹åŽçš„å˜é‡æ€»æ˜¯å¼€è¾Ÿä¸€ä¸ªæ–°çš„存储槽。 -For contracts that use inheritance, the ordering of state variables is determined by the -C3-linearized order of contracts starting with the most base-ward contract. If allowed -by the above rules, state variables from different contracts do share the same storage slot. +对于使用继承的åˆçº¦ï¼ŒçŠ¶æ€å˜é‡çš„排åºæ˜¯ä»Žæœ€åŸºç¡€çš„åˆçº¦å¼€å§‹ï¼Œç”±åˆçº¦çš„C3线性化顺åºå†³å®šçš„。 +如果上述规则å…许,æ¥è‡ªä¸åŒåˆçº¦çš„状æ€å˜é‡ç¡®å®žå…±äº«åŒä¸€ä¸ªå­˜å‚¨æ§½ã€‚ -The elements of structs and arrays are stored after each other, just as if they were given -as individual values. +结构体和数组中的元素都是顺åºå­˜å‚¨çš„,就åƒå®ƒä»¬è¢«æ˜Žç¡®ç»™å®šçš„那样。 .. warning:: - When using elements that are smaller than 32 bytes, your contract's gas usage may be higher. - This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller - than that, the EVM must use more operations in order to reduce the size of the element from 32 - bytes to the desired size. - - It might be beneficial to use reduced-size types if you are dealing with storage values - because the compiler will pack multiple elements into one storage slot, and thus, combine - multiple reads or writes into a single operation. - If you are not reading or writing all the values in a slot at the same time, this can - have the opposite effect, though: When one value is written to a multi-value storage - slot, the storage slot has to be read first and then - combined with the new value such that other data in the same slot is not destroyed. - - When dealing with function arguments or memory - values, there is no inherent benefit because the compiler does not pack these values. - - Finally, in order to allow the EVM to optimize for this, ensure that you try to order your - storage variables and ``struct`` members such that they can be packed tightly. For example, - declaring your storage variables in the order of ``uint128, uint128, uint256`` instead of - ``uint128, uint256, uint128``, as the former will only take up two slots of storage whereas the - latter will take up three. + 当使用å°äºŽ32字节的元素时,您的åˆçº¦çš„气体用é‡å¯èƒ½ä¼šæ›´é«˜ã€‚ + 这是因为EVMæ¯æ¬¡å¯¹32字节进行æ“作。因此,如果元素å°äºŽè¿™ä¸ªå¤§å°ï¼Œ + EVM必须使用更多的æ“作,以便将元素的大å°ä»Ž32字节å‡å°‘到所需的大å°ã€‚ + + 如果您处ç†çš„是存储值,使用缩å°å°ºå¯¸çš„类型å¯èƒ½æ˜¯æœ‰ç›Šçš„, + 因为编译器会将多个元素打包到一个存储槽中, + 从而将多个读或写åˆå¹¶åˆ°ä¸€ä¸ªæ“作中。 + 如果您ä¸æ˜¯åœ¨åŒä¸€æ—¶é—´è¯»å–或写入一个槽中的所有值, + è¿™å¯èƒ½ä¼šäº§ç”Ÿç›¸å的效果,虽然。当一个值被写入一个多值存储槽时, + 该存储槽必须先被读å–, + 然åŽä¸Žæ–°å€¼ç»“åˆï¼Œè¿™æ ·åŒä¸€æ§½ä¸­çš„其他数æ®å°±ä¸ä¼šè¢«ç ´å。 + + 在处ç†å‡½æ•°å‚数或内存值时,因为编译器ä¸ä¼šæ‰“包这些值,所以没有什么好处, + + 最åŽï¼Œä¸ºäº†è®©EVM对此进行优化, + ç¡®ä¿æ‚¨çš„存储å˜é‡å’Œ ``struct`` æˆå‘˜çš„顺åºï¼Œä½¿å®ƒä»¬èƒ½å¤Ÿè¢«ç´§å¯†åœ°åŒ…装起æ¥ã€‚ + 例如,按照 ``uint128, uint128, uint256`` 的顺åºå£°æ˜Žæ‚¨çš„存储å˜é‡ï¼Œ + 而ä¸æ˜¯ ``uint128, uint256, uint128``,因为å‰è€…åªå ç”¨ä¸¤ä¸ªå­˜å‚¨æ§½ï¼Œ + 而åŽè€…则å ç”¨ä¸‰ä¸ªå­˜å‚¨æ§½ã€‚ .. note:: - The layout of state variables in storage is considered to be part of the external interface - of Solidity due to the fact that storage pointers can be passed to libraries. This means that - any change to the rules outlined in this section is considered a breaking change - of the language and due to its critical nature should be considered very carefully before - being executed. In the event of such a breaking change, we would want to release a - compatibility mode in which the compiler would generate bytecode supporting the old layout. + 由于存储指针å¯ä»¥ä¼ é€’给库,存储中的状æ€å˜é‡çš„结构被认为是 Solidity 外部接å£çš„一部分。 + è¿™æ„味ç€å¯¹è¿™ä¸€èŠ‚中概述的规则的任何改å˜éƒ½è¢«è®¤ä¸ºæ˜¯å¯¹è¯­è¨€çš„é‡å¤§æ”¹å˜ï¼Œ + 由于它的关键性质,在执行之å‰åº”该éžå¸¸ä»”细地考虑。 + 在å‘生这ç§é‡å¤§å˜åŒ–的情况下,我们希望å‘布一ç§å…¼å®¹æ¨¡å¼ï¼Œ + 在这ç§æ¨¡å¼ä¸‹ï¼Œç¼–译器将生æˆæ”¯æŒæ—§ç»“构的字节ç ã€‚ -Mappings and Dynamic Arrays +映射和动æ€æ•°ç»„ =========================== .. _storage-hashed-encoding: -Due to their unpredictable size, mappings and dynamically-sized array types cannot be stored -"in between" the state variables preceding and following them. -Instead, they are considered to occupy only 32 bytes with regards to the -:ref:`rules above ` and the elements they contain are stored starting at a different -storage slot that is computed using a Keccak-256 hash. +由于映射和动æ€æ•°ç»„的大å°æ˜¯ä¸å¯é¢„知的,他们ä¸èƒ½è¢«å­˜å‚¨åœ¨å…¶å‰åŽçš„状æ€å˜é‡ä¹‹é—´ã€‚ +相å,它们被认为åªå ç”¨32个字节, 与 :ref:`上述规则 ` 有关, +它们所包å«çš„元素被存储在一个ä¸åŒçš„存储槽,该存储槽是用Keccak-256哈希计算的。 -Assume the storage location of the mapping or array ends up being a slot ``p`` -after applying :ref:`the storage layout rules `. -For dynamic arrays, -this slot stores the number of elements in the array (byte arrays and -strings are an exception, see :ref:`below `). -For mappings, the slot stays empty, but it is still needed to ensure that even if there are -two mappings next to each other, their content ends up at different storage locations. +å‡è®¾æ˜ å°„或数组的存储ä½ç½®åœ¨é€‚应了 :ref:`存储结构规则 ` åŽï¼Œæœ€ç»ˆä½äºŽä¸€ä¸ªæ§½ ``p``。 +对于动æ€æ•°ç»„ï¼Œè¿™ä¸ªæ§½å­˜å‚¨äº†æ•°ç»„ä¸­çš„å…ƒç´ æ•°é‡ +(字节数组和字符串是一个例外,å‚è§ :ref:`下文 `)。 +对于映射æ¥è¯´ï¼Œè¿™ä¸ªæ§½ä¿æŒç©ºçš„状æ€ï¼Œ +但是ä»ç„¶éœ€è¦å®ƒæ¥ç¡®ä¿å³ä½¿æœ‰ä¸¤ä¸ªæ˜ å°„相邻,它们的内容最终也是在ä¸åŒçš„存储ä½ç½®ã€‚ -Array data is located starting at ``keccak256(p)`` and it is laid out in the same way as -statically-sized array data would: One element after the other, potentially sharing -storage slots if the elements are not longer than 16 bytes. Dynamic arrays of dynamic arrays apply this -rule recursively. The location of element ``x[i][j]``, where the type of ``x`` is ``uint24[][]``, is -computed as follows (again, assuming ``x`` itself is stored at slot ``p``): -The slot is ``keccak256(keccak256(p) + i) + floor(j / floor(256 / 24))`` and -the element can be obtained from the slot data ``v`` using ``(v >> ((j % floor(256 / 24)) * 24)) & type(uint24).max``. +数组数æ®ä»Ž ``keccak256(p)`` 开始,它的排列方å¼ä¸Žé™æ€å¤§å°çš„阵列数æ®ç›¸åŒï¼š +一个元素接ç€ä¸€ä¸ªå…ƒç´ ï¼Œå¦‚果元素的长度ä¸è¶…过16字节, +就有å¯èƒ½å…±äº«å­˜å‚¨æ§½ã€‚包å«åŠ¨æ€æ•°ç»„的动æ€æ•°ç»„递归地应用这一规则。 +元素 ``x[i][j]`` çš„ä½ç½®ä¸ºï¼Œå…¶ä¸­ ``x`` 的类型是 ``uint24[][]`` , +计算方法如下(åŒæ ·ï¼Œå‡è®¾ ``x`` 本身存储在槽 ``p``): +槽是 ``keccak256(keccak256(p)+i)+ floor(j / floor(256 / 24))``, +元素å¯ä»¥ä»Žæ§½æ•°æ® ``v`` 得到,使用 ``(v >> ((j % floor(256 / 24)) * 24)) & type(uint24).max``。 -The value corresponding to a mapping key ``k`` is located at ``keccak256(h(k) . p)`` -where ``.`` is concatenation and ``h`` is a function that is applied to the key depending on its type: +对应于映射键 ``k`` 的值ä½äºŽ ``keccak256(h(k) . p)``, +其中 ``.`` 是连接符, ``h`` 是一个函数,根æ®é”®çš„类型应用于键。 -- for value types, ``h`` pads the value to 32 bytes in the same way as when storing the value in memory. -- for strings and byte arrays, ``h(k)`` is just the unpadded data. +- 对于值类型, 函数 ``h`` 将与在内存中存储值的相åŒæ–¹å¼æ¥å°†å€¼å¡«å……为32字节。 +- 对于字符串和字节数组, ``h(k)`` åªæ˜¯æœªå¡«å……çš„æ•°æ®ã€‚ -If the mapping value is a -non-value type, the computed slot marks the start of the data. If the value is of struct type, -for example, you have to add an offset corresponding to the struct member to reach the member. +如果映射类型的值是一个éžå€¼ç±»åž‹ï¼Œåˆ™è®¡ç®—的槽会标记为数æ®çš„开始ä½ç½®ã€‚ +例如,如果值是结构体类型,您必须添加一个与结构体æˆå‘˜ç›¸å¯¹åº”çš„å移é‡æ‰èƒ½è®¿é—®åˆ°è¯¥æˆå‘˜ã€‚ -As an example, consider the following contract: +作为示例,å‚考以下åˆçº¦ï¼š .. code-block:: solidity @@ -111,46 +100,44 @@ As an example, consider the following contract: mapping(uint => mapping(uint => S)) data; } -Let us compute the storage location of ``data[4][9].c``. -The position of the mapping itself is ``1`` (the variable ``x`` with 32 bytes precedes it). -This means ``data[4]`` is stored at ``keccak256(uint256(4) . uint256(1))``. The type of ``data[4]`` is -again a mapping and the data for ``data[4][9]`` starts at slot -``keccak256(uint256(9) . keccak256(uint256(4) . uint256(1)))``. -The slot offset of the member ``c`` inside the struct ``S`` is ``1`` because ``a`` and ``b`` are packed -in a single slot. This means the slot for -``data[4][9].c`` is ``keccak256(uint256(9) . keccak256(uint256(4) . uint256(1))) + 1``. -The type of the value is ``uint256``, so it uses a single slot. +让我们计算一下 ``data[4][9].c`` 的存储ä½ç½®ã€‚ +映射本身的ä½ç½®æ˜¯ ``1`` (å˜é‡ ``x`` å‰é¢æœ‰32字节)。 +è¿™æ„å‘³ç€ ``data[4]`` 存储在 ``keccak256(uint256(4) . uint256(1))``。 +``data[4]`` 的类型还是一个映射, +``data[4][9]`` çš„æ•°æ®ä»Ž ``keccak256(uint256(9) . keccak256(uint256(4) . uint256(1)))`` 槽开始。 +æˆå‘˜ ``c`` 在结构 ``S`` 中的槽ä½å移是 ``1``,因为 ``a`` å’Œ ``b`` 被装在一个槽ä½ä¸­ã€‚ +è¿™æ„å‘³ç€ ``data[4][9].c`` çš„æ’槽是 ``keccak256(uint256(9) . keccak256(uint256(4) . uint256(1))) + 1``。 +该值的类型是 ``uint256``,所以它å ç”¨ä¸€ä¸ªæ§½ã€‚ .. _bytes-and-string: -``bytes`` and ``string`` +``bytes`` å’Œ ``string`` ------------------------ -``bytes`` and ``string`` are encoded identically. -In general, the encoding is similar to ``bytes1[]``, in the sense that there is a slot for the array itself and -a data area that is computed using a ``keccak256`` hash of that slot's position. -However, for short values (shorter than 32 bytes) the array elements are stored together with the length in the same slot. +``bytes`` å’Œ ``string`` çš„ç¼–ç æ˜¯ç›¸åŒçš„。 +一般æ¥è¯´ï¼Œç¼–ç ä¸Ž ``bytes1[]`` 类似,å³æœ‰ä¸€ä¸ªæ§½ç”¨äºŽå­˜æ”¾æ•°ç»„本身和一个数æ®åŒºï¼Œ +这个数æ®åŒºæ˜¯ç”¨è¯¥æ§½çš„ä½ç½®çš„ ``keccak256`` 哈希值计算的。 +然而,对于较短的值(短于32字节),数组元素与长度一起存储在åŒä¸€ä¸ªæ§½ä¸­ã€‚ -In particular: if the data is at most ``31`` bytes long, the elements are stored -in the higher-order bytes (left aligned) and the lowest-order byte stores the value ``length * 2``. -For byte arrays that store data which is ``32`` or more bytes long, the main slot ``p`` stores ``length * 2 + 1`` and the data is -stored as usual in ``keccak256(p)``. This means that you can distinguish a short array from a long array -by checking if the lowest bit is set: short (not set) and long (set). +特别是:如果数æ®æœ€å¤šåªæœ‰ ``31`` 字节长, +元素被存储在高阶字节中(左对é½ï¼‰ï¼Œæœ€ä½Žé˜¶å­—节存储值 ``length * 2``。 +对于存储数æ®é•¿åº¦ä¸º ``32`` 或更多字节的字节数,主槽 ``p`` 存储 ``length * 2 + 1``, +æ•°æ®ç…§å¸¸å­˜å‚¨åœ¨ ``keccak256(p)``。这æ„味ç€æ‚¨å¯ä»¥é€šè¿‡æ£€æŸ¥æœ€ä½Žä½æ˜¯å¦è¢«è®¾ç½®æ¥åŒºåˆ†çŸ­æ•°ç»„和长数组: +短数组(未设置)和长数组(设置)。 .. note:: - Handling invalidly encoded slots is currently not supported but may be added in the future. - If you are compiling via IR, reading an invalidly encoded slot results in a ``Panic(0x22)`` error. + ç›®å‰ä¸æ”¯æŒå¤„ç†æ— æ•ˆç¼–ç çš„槽,但将æ¥å¯èƒ½ä¼šåŠ å…¥ã€‚ + 如果您通过 IR 进行编译,读å–一个无效编ç çš„槽会导致 ``Panic(0x22)`` 错误。 -JSON Output +JSON输出 =========== .. _storage-layout-top-level: -The storage layout of a contract can be requested via -the :ref:`standard JSON interface `. The output is a JSON object containing two keys, -``storage`` and ``types``. The ``storage`` object is an array where each -element has the following form: +åˆçº¦çš„存储结构å¯ä»¥é€šè¿‡ :ref:`标准的JSONæŽ¥å£ ` 请求获得。 +输出的是一个JSON对象,包å«ä¸¤ä¸ªé”®ï¼Œ ``storage`` å’Œ ``types``。 +``storage`` 对象是一个数组,æ¯ä¸ªå…ƒç´ éƒ½æœ‰ä»¥ä¸‹å½¢å¼ï¼š .. code-block:: json @@ -165,20 +152,16 @@ element has the following form: "type": "t_uint256" } -The example above is the storage layout of ``contract A { uint x; }`` from source unit ``fileA`` -and +上é¢çš„例å­æ¥è‡ªæºäºŽé¡¹ç›® ``fileA`` çš„ ``contract A { uint x; }`` 的存储结构,并且 -- ``astId`` is the id of the AST node of the state variable's declaration -- ``contract`` is the name of the contract including its path as prefix -- ``label`` is the name of the state variable -- ``offset`` is the offset in bytes within the storage slot according to the encoding -- ``slot`` is the storage slot where the state variable resides or starts. This - number may be very large and therefore its JSON value is represented as a - string. -- ``type`` is an identifier used as key to the variable's type information (described in the following) +- ``astId`` 是状æ€å˜é‡å£°æ˜Žçš„AST节点的ID +- ``contract`` 是åˆçº¦çš„å称,包括其路径作为å‰ç¼€ +- ``label`` 是状æ€å˜é‡çš„å称 +- ``offset`` 是根æ®ç¼–ç åœ¨å­˜å‚¨æ§½ä¸­çš„字节åç§»é‡ +- ``slot`` 是状æ€å˜é‡æ‰€åœ¨æˆ–开始的存储槽。这个数字å¯èƒ½éžå¸¸å¤§ï¼Œå› æ­¤å®ƒçš„JSON值被表示为一个字符串 +- ``type`` 是一个标识符,作为å˜é‡ç±»åž‹ä¿¡æ¯çš„关键(如下所述) -The given ``type``, in this case ``t_uint256`` represents an element in -``types``, which has the form: +给定的 ``type``,在这里是 ``t_uint256``,代表 ``types`` 中的一个元素,它的形å¼æ˜¯ï¼š .. code-block:: json @@ -189,31 +172,29 @@ The given ``type``, in this case ``t_uint256`` represents an element in "numberOfBytes": "32", } -where +这里 -- ``encoding`` how the data is encoded in storage, where the possible values are: +- ``encoding`` æ•°æ®åœ¨å­˜å‚¨ä¸­æ˜¯å¦‚何编ç çš„,å¯èƒ½çš„值是: - - ``inplace``: data is laid out contiguously in storage (see :ref:`above `). - - ``mapping``: Keccak-256 hash-based method (see :ref:`above `). - - ``dynamic_array``: Keccak-256 hash-based method (see :ref:`above `). - - ``bytes``: single slot or Keccak-256 hash-based depending on the data size (see :ref:`above `). + - ``inplace``: æ•°æ®åœ¨å­˜å‚¨ä¸­æ˜¯è¿žç»­å¸ƒç½®çš„(å‚è§ :ref:`上文 `)。 + - ``mapping``: 基于Keccak-256的哈希方法(å‚è§ :ref:`上文 `)。 + - ``dynamic_array``: 基于Keccak-256的哈希方法(å‚è§ :ref:`上文 `)。 + - ``bytes``: å•æ§½æˆ–基于Keccak-256哈希值,å–决于数æ®å¤§å°ï¼ˆå‚è§ :ref:`上文 `)。 -- ``label`` is the canonical type name. -- ``numberOfBytes`` is the number of used bytes (as a decimal string). - Note that if ``numberOfBytes > 32`` this means that more than one slot is used. +- ``label`` 是典型的类型å称。 +- ``numberOfBytes`` 是使用的字节数(å进制字符串)。 + 注æ„,如果 ``numberOfBytes > 32`` è¿™æ„味ç€ä½¿ç”¨äº†ä¸€ä¸ªä»¥ä¸Šçš„槽。 -Some types have extra information besides the four above. Mappings contain -its ``key`` and ``value`` types (again referencing an entry in this mapping -of types), arrays have its ``base`` type, and structs list their ``members`` in -the same format as the top-level ``storage`` (see :ref:`above -`). +除了上述四ç§ç±»åž‹å¤–,有些类型还有é¢å¤–çš„ä¿¡æ¯ã€‚ +映射包å«å®ƒçš„ ``key`` å’Œ ``value`` 类型(å†æ¬¡å¼•ç”¨è¿™ä¸ªç±»åž‹æ˜ å°„中的一个项), +数组有它的 ``base`` 类型,结构体会列出它们的 ``æˆå‘˜``, +其格å¼ä¸Žé«˜å±‚次的 ``storage`` 相åŒï¼ˆå‚è§ :ref:`上文 `)。 .. note:: - The JSON output format of a contract's storage layout is still considered experimental - and is subject to change in non-breaking releases of Solidity. + åˆçº¦çš„存储结构的 JSON 输出格å¼ä»è¢«è®¤ä¸ºæ˜¯å®žéªŒæ€§çš„, + 并且在 Solidity çš„éžé‡å¤§ç‰ˆæœ¬ä¸­ä¼šæœ‰å˜åŒ–。 -The following example shows a contract and its storage layout, containing -value and reference types, types that are encoded packed, and nested types. +下é¢çš„例å­æ˜¾ç¤ºäº†ä¸€ä¸ªåˆçº¦åŠå…¶å­˜å‚¨ç»“构,包å«å€¼ç±»åž‹å’Œå¼•ç”¨ç±»åž‹ï¼Œè¢«ç¼–ç æ‰“包的类型,以åŠåµŒå¥—的类型。 .. code-block:: solidity diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index b3e144e94744..1f878ccccbe3 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -2,23 +2,52 @@ .. _optimizer: ************* -The Optimizer +优化器 ************* -The Solidity compiler uses two different optimizer modules: The "old" optimizer -that operates at the opcode level and the "new" optimizer that operates on Yul IR code. +<<<<<<< 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 + +基于æ“作ç çš„优化器对æ“作ç åº”用一套 `简化规则 `_。 +它还结åˆäº†ç›¸ç­‰çš„代ç é›†å¹¶åˆ é™¤äº†æœªä½¿ç”¨çš„代ç ã€‚ + +基于Yul的优化器è¦å¼ºå¤§å¾—多,因为它å¯ä»¥è·¨å‡½æ•°è°ƒç”¨å·¥ä½œã€‚ +例如,任æ„跳转在Yul中是ä¸å¯èƒ½çš„, +所以有å¯èƒ½è®¡ç®—æ¯ä¸ªå‡½æ•°çš„副作用。å‡è®¾æœ‰ä¸¤ä¸ªå‡½æ•°è°ƒç”¨ï¼Œ +其中第一个ä¸ä¿®æ”¹å­˜å‚¨ï¼Œç¬¬äºŒä¸ªä¿®æ”¹å­˜å‚¨ã€‚ +如果它们的å‚数和返回值ä¸ç›¸äº’ä¾èµ–,我们就å¯ä»¥å¯¹å‡½æ•°è°ƒç”¨é‡æ–°æŽ’åºã€‚ +åŒæ ·åœ°ï¼Œå¦‚果一个函数是没有副作用的,而且其结果是乘以0的,就å¯ä»¥å®Œå…¨åˆ é™¤è¯¥å‡½æ•°è°ƒç”¨ã€‚ + +<<<<<<< HEAD +ç›®å‰ï¼Œå‚æ•° ``--optimize`` 会为生æˆçš„字节ç æ¿€æ´»åŸºäºŽæ“作ç çš„优化器, +并为内部生æˆçš„ Yul 代ç æ¿€æ´» Yul 优化器,例如当使用 ABI coder v2 时。 +您å¯ä»¥ä½¿ç”¨ ``solc --ir optimized --optimize`` æ¥ä¸º Solidity æºç äº§ç”Ÿä¸€ä¸ªä¼˜åŒ–çš„ Yul IR。 +åŒæ ·åœ°ï¼Œæ‚¨å¯ä»¥ä½¿ç”¨ ``solc --strict-assembly --optimize`` æ¥äº§ç”Ÿä¸€ä¸ªç‹¬ç«‹çš„ Yul 模å¼ã€‚ -The opcode-based optimizer applies a set of `simplification rules `_ -to opcodes. It also combines equal code sets and removes unused code. - -The Yul-based optimizer is much more powerful, because it can work across function -calls. For example, arbitrary jumps are not possible in Yul, so it is -possible to compute the side-effects of each function. Consider two function calls, -where the first does not modify storage and the second does modify storage. -If their arguments and return values do not depend on each other, we can reorder -the function calls. Similarly, if a function is -side-effect free and its result is multiplied by zero, you can remove the function -call completely. +.. note:: + `窥视孔(peephole)优化器 `_ + 和内è”器总是默认å¯ç”¨çš„,åªèƒ½é€šè¿‡ :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. @@ -27,71 +56,69 @@ optimized Yul IR for a Solidity source. Similarly, one can use ``solc --strict-a for a stand-alone Yul mode. .. note:: - The `peephole optimizer `_ is always + Some optimizer steps, such as, for example, the `peephole optimizer `_ + and the :ref:`unchecked loop increment optimizer ` are always enabled by default and can only be turned off via the :ref:`Standard JSON `. +.. note:: + An empty optimizer sequence is accepted even without ``--optimize`` in order to fully disable + the user-supplied portion of the Yul :ref:`optimizer sequence `, as by default, + even when the optimizer is not turned on, the :ref:`unused pruner ` step will be run. + You can find more details on both optimizer modules and their optimization steps below. +>>>>>>> english/develop -Benefits of Optimizing Solidity Code +优化Solidity代ç çš„好处 ==================================== -Overall, the optimizer tries to simplify complicated expressions, which reduces both code -size and execution cost, i.e., it can reduce gas needed for contract deployment as well as for external calls made to the contract. -It also specializes or inlines functions. Especially -function inlining is an operation that can cause much bigger code, but it is -often done because it results in opportunities for more simplifications. - +总的æ¥è¯´ï¼Œä¼˜åŒ–器试图简化å¤æ‚的表达å¼ï¼Œä»Žè€Œå‡å°‘代ç å¤§å°å’Œæ‰§è¡Œæˆæœ¬ï¼Œ +也就是说,它å¯ä»¥å‡å°‘部署åˆçº¦ä»¥åŠå¯¹åˆçº¦è¿›è¡Œå¤–部调用所需的气体。 +它还会对函数进行专业化或内è”化优化。特别是当函数内è”一个å¯èƒ½å¯¼è‡´æ›´å¤§çš„代ç æ“作时, +它ç»å¸¸è¿™æ ·åšï¼Œå› ä¸ºè¿™å¯¼è‡´äº†æ›´å¤šç®€åŒ–的机会。 -Differences between Optimized and Non-Optimized Code +优化和éžä¼˜åŒ–代ç ä¹‹é—´çš„差异 ==================================================== -Generally, the most visible difference is that constant expressions are evaluated at compile time. -When it comes to the ASM output, one can also notice a reduction of equivalent or duplicate -code blocks (compare the output of the flags ``--asm`` and ``--asm --optimize``). However, -when it comes to the Yul/intermediate-representation, there can be significant -differences, for example, functions may be inlined, combined, or rewritten to eliminate -redundancies, etc. (compare the output between the flags ``--ir`` and -``--optimize --ir-optimized``). +一般æ¥è¯´ï¼Œæœ€æ˜Žæ˜¾çš„区别是常é‡è¡¨è¾¾å¼åœ¨ç¼–译时被评估。 +当涉åŠåˆ°ASM输出时,人们也å¯ä»¥æ³¨æ„到等价或é‡å¤çš„代ç å—çš„å‡å°‘(比较 ``--asm`` å’Œ ``--asm --optimize`` 标志的输出)。 +然而,当涉åŠåˆ°Yul/中间代表时,å¯èƒ½ä¼šæœ‰æ˜Žæ˜¾çš„差异, +例如,函数å¯èƒ½è¢«å†…è”,åˆå¹¶æˆ–é‡å†™ä»¥æ¶ˆé™¤å†—余等等(比较带有 ``--ir`` å’Œ ``--optimize --ir-optimized`` 标志的输出)。 .. _optimizer-parameter-runs: -Optimizer Parameter Runs +优化器å‚æ•°è¿è¡Œ ======================== -The number of runs (``--optimize-runs``) specifies roughly how often each opcode of the -deployed code will be executed across the life-time of the contract. This means it is a -trade-off parameter between code size (deploy cost) and code execution cost (cost after deployment). -A "runs" parameter of "1" will produce short but expensive code. In contrast, a larger "runs" -parameter will produce longer but more gas efficient code. The maximum value of the parameter -is ``2**32-1``. +è¿è¡Œæ¬¡æ•°ï¼ˆ ``--optimize-runs`` )大致规定了在åˆçº¦æœ‰æ•ˆæœŸå†…, +所部署的代ç çš„æ¯ä¸ªæ“作ç è¢«æ‰§è¡Œçš„频率。 +è¿™æ„味ç€å®ƒæ˜¯ä»£ç å¤§å°ï¼ˆéƒ¨ç½²æˆæœ¬ï¼‰å’Œä»£ç æ‰§è¡Œæˆæœ¬ï¼ˆéƒ¨ç½²åŽçš„æˆæœ¬ï¼‰ä¹‹é—´çš„一个折衷å‚数。 +一个 “è¿è¡Œâ€ å‚数为 “1†将产生简短的åˆçº¦ä½†æ˜‚贵的执行代ç ã€‚相å, +一个较大的 “è¿è¡Œâ€ å‚数将产生较大的åˆçº¦ä½†æ›´çœæ°”体的执行代ç ã€‚ +该å‚数的最大值为 ``2**32-1``。 .. note:: - A common misconception is that this parameter specifies the number of iterations of the optimizer. - This is not true: The optimizer will always run as many times as it can still improve the code. + 一个常è§çš„误解是,这个å‚数指定了优化器的迭代次数。这是ä¸æ­£ç¡®çš„。 + 优化器将始终è¿è¡Œå°½å¯èƒ½å¤šçš„次数æ¥æ”¹è¿›ä»£ç ã€‚ -Opcode-Based Optimizer Module +基于æ“作ç çš„ä¼˜åŒ–å™¨æ¨¡å— ============================= -The opcode-based optimizer module operates on assembly code. It splits the -sequence of instructions into basic blocks at ``JUMPs`` and ``JUMPDESTs``. -Inside these blocks, the optimizer analyzes the instructions and records every modification to the stack, -memory, or storage as an expression which consists of an instruction and -a list of arguments which are pointers to other expressions. - -Additionally, the opcode-based optimizer -uses a component called "CommonSubexpressionEliminator" that, amongst other -tasks, finds expressions that are always equal (on every input) and combines -them into an expression class. It first tries to find each new -expression in a list of already known expressions. If no such matches are found, -it simplifies the expression according to rules like -``constant + constant = sum_of_constants`` or ``X * 1 = X``. Since this is -a recursive process, we can also apply the latter rule if the second factor -is a more complex expression which we know always evaluates to one. - -Certain optimizer steps symbolically track the storage and memory locations. For example, this -information is used to compute Keccak-256 hashes that can be evaluated during compile time. Consider -the sequence: +基于æ“作ç çš„优化器模å—对汇编代ç è¿›è¡Œæ“作。 +它在 ``JUMPs`` å’Œ ``JUMPDESTs`` 之间将指令åºåˆ—分æˆåŸºæœ¬å—。 +在这些å—中,优化器分æžæŒ‡ä»¤ï¼Œå¹¶å°†å¯¹å †æ ˆã€å†…存或存储的æ¯ä¸€æ¬¡ä¿®æ”¹è®°å½•ä¸ºä¸€ä¸ªè¡¨è¾¾å¼ï¼Œ +该表达å¼ç”±ä¸€æ¡æŒ‡ä»¤å’Œä¸€åˆ—å‚数组æˆï¼Œè¿™äº›å‚数是指å‘其他表达å¼çš„指针。 + +此外,基于æ“作ç çš„优化器使用了一个å为 “通用å­è¡¨è¾¾å¼æ¶ˆé™¤å™¨â€ 的组件, +它除其他任务外,还能找到总是相等的表达å¼ï¼ˆåœ¨æ¯ä¸ªè¾“入上), +并将它们åˆå¹¶ä¸ºä¸€ä¸ªè¡¨è¾¾å¼ç±»ã€‚它首先å°è¯•åœ¨ä¸€ä¸ªå·²ç»çŸ¥é“的表达å¼åˆ—表中找到æ¯ä¸ªæ–°çš„表达å¼ã€‚ +如果没有找到这样的匹é…, +å®ƒå°±æ ¹æ® ``constant + constant = sum_of_constants`` 或 ``X * 1 = X`` 这样的规则简化表达å¼ã€‚ +由于这是一个递归过程,如果第二个因素是一个更å¤æ‚的表达å¼ï¼Œå¹¶ä¸”知é“这个表达å¼çš„值总是为1,我们也å¯ä»¥åº”用åŽä¸€ä¸ªè§„则。 + +æŸäº›ä¼˜åŒ–器步骤象å¾æ€§åœ°è·Ÿè¸ªå­˜å‚¨å’Œå†…å­˜ä½ç½®ã€‚例如, +这些信æ¯è¢«ç”¨æ¥è®¡ç®—Keccak-256哈希值,å¯ä»¥åœ¨ç¼–译时进行评估。 +考虑一下这个åºåˆ—: .. code-block:: none @@ -103,7 +130,7 @@ the sequence: MSTORE KECCAK256 -or the equivalent Yul +或ç€ç­‰åŒäºŽYul为 .. code-block:: yul @@ -111,107 +138,96 @@ or the equivalent Yul mstore(x, 100) let value := keccak256(x, 32) -In this case, the optimizer tracks the value at a memory location ``calldataload(0)`` and then -realizes that the Keccak-256 hash can be evaluated at compile time. This only works if there is no -other instruction that modifies memory between the ``mstore`` and ``keccak256``. So if there is an -instruction that writes to memory (or storage), then we need to erase the knowledge of the current -memory (or storage). There is, however, an exception to this erasing, when we can easily see that -the instruction doesn't write to a certain location. +在这ç§æƒ…况下,优化器跟踪ä½äºŽå†…å­˜ä½ç½® ``calldataload(0)`` 的值, +然åŽæ„识到Keccak-256哈希值å¯ä»¥åœ¨ç¼–译时被评估。 +è¿™åªæœ‰åœ¨ ``mstore`` å’Œ ``keccak256`` 之间没有其他指令修改内存时æ‰æœ‰æ•ˆã€‚ +因此,如果有一æ¡æŒ‡ä»¤å†™åˆ°å†…存(或存储),那么我们需è¦æ“¦é™¤å¯¹å½“å‰å†…存(或存储)的记忆。 +然而,这ç§æ“¦é™¤æœ‰ä¸€ä¸ªä¾‹å¤–,当我们å¯ä»¥å¾ˆå®¹æ˜“地看到指令没有写到æŸä¸ªä½ç½®ã€‚ -For example, +示例, .. code-block:: yul let x := calldataload(0) mstore(x, 100) - // Current knowledge memory location x -> 100 + // 已知当å‰å†…å­˜ä½ç½®x -> 100 let y := add(x, 32) - // Does not clear the knowledge that x -> 100, since y does not write to [x, x + 32) + // 没有清除 x -> 100 的记忆,因为y并没有写到[x,x+32)。 mstore(y, 200) - // This Keccak-256 can now be evaluated + // 现在å¯ä»¥å¯¹è¿™ä¸ªKeccak-256进行计算了 let value := keccak256(x, 32) -Therefore, modifications to storage and memory locations, of say location ``l``, must erase -knowledge about storage or memory locations which may be equal to ``l``. More specifically, for -storage, the optimizer has to erase all knowledge of symbolic locations, that may be equal to ``l`` -and for memory, the optimizer has to erase all knowledge of symbolic locations that may not be at -least 32 bytes away. If ``m`` denotes an arbitrary location, then this decision on erasure is done -by computing the value ``sub(l, m)``. For storage, if this value evaluates to a literal that is -non-zero, then the knowledge about ``m`` will be kept. For memory, if the value evaluates to a -literal that is between ``32`` and ``2**256 - 32``, then the knowledge about ``m`` will be kept. In -all other cases, the knowledge about ``m`` will be erased. - -After this process, we know which expressions have to be on the stack at -the end, and have a list of modifications to memory and storage. This information -is stored together with the basic blocks and is used to link them. Furthermore, -knowledge about the stack, storage and memory configuration is forwarded to -the next block(s). - -If we know the targets of all ``JUMP`` and ``JUMPI`` instructions, -we can build a complete control flow graph of the program. If there is only -one target we do not know (this can happen as in principle, jump targets can -be computed from inputs), we have to erase all knowledge about the input state -of a block as it can be the target of the unknown ``JUMP``. If the opcode-based -optimizer module finds a ``JUMPI`` whose condition evaluates to a constant, it transforms it -to an unconditional jump. - -As the last step, the code in each block is re-generated. The optimizer creates -a dependency graph from the expressions on the stack at the end of the block, -and it drops every operation that is not part of this graph. It generates code -that applies the modifications to memory and storage in the order they were -made in the original code (dropping modifications which were found not to be -needed). Finally, it generates all values that are required to be on the -stack in the correct place. - -These steps are applied to each basic block and the newly generated code -is used as replacement if it is smaller. If a basic block is split at a -``JUMPI`` and during the analysis, the condition evaluates to a constant, -the ``JUMPI`` is replaced based on the value of the constant. Thus code like +因此,对存储和内存ä½ç½®çš„修改,比如说ä½ç½® ``l``, +必须擦除关于å¯èƒ½ç­‰äºŽ ``l`` 的存储或内存ä½ç½®çš„记忆。更具体地说, +对于存储,优化器必须删除所有å¯èƒ½ç­‰äºŽ ``l`` 的符å·ä½ç½®çš„记忆, +对于内存,优化器必须删除所有å¯èƒ½ä¸è¶…过32字节的符å·ä½ç½®çš„记忆。 +如果 ``m`` 表示一个任æ„çš„ä½ç½®ï¼Œé‚£ä¹ˆè¿™ä¸ªæ“¦é™¤çš„决定是通过计算 ``sub(l, m)`` 的值æ¥å®Œæˆã€‚ +对于存储,如果这个值被评估为一个éžé›¶çš„值,那么关于 ``m`` 的记忆将被ä¿ç•™ã€‚ +对于内存,如果这个值被评估为一个介于 ``32`` å’Œ ``2**256 - 32`` 之间的值,那么关于 ``m`` 的记忆将被ä¿ç•™ã€‚ +在所有其他情况下,关于 ``m`` 的记忆将被删除。 + +并且有一个对内存和存储的修改列表。 +这些信æ¯ä¸ŽåŸºæœ¬ä»£ç å—一起存储并用æ¥é“¾æŽ¥å®ƒä»¬ã€‚此外, +关于堆栈ã€å­˜å‚¨å’Œå†…å­˜é…置的记忆被转å‘给下一个(几个)å—。 + +如果我们知é“所有 ``JUMP`` å’Œ ``JUMPI`` 指令的目标, +我们就å¯ä»¥æž„建一个完整的程åºæµç¨‹å›¾ã€‚ +如果åªæœ‰ä¸€ä¸ªæˆ‘们ä¸çŸ¥é“的目标(原则上å¯èƒ½å‘生,跳转目标å¯ä»¥åŸºäºŽè¾“å…¥æ¥è®¡ç®—), +我们必须消除关于代ç å—输入状æ€çš„所有信æ¯ï¼Œå› ä¸ºå®ƒå¯èƒ½æ˜¯æœªçŸ¥çš„ ``JUMP`` 目标。 +如果一个 ``JUMPI`` çš„æ¡ä»¶ç­‰äºŽä¸€ä¸ªå¸¸é‡ï¼Œå®ƒå°†è¢«è½¬æ¢ä¸ºæ— æ¡ä»¶è·³è½¬ã€‚ + +作为最åŽä¸€æ­¥ï¼Œæ¯ä¸ªå—中的代ç éƒ½ä¼šè¢«å®Œå…¨é‡æ–°ç”Ÿæˆã€‚ +然åŽä¼˜åŒ–器会从代ç å—的结尾处在栈上的表达å¼å¼€å§‹åˆ›å»ºä¾èµ–关系图, +且ä¸æ˜¯è¯¥å›¾ç»„æˆéƒ¨åˆ†çš„æ¯ä¸ªæ“作都会被丢弃。 +这样生æˆçš„代ç å°†æŒ‰ç…§åŽŸå§‹ä»£ç ä¸­çš„顺åºå¯¹å†…存和存储进行修改(èˆå¼ƒä¸éœ€è¦çš„修改)。 +最åŽï¼Œå®ƒç”Ÿæˆäº†æ‰€æœ‰éœ€è¦åœ¨å †æ ˆä¸­çš„正确ä½ç½®çš„值。 + +这些步骤适用于æ¯ä¸ªåŸºæœ¬ä»£ç å—,如果代ç å—较å°ï¼Œåˆ™æ–°ç”Ÿæˆçš„代ç å°†ç”¨ä½œæ›¿æ¢ã€‚ +如果一个基本代ç å—在 ``JUMPI`` 处被分割,且在分æžè¿‡ç¨‹ä¸­è¢«è¯„估为一个常数, +则会根æ®å¸¸é‡çš„值æ¥æ›¿æ¢ ``JUMPI``,因此,类似于 .. code-block:: solidity uint x = 7; data[7] = 9; - if (data[x] != x + 2) // this condition is never true + if (data[x] != x + 2) // 这个æ¡ä»¶æ°¸è¿œä¸ä¼šæ˜¯çœŸçš„ return 2; else return 1; -simplifies to this: +简化为这样: .. code-block:: solidity data[7] = 9; return 1; -Simple Inlining +简å•å†…è” --------------- -Since Solidity version 0.8.2, there is another optimizer step that replaces certain -jumps to blocks containing "simple" instructions ending with a "jump" by a copy of these instructions. -This corresponds to inlining of simple, small Solidity or Yul functions. In particular, the sequence -``PUSHTAG(tag) JUMP`` may be replaced, whenever the ``JUMP`` is marked as jump "into" a -function and behind ``tag`` there is a basic block (as described above for the -"CommonSubexpressionEliminator") that ends in another ``JUMP`` which is marked as a jump -"out of" a function. +从Solidity 0.8.2版本开始,有å¦ä¸€ä¸ªä¼˜åŒ–步骤, +它用这些指令的拷è´æ¥æ›¿æ¢æŸäº›åŒ…å«ä»¥ “跳转†结æŸçš„ “简å•â€ 指令的å—的跳转。 +这相当于对简å•çš„ã€å°çš„Solidity或Yul函数进行内è”。特别是, +``PUSHTAG(tag) JUMP`` åºåˆ—å¯ä»¥è¢«æ›¿æ¢ï¼Œåªè¦ ``JUMP`` 被标记为 "进入" 一个函数的跳转, +并且在 ``tag`` åŽé¢æœ‰ä¸€ä¸ªåŸºæœ¬å—(如上é¢æè¿°çš„ “通用å­è¡¨è¾¾å¼æ¶ˆé™¤å™¨â€ï¼‰ï¼Œ +它以å¦ä¸€ä¸ª ``JUMP`` 结æŸï¼Œè¢«æ ‡è®°ä¸º “离开†一个函数的跳转。 + -In particular, consider the following prototypical example of assembly generated for a -call to an internal Solidity function: +特别是,考虑以下为调用内部Solidity函数而生æˆçš„汇编的原型例å­: .. code-block:: text tag_return tag_f - jump // in + jump // 从此进入 tag_return: ...opcodes after call to f... tag_f: ...body of function f... - jump // out + jump // 从此退出 -As long as the body of the function is a continuous basic block, the "Inliner" can replace ``tag_f jump`` by -the block at ``tag_f`` resulting in: +åªè¦å‡½æ•°çš„主体是一个连续的基本å—,“内蔆就å¯ä»¥ç”¨ä½äºŽ ``tag_f`` 处的å—æ¥ä»£æ›¿ ``tag_f jump`` ,结果是: .. code-block:: text @@ -223,10 +239,9 @@ the block at ``tag_f`` resulting in: tag_f: ...body of function f... - jump // out + jump // 从此退出 -Now ideally, the other optimizer steps described above will result in the return tag push being moved -towards the remaining jump resulting in: +现在,ç†æƒ³æƒ…况下,上述的其他优化器步骤将导致返回标签的推é€è¢«ç§»å‘剩余的跳转,从而导致: .. code-block:: text @@ -238,59 +253,63 @@ towards the remaining jump resulting in: tag_f: ...body of function f... - jump // out + jump // 从此退出 -In this situation the "PeepholeOptimizer" will remove the return jump. Ideally, all of this can be done -for all references to ``tag_f`` leaving it unused, s.t. it can be removed, yielding: +在这ç§æƒ…况下,“窥视孔优化器(PeepholeOptimizer)†将删除返回跳转。ç†æƒ³æƒ…况下, +所有对 ``tag_f`` 的引用都å¯ä»¥è¿™æ ·åšï¼Œè€Œä¸ä½¿ç”¨å®ƒï¼Œç‰¹åˆ«å¤„ç†çš„è¯ï¼Œå®ƒä¹Ÿå¯ä»¥è¢«ç§»é™¤ï¼š .. code-block:: text ...body of function f... ...opcodes after call to f... -So the call to function ``f`` is inlined and the original definition of ``f`` can be removed. +因此,对函数 ``f`` 的调用是内è”的,å¯ä»¥åˆ é™¤ ``f`` 的原始定义。 -Inlining like this is attempted, whenever a heuristics suggests that inlining is cheaper over the lifetime of a -contract than not inlining. This heuristics depends on the size of the function body, the -number of other references to its tag (approximating the number of calls to the function) and -the expected number of executions of the contract (the global optimizer parameter "runs"). +无论何时,åªè¦å¯å‘å¼ç®—法表明,在åˆåŒçš„生命周期内,内è”比ä¸å†…è”更便宜,就会å°è¯•è¿™æ ·çš„内è”。 +è¿™ç§å¯å‘å¼æ–¹æ³•å–决于函数体的大å°ã€å¯¹å…¶æ ‡è®°çš„其他引用的数é‡ï¼ˆè¿‘似于函数调用的数é‡ï¼‰ +以åŠåˆçº¦çš„预期执行次数(全局优化器å‚æ•° "runs")。 -Yul-Based Optimizer Module +基于Yulçš„ä¼˜åŒ–å™¨æ¨¡å— ========================== -The Yul-based optimizer consists of several stages and components that all transform -the AST in a semantically equivalent way. The goal is to end up either with code -that is shorter or at least only marginally longer but will allow further -optimization steps. +基于Yul的优化器由几个阶段和组件组æˆï¼Œå®ƒä»¬éƒ½ä»¥è¯­ä¹‰ç­‰æ•ˆçš„æ–¹å¼è½¬æ¢AST。 +我们的目标是,最终的代ç è¦ä¹ˆæ›´çŸ­ï¼Œè¦ä¹ˆè‡³å°‘略长,但å…许进一步的优化步骤。 .. warning:: - Since the optimizer is under heavy development, the information here might be outdated. - If you rely on a certain functionality, please reach out to the team directly. + 由于优化器正在进行大é‡å¼€å‘,这里的信æ¯å¯èƒ½å·²ç»è¿‡æ—¶ã€‚ + 如果您ä¾èµ–æŸé¡¹åŠŸèƒ½ï¼Œè¯·ç›´æŽ¥è”系团队。 -The optimizer currently follows a purely greedy strategy and does not do any -backtracking. +优化器目å‰éµå¾ªçš„是一ç§çº¯ç²¹çš„贪婪策略,ä¸åšä»»ä½•å›žæº¯ã€‚ -All components of the Yul-based optimizer module are explained below. -The following transformation steps are the main components: +下é¢å°†è§£é‡ŠåŸºäºŽYul的优化器模å—的所有组件。 +以下的转æ¢æ­¥éª¤æ˜¯ä¸»è¦çš„组æˆéƒ¨åˆ†ï¼š +<<<<<<< HEAD +- SSAè½¬æ¢ +- 通用å­è¡¨è¾¾å¼æ¶ˆé™¤å™¨ +- 表达å¼ç®€åŒ–器 +- 冗余赋值消除器 +- å®Œå…¨å†…è” +======= - SSA Transform - Common Subexpression Eliminator - Expression Simplifier -- Redundant Assign Eliminator +- Unused Assign Eliminator - Full Inliner +>>>>>>> english/develop .. _optimizer-steps: -Optimizer Steps +优化器的步骤 --------------- -This is a list of all steps the Yul-based optimizer sorted alphabetically. You can find more information -on the individual steps and their sequence below. +这是按字æ¯é¡ºåºæŽ’列的基于Yul的优化器的所有步骤的列表。 +您å¯ä»¥åœ¨ä¸‹é¢æ‰¾åˆ°æ›´å¤šå…³äºŽå„个步骤和它们的顺åºçš„ä¿¡æ¯ã€‚ ============ =============================== -Abbreviation Full name +缩略语 全称 ============ =============================== ``f`` :ref:`block-flattener` ``l`` :ref:`circular-reference-pruner` @@ -315,109 +334,118 @@ Abbreviation Full name ``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` ``t`` :ref:`structural-simplifier` +``r`` :ref:`unused-assign-eliminator` ``p`` :ref:`unused-function-parameter-pruner` ``S`` :ref:`unused-store-eliminator` ``u`` :ref:`unused-pruner` ``d`` :ref:`var-decl-initializer` ============ =============================== -Some steps depend on properties ensured by ``BlockFlattener``, ``FunctionGrouper``, ``ForLoopInitRewriter``. -For this reason the Yul optimizer always applies them before applying any steps supplied by the user. +一些步骤ä¾èµ–于 ``BlockFlattener``, ``FunctionGrouper``, ``ForLoopInitRewriter`` 所ä¿è¯çš„属性。 +由于这个原因,Yul 优化器总是在应用用户æ供的任何步骤之å‰åº”用它们。 +<<<<<<< HEAD +基于推ç†çš„简化器(ReasoningBasedSimplifier)是一个优化器步骤, +ç›®å‰åœ¨é»˜è®¤æ­¥éª¤é›†ä¸­æ²¡æœ‰å¯ç”¨ã€‚它使用一个 SMT 求解器æ¥ç®€åŒ–算术表达å¼å’Œå¸ƒå°”æ¡ä»¶ã€‚ +此外,它还没有得到彻底的测试或验è¯ï¼Œå¯èƒ½ä¼šäº§ç”Ÿä¸å¯å¤çŽ°çš„结果,所以请谨慎使用! +======= +.. _selecting-optimizations: +>>>>>>> english/develop -Selecting Optimizations +选择优化方案 ----------------------- -By default the optimizer applies its predefined sequence of optimization steps to the generated assembly. -You can override this sequence and supply your own using the ``--yul-optimizations`` option: +默认情况下,优化器将其预定义的优化步骤åºåˆ—应用于生æˆçš„程åºé›†ã€‚ +您å¯ä»¥ä½¿ç”¨ ``--yul-optimizations`` 选项æ¥è¦†ç›–这个åºåˆ—并æ供您自己的åºåˆ—: .. code-block:: bash solc --optimize --ir-optimized --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul:fDnTOcmu' -The order of steps is significant and affects the quality of the output. -Moreover, applying a step may uncover new optimization opportunities for others that were already applied, -so repeating steps is often beneficial. +步骤的顺åºå¾ˆé‡è¦ï¼Œä¼šå½±å“到输出的质é‡ã€‚ +此外,应用一个步骤å¯èƒ½ä¸ºå…¶ä»–å·²ç»åº”用的步骤å‘现新的优化机会。因此,é‡å¤æ­¥éª¤å¾€å¾€æ˜¯æœ‰ç›Šçš„。 -The sequence inside ``[...]`` will be applied multiple times in a loop until the Yul code -remains unchanged or until the maximum number of rounds (currently 12) has been reached. -Brackets (``[]``) may be used multiple times in a sequence, but can not be nested. +``[...]`` 里é¢çš„åºåˆ—将在一个循环中多次应用, +直到 Yul 代ç ä¿æŒä¸å˜æˆ–达到最大轮数(目å‰æ˜¯12)。 +方括å·ï¼ˆ ``[]`` )å¯ä»¥åœ¨ä¸€ä¸ªåºåˆ—中多次使用,但ä¸èƒ½åµŒå¥—。 -An important thing to note, is that there are some hardcoded steps that are always run before and after the -user-supplied sequence, or the default sequence if one was not supplied by the user. +需è¦æ³¨æ„的一件事是,有一些硬编ç çš„步骤总是在用户æ供的åºåˆ—之å‰å’Œä¹‹åŽè¿è¡Œï¼Œ +如果用户没有æä¾›åºåˆ—,则是默认åºåˆ—。 -The cleanup sequence delimiter ``:`` is optional, and is used to supply a custom cleanup sequence -in order to replace the default one. If omitted, the optimizer will simply apply the default cleanup -sequence. In addition, the delimiter may be placed at the beginning of the user-supplied sequence, -which will result in the optimization sequence being empty, whereas conversely, if placed at the end of -the sequence, will be treated as an empty cleanup sequence. +清ç†åºåˆ—分界符 ``:`` 是å¯é€‰çš„,用于æ供一个自定义的清ç†åºåˆ—, +以å–代默认åºåˆ—。如果çœç•¥ï¼Œä¼˜åŒ–器将简å•åœ°åº”用默认的清ç†åºåˆ—。 +此外,定界符å¯ä»¥æ”¾åœ¨ç”¨æˆ·æ供的åºåˆ—的开头, +这将导致优化åºåˆ—为空,å之,如果放在åºåˆ—的末尾, +将被视为一个空的清ç†åºåˆ—。 -Preprocessing +é¢„å¤„ç† ------------- -The preprocessing components perform transformations to get the program -into a certain normal form that is easier to work with. This normal -form is kept during the rest of the optimization process. +预处ç†ç»„件进行转æ¢ï¼Œä½¿ç¨‹åºå˜æˆæŸç§æ›´å®¹æ˜“æ“作的正常形å¼ã€‚ +è¿™ç§æ­£å¸¸å½¢å¼åœ¨å‰©ä¸‹çš„优化过程中被ä¿ç•™ã€‚ .. _disambiguator: -Disambiguator +消歧器 ^^^^^^^^^^^^^ -The disambiguator takes an AST and returns a fresh copy where all identifiers have -unique names in the input AST. This is a prerequisite for all other optimizer stages. -One of the benefits is that identifier lookup does not need to take scopes into account -which simplifies the analysis needed for other steps. +消歧器获å–AST并返回一个新拷è´ï¼Œå…¶ä¸­æ‰€æœ‰æ ‡è¯†ç¬¦åœ¨è¾“å…¥AST中都有唯一的å称。 +这是所有其他优化器阶段的先决æ¡ä»¶ã€‚ +其中一个好处是,标识符查找ä¸éœ€è¦è€ƒè™‘作用域, +这简化了其他步骤所需的分æžã€‚ -All subsequent stages have the property that all names stay unique. This means if -a new identifier needs to be introduced, a new unique name is generated. +所有åŽç»­é˜¶æ®µéƒ½æœ‰ä¸€ä¸ªå±žæ€§ï¼Œå³æ‰€æœ‰çš„å字都ä¿æŒå”¯ä¸€ã€‚ +è¿™æ„味ç€å¦‚果需è¦å¼•å…¥ä¸€ä¸ªæ–°çš„标识符,就会产生一个新的唯一å称。 .. _function-hoister: -FunctionHoister +函数æå‡å™¨ ^^^^^^^^^^^^^^^ -The function hoister moves all function definitions to the end of the topmost block. This is -a semantically equivalent transformation as long as it is performed after the -disambiguation stage. The reason is that moving a definition to a higher-level block cannot decrease -its visibility and it is impossible to reference variables defined in a different function. +函数æå‡å™¨å°†æ‰€æœ‰çš„函数定义移到最上é¢çš„å—的末尾。 +åªè¦åœ¨æ¶ˆæ­§ä¹‰é˜¶æ®µä¹‹åŽè¿›è¡Œï¼Œè¿™å°±æ˜¯ä¸€ä¸ªè¯­ä¹‰ä¸Šçš„等价转æ¢ã€‚ +原因是,将一个定义移到更高层次的å—中ä¸èƒ½é™ä½Žå…¶å¯è§æ€§ï¼Œ +而且ä¸å¯èƒ½å¼•ç”¨åœ¨ä¸åŒå‡½æ•°ä¸­å®šä¹‰çš„å˜é‡ã€‚ -The benefit of this stage is that function definitions can be looked up more easily -and functions can be optimized in isolation without having to traverse the AST completely. +这个阶段的好处是,å¯ä»¥æ›´å®¹æ˜“地查找函数定义, +并且å¯ä»¥å­¤ç«‹åœ°ä¼˜åŒ–函数,而ä¸å¿…完全é历AST。 .. _function-grouper: -FunctionGrouper +函数分组器 ^^^^^^^^^^^^^^^ -The function grouper has to be applied after the disambiguator and the function hoister. -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. +函数分组器必须在消歧义器和函数æå‡å™¨ä¹‹åŽåº”用。 +它的作用是将所有ä¸æ˜¯å‡½æ•°å®šä¹‰çš„最上é¢çš„元素移到一个å•ä¸€çš„å—中, +这个å—是根å—的第一个语å¥ã€‚ -After this step, a program has the following normal form: +在这一步之åŽï¼Œä¸€ä¸ªç¨‹åºå…·æœ‰ä»¥ä¸‹æ­£å¸¸å½¢å¼ï¼š .. code-block:: text { I F... } -Where ``I`` is a (potentially empty) block that does not contain any function definitions (not even recursively) -and ``F`` is a list of function definitions such that no function contains a function definition. +其中 ``I`` 是一个(å¯èƒ½æ˜¯ç©ºçš„)区å—,ä¸åŒ…å«ä»»ä½•å‡½æ•°å®šä¹‰ï¼ˆç”šè‡³æ˜¯é€’归的), +``F`` 是一个函数定义的列表,使得没有一个函数包å«å‡½æ•°å®šä¹‰ã€‚ -The benefit of this stage is that we always know where the list of function begins. +这个阶段的好处是,我们总是知é“功能列表的开始ä½ç½®ã€‚ .. _for-loop-condition-into-body: -ForLoopConditionIntoBody +循环æ¡ä»¶è¿›å…¥æ­£æ–‡ ^^^^^^^^^^^^^^^^^^^^^^^^ -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). +è¿™ç§è½¬æ¢å°†for循环的循环迭代æ¡ä»¶ç§»åŠ¨åˆ°å¾ªçŽ¯ä½“中。 +我们需è¦è¿™ç§è½¬æ¢ï¼Œå› ä¸º :ref:`expression-splitter` å°†ä¸é€‚用于迭代æ¡ä»¶è¡¨è¾¾å¼ï¼ˆä»¥ä¸‹ç¤ºä¾‹ä¸­çš„ ``C``)。 .. code-block:: text @@ -425,7 +453,7 @@ apply to iteration condition expressions (the ``C`` in the following example). Body... } -is transformed to +被转化为 .. code-block:: text @@ -434,16 +462,15 @@ is transformed to Body... } -This transformation can also be useful when paired with ``LoopInvariantCodeMotion``, since -invariants in the loop-invariant conditions can then be taken outside the loop. +当与 ``循环ä¸å˜ä»£ç æ¨¡å¼`` æ­é…时,这ç§è½¬æ¢ä¹Ÿæ˜¯æœ‰ç”¨çš„,因为循环ä¸å˜æ¡ä»¶ä¸­çš„ä¸å˜é‡å¯ä»¥åœ¨å¾ªçŽ¯ä¹‹å¤–进行。 + .. _for-loop-init-rewriter: -ForLoopInitRewriter +循环åˆå§‹é‡å†™å™¨ ^^^^^^^^^^^^^^^^^^^ -This transformation moves the initialization part of a for-loop to before -the loop: +è¿™ç§è½¬æ¢å°†for-loopçš„åˆå§‹åŒ–部分移到循环之å‰ï¼š .. code-block:: text @@ -451,7 +478,7 @@ the loop: Body... } -is transformed to +被转化为 .. code-block:: text @@ -460,31 +487,35 @@ is transformed to Body... } +<<<<<<< HEAD +这简化了其余的优化过程, +因为我们å¯ä»¥å¿½ç•¥for循环åˆå§‹åŒ–å—çš„å¤æ‚范围规则。 +======= This eases the rest of the optimization process because we can ignore -the complicated scoping rules of the for loop initialisation block. +the complicated scoping rules of the for loop initialization block. +>>>>>>> english/develop .. _var-decl-initializer: -VarDeclInitializer +åˆå§‹åŒ–ç¨‹åº ^^^^^^^^^^^^^^^^^^ -This step rewrites variable declarations so that all of them are initialized. -Declarations like ``let x, y`` are split into multiple declaration statements. +这一步é‡å†™äº†å˜é‡å£°æ˜Žï¼Œä½¿æ‰€æœ‰çš„å˜é‡éƒ½è¢«åˆå§‹åŒ–。 +åƒ ``let x, y`` 这样的声明被分割æˆå¤šä¸ªå£°æ˜Žè¯­å¥ã€‚ -Only supports initializing with the zero literal for now. +ç›®å‰åªæ”¯æŒç”¨é›¶å€¼åˆå§‹åŒ–。 -Pseudo-SSA Transformation +伪SSAè½¬æ¢ ------------------------- -The purpose of this components is to get the program into a longer form, -so that other components can more easily work with it. The final representation -will be similar to a static-single-assignment (SSA) form, with the difference -that it does not make use of explicit "phi" functions which combines the values -from different branches of control flow because such a feature does not exist -in the Yul language. Instead, when control flow merges, if a variable is re-assigned -in one of the branches, a new SSA variable is declared to hold its current value, -so that the following expressions still only need to reference SSA variables. +这个组件的目的是让程åºå˜æˆä¸€ä¸ªè¾ƒé•¿çš„å½¢å¼ï¼Œ +以便其他组件能够更容易地与之é…åˆã€‚ +最终的表现形å¼å°†ç±»ä¼¼äºŽé™æ€å•ä¸€èµ‹å€¼ï¼ˆSSA)的形å¼ï¼Œä¸åŒçš„是, +它ä¸ä½¿ç”¨æ˜Žç¡®çš„ "phi" 函数æ¥åˆå¹¶æ¥è‡ªæŽ§åˆ¶æµä¸åŒåˆ†æ”¯çš„值, +因为Yul语言中ä¸å­˜åœ¨è¿™æ ·çš„功能。相å,当控制æµåˆå¹¶æ—¶ï¼Œ +如果一个å˜é‡åœ¨å…¶ä¸­ä¸€ä¸ªåˆ†æ”¯ä¸­è¢«é‡æ–°èµ‹å€¼ï¼Œå°±ä¼šå£°æ˜Žä¸€ä¸ªæ–°çš„SSAå˜é‡æ¥ä¿æŒå®ƒçš„当å‰å€¼ï¼Œ +这样,下é¢çš„表达å¼ä»ç„¶åªéœ€è¦å¼•ç”¨SSAå˜é‡ã€‚ -An example transformation is the following: +下é¢æ˜¯ä¸€ä¸ªè½¬æ¢çš„例å­ï¼š .. code-block:: yul @@ -499,8 +530,7 @@ An example transformation is the following: } -When all the following transformation steps are applied, the program will look -as follows: +应用以下所有转æ¢æ­¥éª¤åŽï¼Œç¨‹åºå°†å¦‚下所示: .. code-block:: yul @@ -527,30 +557,27 @@ as follows: sstore(a_13, _8) } -Note that the only variable that is re-assigned in this snippet is ``b``. -This re-assignment cannot be avoided because ``b`` has different values -depending on the control flow. All other variables never change their -value once they are defined. The advantage of this property is that -variables can be freely moved around and references to them -can be exchanged by their initial value (and vice-versa), -as long as these values are still valid in the new context. +请注æ„,此代ç æ®µä¸­å”¯ä¸€é‡æ–°åˆ†é…çš„å˜é‡æ˜¯ ``b``。 +无法é¿å…è¿™ç§é‡æ–°åˆ†é…,因为根æ®æŽ§åˆ¶æµï¼Œ ``b`` 具有ä¸åŒçš„值。 +所有其他å˜é‡åœ¨å®šä¹‰åŽéƒ½ä¸ä¼šæ”¹å˜å…¶å€¼ã€‚ +该属性的优点是,å˜é‡å¯ä»¥è‡ªç”±ç§»åŠ¨ï¼Œ +对它们的引用å¯ä»¥é€šè¿‡å®ƒä»¬çš„åˆå§‹å€¼è¿›è¡Œäº¤æ¢ï¼ˆå之亦然), +åªè¦è¿™äº›å€¼åœ¨æ–°ä¸Šä¸‹æ–‡ä¸­ä»ç„¶æœ‰æ•ˆã€‚ -Of course, the code here is far from being optimized. To the contrary, it is much -longer. The hope is that this code will be easier to work with and furthermore, -there are optimizer steps that undo these changes and make the code more -compact again at the end. +当然,这里的代ç è¿œè¿œæ²¡æœ‰å¾—到优化。相å,它è¦é•¿å¾—多。 +我们希望这段代ç æ›´å®¹æ˜“使用,此外,还有一些优化器步骤å¯ä»¥æ’¤é”€è¿™äº›æ›´æ”¹ï¼Œ +并在最åŽä½¿ä»£ç æ›´åŠ ç´§å‡‘。 .. _expression-splitter: -ExpressionSplitter +表达å¼æ‹†åˆ†å™¨ ^^^^^^^^^^^^^^^^^^ -The expression splitter turns expressions like ``add(mload(0x123), mul(mload(0x456), 0x20))`` -into a sequence of declarations of unique variables that are assigned sub-expressions -of that expression so that each function call has only variables -as arguments. +表达å¼æ‹†åˆ†å™¨å°†è¯¸å¦‚ ``add(mload(0x123), mul(mload(0x456), 0x20))`` +这样的表达å¼å˜æˆä¸€è¿žä¸²ç‹¬ç‰¹å˜é‡çš„声明,这些å˜é‡è¢«åˆ†é…给该表达å¼çš„å­è¡¨è¾¾å¼ï¼Œ +这样æ¯ä¸ªå‡½æ•°è°ƒç”¨åªæœ‰å˜é‡ä½œä¸ºå‚数。 -The above would be transformed into +上述内容将被转化为 .. code-block:: yul @@ -564,33 +591,34 @@ The above would be transformed into let z := add(_6, _4) } -Note that this transformation does not change the order of opcodes or function calls. +请注æ„,这ç§è½¬æ¢å¹¶ä¸æ”¹å˜æ“作ç æˆ–函数调用的顺åºã€‚ -It is not applied to loop iteration-condition, because the loop control flow does not allow -this "outlining" of the inner expressions in all cases. We can sidestep this limitation by applying -:ref:`for-loop-condition-into-body` to move the iteration condition into loop body. +它ä¸é€‚用于循环迭代æ¡ä»¶ï¼Œå› ä¸ºå¾ªçŽ¯æŽ§åˆ¶æµä¸å…许在所有情况下 “概述†内部表达å¼ã€‚ +我们å¯ä»¥é€šè¿‡åº”用 :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 -The benefits of this form are that it is much easier to re-order the sequence of opcodes -and it is also easier to perform function call inlining. Furthermore, it is simpler -to replace individual parts of expressions or re-organize the "expression tree". -The drawback is that such code is much harder to read for humans. +è¿™ç§å½¢å¼çš„好处是,更容易é‡æ–°æŽ’列æ“作ç åºåˆ—, +也更容易执行函数调用内è”。此外, +也更简å•åœ°æ›¿æ¢è¡¨è¾¾å¼çš„å„个部分或é‡æ–°ç»„织 “表达å¼æ ‘â€ã€‚ +缺点是这样的代ç å¯¹æˆ‘们æ¥è¯´æ›´éš¾é˜…读。 .. _SSA-transform: -SSATransform +SSAè½¬æ¢ ^^^^^^^^^^^^ -This stage tries to replace repeated assignments to -existing variables by declarations of new variables as much as -possible. -The reassignments are still there, but all references to the -reassigned variables are replaced by the newly declared variables. +这个阶段尽å¯èƒ½åœ°ç”¨æ–°å˜é‡çš„声明æ¥å–代对现有å˜é‡çš„é‡å¤èµ‹å€¼ã€‚ +é‡æ–°èµ‹å€¼ä»ç„¶å­˜åœ¨ï¼Œä½†æ˜¯æ‰€æœ‰å¯¹é‡æ–°èµ‹å€¼çš„å˜é‡çš„引用都被新声明的å˜é‡æ‰€å–代。 -Example: +示例: .. code-block:: yul @@ -600,7 +628,7 @@ Example: a := 3 } -is transformed to +被转化为 .. code-block:: yul @@ -612,40 +640,43 @@ is transformed to a := a_3 } -Exact semantics: +精确语义: -For any variable ``a`` that is assigned to somewhere in the code -(variables that are declared with value and never re-assigned -are not modified) perform the following transforms: +对于任何在代ç ä¸­è¢«åˆ†é…到æŸå¤„çš„å˜é‡ ``a`` +(带值声明且从未é‡æ–°åˆ†é…çš„å˜é‡ä¸è¢«ä¿®æ”¹ï¼‰ï¼Œæ‰§è¡Œä»¥ä¸‹è½¬æ¢: -- replace ``let a := v`` by ``let a_i := v let a := a_i`` -- replace ``a := v`` by ``let a_i := v a := a_i`` where ``i`` is a number such that ``a_i`` is yet unused. +- å°† ``let a := v`` 替æ¢ä¸º ``let a_i := v let a := a_i`` +- å°† ``a := v`` 替æ¢ä¸º ``let a_i := v a := a_i``, 其中 ``i`` 是一个数字,使得 ``a_i`` 尚未使用。 -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/ForLoop/Block statement. +此外,总是记录用于 ``a`` çš„ ``i`` 的当å‰å€¼ï¼Œå¹¶ç”¨ ``a_i`` 替æ¢å¯¹ ``a`` çš„æ¯æ¬¡å¼•ç”¨ã€‚ +å˜é‡ ``a`` 的当å‰å€¼æ˜ å°„在æ¯ä¸ªåˆ†é…给它的å—结æŸæ—¶è¢«æ¸…除, +如果它被分é…在for循环体或postå—内,则在for循环åˆå§‹å—结æŸæ—¶è¢«æ¸…除。 +如果一个å˜é‡çš„值根æ®ä¸Šé¢çš„规则被清除,并且该å˜é‡è¢«å£°æ˜Žåœ¨å—之外, +一个新的SSAå˜é‡å°†åœ¨æŽ§åˆ¶æµåŠ å…¥çš„ä½ç½®è¢«åˆ›å»ºï¼Œè¿™åŒ…括循环åŽ/体å—的开始和If/Switch/ForLoop/Block语å¥ä¹‹åŽçš„ä½ç½®ã€‚ -After this stage, the Redundant Assign Eliminator is recommended to remove the unnecessary +<<<<<<< HEAD +在此阶段之åŽï¼Œå»ºè®®ä½¿ç”¨å†—余赋值消除器删除ä¸å¿…è¦çš„中间分é…。 +======= +After this stage, the Unused Assign Eliminator is recommended to remove the unnecessary intermediate assignments. +>>>>>>> english/develop -This stage provides best results if the Expression Splitter and the Common Subexpression Eliminator -are run right before it, because then it does not generate excessive amounts of variables. -On the other hand, the Common Subexpression Eliminator could be more efficient if run after the -SSA transform. +如果在这个阶段之å‰è¿è¡Œè¡¨è¾¾å¼æ‹†åˆ†å™¨å’Œé€šç”¨å­è¡¨è¾¾å¼æ¶ˆé™¤å™¨ï¼Œ +那么这个阶段会æ供最好的结果,因为这样就ä¸ä¼šäº§ç”Ÿè¿‡å¤šçš„å˜é‡ã€‚ +å¦ä¸€æ–¹é¢ï¼Œå¦‚果在SSA转æ¢ä¹‹åŽè¿è¡Œé€šç”¨å­è¡¨è¾¾å¼æ¶ˆé™¤å™¨ï¼Œåˆ™æ•ˆçŽ‡æ›´é«˜ã€‚ -.. _redundant-assign-eliminator: +.. _unused-assign-eliminator: -RedundantAssignEliminator +<<<<<<< HEAD +冗余赋值消除器 ^^^^^^^^^^^^^^^^^^^^^^^^^ +======= +UnusedAssignEliminator +^^^^^^^^^^^^^^^^^^^^^^ +>>>>>>> english/develop -The SSA transform always generates an assignment of the form ``a := a_i``, even though -these might be unnecessary in many cases, like the following example: +SSA转æ¢æ€»æ˜¯ç”Ÿæˆ ``a := a_i`` å½¢å¼çš„赋值, +尽管这些赋值在许多情况下å¯èƒ½æ˜¯ä¸å¿…è¦çš„,比如下é¢çš„例å­ï¼š .. code-block:: yul @@ -656,7 +687,7 @@ these might be unnecessary in many cases, like the following example: sstore(a, 1) } -The SSA transform converts this snippet to the following: +SSA转æ¢å°†è¿™ä¸ªç‰‡æ®µè½¬æ¢ä¸ºä»¥ä¸‹å†…容: .. code-block:: yul @@ -670,9 +701,14 @@ The SSA transform converts this snippet to the following: sstore(a_3, 1) } -The Redundant Assign Eliminator removes all the three assignments to ``a``, because +<<<<<<< HEAD +冗余赋值消除器将删除对 ``a`` 的所有三个赋值,因为未使用 ``a`` 的值, +因此将此代ç æ®µè½¬æ¢ä¸ºä¸¥æ ¼çš„SSAå½¢å¼ä¸ºï¼š +======= +The Unused Assign Eliminator 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 @@ -683,327 +719,320 @@ snippet into strict SSA form: sstore(a_3, 1) } -Of course the intricate parts of determining whether an assignment is redundant or not +<<<<<<< HEAD +当然,确定分é…是å¦å¤šä½™çš„错综å¤æ‚的部分与加入控制æµæœ‰å…³ã€‚ +======= +Of course the intricate parts of determining whether an assignment is unused or not are connected to joining control flow. +>>>>>>> english/develop -The component works as follows in detail: +该组件的详细工作情况如下: -The AST is traversed twice: in an information gathering step and in the -actual removal step. During information gathering, we maintain a -mapping from assignment statements to the three states -"unused", "undecided" and "used" which signifies whether the assigned -value will be used later by a reference to the variable. +AST被é历了两次:分别在在信æ¯æ”¶é›†æ­¥éª¤å’Œå®žé™…删除步骤中。 +在信æ¯æ”¶é›†è¿‡ç¨‹ä¸­ï¼Œæˆ‘们维护了一个从赋值语å¥åˆ° “未使用(unused)â€ï¼Œâ€œæœªå†³å®šï¼ˆundecided)†和 “已使用(used)†三ç§çŠ¶æ€çš„映射, +这标志ç€åˆ†é…的值是å¦ä¼šåœ¨ä»¥åŽè¢«å˜é‡çš„引用使用。 -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". +当一个赋值被访问时,它被添加到处于 “未决定†状æ€çš„映射中 +(è§ä¸‹é¢å…³äºŽfor循环的注释),而其他æ¯ä¸ªä»å¤„于 “未决定†状æ€çš„对åŒä¸€å˜é‡çš„赋值被改为 “未使用â€ã€‚ +当一个å˜é‡è¢«å¼•ç”¨æ—¶ï¼Œä»»ä½•å¯¹è¯¥å˜é‡çš„赋值ä»å¤„于 “未决定†状æ€ï¼Œå…¶çŠ¶æ€è¢«æ”¹å˜ä¸º “已使用â€ã€‚ -At points where control flow splits, a copy -of the mapping is handed over to each branch. At points where control flow -joins, the two mappings coming from the two branches are combined in the following way: -Statements that are only in one mapping or have the same state are used unchanged. -Conflicting values are resolved in the following way: +在控制æµåˆ†å‰çš„地方,映射的拷è´è¢«ç§»äº¤ç»™æ¯ä¸ªåˆ†æ”¯ã€‚ +在控制æµæ±‡åˆçš„地方,æ¥è‡ªä¸¤ä¸ªåˆ†æ”¯çš„两个映射以下列方å¼åˆå¹¶ï¼š +åªåœ¨ä¸€ä¸ªæ˜ å°„中的语å¥æˆ–具有相åŒçŠ¶æ€çš„语å¥ä¸ä½œæ”¹åŠ¨åœ°ä½¿ç”¨ã€‚ +冲çªçš„值以如下方å¼è§£å†³ï¼š -- "unused", "undecided" -> "undecided" -- "unused", "used" -> "used" -- "undecided", "used" -> "used" +- “未使用â€ï¼Œ “未决定†-> “未决定†+- “未使用â€ï¼Œ “已使用†-> “已使用†+- “未决定â€ï¼Œ “已使用†-> “已使用†-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. +对于For循环,考虑到æ¡ä»¶ä¸‹çš„连接控制æµï¼Œå°†å¯¹æ¡ä»¶ã€ä¸»ä½“å’ŒåŽéƒ¨è¿›è¡Œä¸¤æ¬¡è®¿é—®ã€‚ +æ¢å¥è¯è¯´ï¼Œæˆ‘们创建了三æ¡æŽ§åˆ¶æµè·¯å¾„:循环的零次è¿è¡Œã€ä¸€æ¬¡è¿è¡Œå’Œä¸¤æ¬¡è¿è¡Œï¼Œç„¶åŽåœ¨æœ€åŽåˆå¹¶å®ƒä»¬ã€‚ -Simulating a third run or even more is unnecessary, which can be seen as follows: +ä¸éœ€è¦æ¨¡æ‹Ÿç¬¬ä¸‰æ¬¡ç”šè‡³æ›´å¤šçš„è¿è¡Œï¼Œè¿™å¯ä»¥å¦‚下所示: -A state of an assignment at the beginning of the iteration will deterministically -result in a state of that assignment at the end of the iteration. Let this -state mapping function be called ``f``. The combination of the three different -states ``unused``, ``undecided`` and ``used`` as explained above is the ``max`` -operation where ``unused = 0``, ``undecided = 1`` and ``used = 2``. +迭代开始时的赋值状æ€å°†å†³å®šæ€§åœ°å¯¼è‡´è¯¥èµ‹å€¼åœ¨è¿­ä»£ç»“æŸæ—¶çš„状æ€ã€‚ +å‡å¦‚这个状æ€æ˜ å°„函数被称为 ``f``。如上所述, +三ç§ä¸åŒçŠ¶æ€ ``unused(未使用)``, ``undecided(未决定)`` å’Œ ``used(已使用)`` 的组åˆæ˜¯ ``最多(max)`` æ“作, +其中 ``unused = 0``, ``undecided = 1``, ``used = 2``。 -The proper way would be to compute +正确的方法是计算 .. code-block:: none max(s, f(s), f(f(s)), f(f(f(s))), ...) -as state after the loop. Since ``f`` just has a range of three different values, -iterating it has to reach a cycle after at most three iterations, -and thus ``f(f(f(s)))`` has to equal one of ``s``, ``f(s)``, or ``f(f(s))`` -and thus +作为循环åŽçš„状æ€ã€‚因为 ``f`` åªæ˜¯æœ‰ä¸‰ä¸ªä¸åŒçš„值的范围, +迭代它必须在最多三个迭代åŽè¾¾åˆ°ä¸€ä¸ªå¾ªçŽ¯ï¼Œ +å› æ­¤ ``f(f(f(s)))`` 必须等于 ``s``, ``f(s)`` 或 ``f(f(s))`` 其中之一, +å› æ­¤ .. code-block:: none max(s, f(s), f(f(s))) = max(s, f(s), f(f(s)), f(f(f(s))), ...). -In summary, running the loop at most twice is enough because there are only three -different states. +总之,最多è¿è¡Œä¸¤æ¬¡å¾ªçŽ¯å°±è¶³å¤Ÿäº†ï¼Œå› ä¸ºåªæœ‰ä¸‰ç§ä¸åŒçš„状æ€ã€‚ -For switch statements that have a "default"-case, there is no control-flow -part that skips the switch. +对于有 "默认" 情况的switch语å¥ï¼Œæ²¡æœ‰è·³è¿‡switch的控制æµéƒ¨åˆ†ã€‚ -When a variable goes out of scope, all statements still in the "undecided" -state are changed to "unused", unless the variable is the return -parameter of a function - there, the state changes to "used". +当一个å˜é‡è¶…出范围时,所有ä»å¤„于 "未决定" 状æ€çš„语å¥éƒ½è¢«æ”¹ä¸º "未使用", +除éžè¯¥å˜é‡æ˜¯ä¸€ä¸ªå‡½æ•°çš„返回å‚æ•°--如何是这样,状æ€å˜ä¸º "已使用"。 -In the second traversal, all assignments that are in the "unused" state are removed. +在第二次é历中,所有处于 "未使用" 状æ€çš„赋值都被删除。 -This step is usually run right after the SSA transform to complete -the generation of the pseudo-SSA. +这一步通常是在SSA转æ¢ä¹‹åŽç«‹å³è¿è¡Œï¼Œä»¥å®Œæˆä¼ªSSA的生æˆã€‚ -Tools +工具 ----- -Movability +å¯ç§»åŠ¨æ€§ ^^^^^^^^^^ -Movability is a property of an expression. It roughly means that the expression -is side-effect free and its evaluation only depends on the values of variables -and the call-constant state of the environment. Most expressions are movable. -The following parts make an expression non-movable: +å¯ç§»åŠ¨æ€§æ˜¯è¡¨è¾¾å¼çš„一个属性。它大致上æ„味ç€è¡¨è¾¾å¼æ˜¯æ²¡æœ‰å‰¯ä½œç”¨çš„, +它的评估åªå–决于å˜é‡çš„值和环境的调用常数状æ€ã€‚ +大多数表达å¼éƒ½æ˜¯å¯ç§»åŠ¨çš„。以下部分使表达å¼ä¸å¯ç§»åŠ¨: -- function calls (might be relaxed in the future if all statements in the function are movable) -- opcodes that (can) have side-effects (like ``call`` or ``selfdestruct``) -- opcodes that read or write memory, storage or external state information -- opcodes that depend on the current PC, memory size or returndata size +- 函数调用(如果函数中的所有语å¥éƒ½æ˜¯å¯ç§»åŠ¨çš„,未æ¥å¯èƒ½ä¼šæ”¾å®½ï¼‰ +- 有副作用的æ“作ç ï¼ˆå¦‚ ``call`` 或 ``selfdestruct``) +- 读å–或写入内存, 存储或外部状æ€ä¿¡æ¯çš„æ“ä½œç  +- å–决于当å‰PCã€å†…存大å°æˆ–返回数æ®å¤§å°çš„æ“ä½œç  -DataflowAnalyzer +æ•°æ®æµåˆ†æžå™¨ ^^^^^^^^^^^^^^^^ -The Dataflow Analyzer 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. - -Expression-Scale Simplifications +æ•°æ®æµåˆ†æžå™¨æœ¬èº«ä¸æ˜¯ä¸€ä¸ªä¼˜åŒ–步骤,而是被其他组件作为工具使用。 +在é历AST时,它跟踪æ¯ä¸ªå˜é‡çš„当å‰å€¼ï¼Œ +åªè¦è¯¥å€¼æ˜¯ä¸€ä¸ªå¯ç§»åŠ¨çš„表达å¼ã€‚ +它记录了作为表达å¼ä¸€éƒ¨åˆ†çš„å˜é‡ï¼Œ +这些表达å¼ç›®å‰è¢«åˆ†é…给其他æ¯ä¸ªå˜é‡ã€‚在æ¯æ¬¡å¯¹å˜é‡ ``a`` 的赋值时, +``a`` 的当å‰å­˜å‚¨å€¼è¢«æ›´æ–°ï¼Œåªè¦ ``a`` 是 ``b`` 当å‰å­˜å‚¨è¡¨è¾¾å¼çš„一部分, +å˜é‡ ``b`` 的所有存储值都被清除。 + +在控制æµè¿žæŽ¥å¤„,如果å˜é‡åœ¨ä»»ä½•æŽ§åˆ¶æµè·¯å¾„中已ç»æˆ–å°†è¦è¢«åˆ†é…, +那么关于这些å˜é‡çš„记忆就会被清除。例如,在进入for循环时,所有将在主体或åŽå—中分é…çš„å˜é‡éƒ½è¢«æ¸…除。 + +表达å¼çš„简化 -------------------------------- -These simplification passes change expressions and replace them by equivalent -and hopefully simpler expressions. +这些简化过程会改å˜è¡¨è¾¾å¼ï¼Œå¹¶ç”¨ç­‰æ•ˆçš„ã€å¸Œæœ›æ›´ç®€å•çš„表达å¼æ›¿æ¢å®ƒä»¬ã€‚ .. _common-subexpression-eliminator: -CommonSubexpressionEliminator +通用å­è¡¨è¾¾å¼æ¶ˆé™¤å™¨ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This step uses the Dataflow Analyzer 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. +这一步使用数æ®æµåˆ†æžå™¨ï¼Œç”¨å¯¹æŸä¸€å˜é‡çš„引用æ¥æ›¿æ¢è¯­æ³•ä¸Šä¸Žè¯¥å˜é‡å½“å‰å€¼ç›¸åŒ¹é…çš„å­è¡¨è¾¾å¼ã€‚ +这是一个等价转æ¢ï¼Œå› ä¸ºè¿™ç§å­è¡¨è¾¾å¼å¿…须是å¯ç§»åŠ¨çš„。 -All subexpressions that are identifiers themselves are replaced by their -current value if the value is an identifier. +如果值是一个标识符,所有本身是标识符的å­è¡¨è¾¾å¼éƒ½è¢«å…¶å½“å‰å€¼æ›¿æ¢ã€‚ +<<<<<<< HEAD +上述两æ¡è§„则的结åˆå…许计算出一个局部值的编å·ï¼Œ +è¿™æ„味ç€å¦‚果两个å˜é‡æœ‰ç›¸åŒçš„值,其中一个将永远是未使用的。 +然åŽï¼Œæœªä½¿ç”¨è¿‡çš„处ç†å™¨æˆ–冗余赋值消除器将能够完全消除此类å˜é‡ã€‚ +======= 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 Unused Pruner or the -Redundant Assign Eliminator will then be able to fully eliminate such +Unused Assign Eliminator will then be able to fully eliminate such variables. +>>>>>>> english/develop -This step is especially efficient if the expression splitter 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. +如果之å‰è¿è¡Œè¿‡è¡¨è¾¾å¼æ‹†åˆ†å™¨ï¼Œåˆ™æ­¤æ­¥éª¤å°¤å…¶æœ‰æ•ˆã€‚ +如果代ç æ˜¯ä¼ªSSAå½¢å¼ï¼Œé‚£ä¹ˆå˜é‡å€¼çš„å¯ç”¨æ—¶é—´æ›´é•¿ï¼Œå› æ­¤æˆ‘们有更高的机会替æ¢è¡¨è¾¾å¼ã€‚ -The expression simplifier will be able to perform better replacements -if the common subexpression eliminator was run right before it. +如果通用å­è¡¨è¾¾å¼æ¶ˆé™¤å™¨åœ¨å®ƒä¹‹å‰è¿è¡Œï¼Œ +表达å¼ç®€åŒ–器将能够进行更好的替æ¢ã€‚ .. _expression-simplifier: -ExpressionSimplifier -^^^^^^^^^^^^^^^^^^^^ +表达å¼ç®€åŒ–器 +^^^^^^^^^^^^ -The ExpressionSimplifier uses the Dataflow Analyzer and makes use -of a list of equivalence transforms on expressions like ``X + 0 -> X`` -to simplify the code. +表达å¼ç®€åŒ–器使用数æ®æµåˆ†æžå™¨ï¼Œ +并利用表达å¼çš„等价å˜æ¢åˆ—表,如 ``X + 0 -> X`` æ¥ç®€åŒ–代ç ã€‚ -It tries to match patterns like ``X + 0`` on each subexpression. -During the matching procedure, it resolves variables to their currently -assigned expressions to be able to match more deeply nested patterns -even when the code is in pseudo-SSA form. +它试图在æ¯ä¸ªå­è¡¨è¾¾å¼ä¸ŠåŒ¹é…诸如 ``X + 0`` 的模å¼ã€‚ +在匹é…过程中,它将å˜é‡è§£æžä¸ºå½“å‰åˆ†é…的表达å¼ï¼Œ +以便能够匹é…更深入的嵌套模å¼ï¼Œ +å³ä½¿ä»£ç æ˜¯ä¼ª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 Expression Simplifier is again more powerful -in split or pseudo-SSA form. +一些模å¼å¦‚ ``X - X -> 0`` åªèƒ½åœ¨è¡¨è¾¾å¼ ``X`` 是å¯ç§»åŠ¨çš„情况下应用, +å¦åˆ™ä¼šåˆ é™¤å…¶æ½œåœ¨çš„副作用。 +由于å˜é‡å¼•ç”¨æ€»æ˜¯å¯ç§»åŠ¨çš„,å³ä½¿å®ƒä»¬çš„当å‰å€¼å¯èƒ½ä¸æ˜¯ï¼Œ +表达å¼ç®€åŒ–器在拆分或伪SSAå½¢å¼ä¸‹åˆæ›´åŠ å¼ºå¤§ã€‚ .. _literal-rematerialiser: -LiteralRematerialiser -^^^^^^^^^^^^^^^^^^^^^ +å­—é¢æ„义上的å†ç‰©è´¨åŒ–器(LiteralRematerialiser) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To be documented. +有待记录。 .. _load-resolver: -LoadResolver +负载解æžå™¨ ^^^^^^^^^^^^ -Optimisation stage that replaces expressions of type ``sload(x)`` and ``mload(x)`` by the value -currently stored in storage resp. memory, if known. +优化阶段,分别将 ``sload(x)`` å’Œ ``mload(x)`` 类型的表达å¼æ›¿æ¢ä¸ºå½“å‰å­˜å‚¨å’Œå†…存中的值,如果已知的è¯ã€‚ + +如果代ç æ˜¯SSAå½¢å¼çš„,效果最好。 + +先决æ¡ä»¶ï¼šæ¶ˆæ­§å™¨ï¼Œå¾ªçŽ¯åˆå§‹é‡å†™å™¨ã€‚ + +<<<<<<< HEAD +.. _reasoning-based-simplifier: + +基于推ç†çš„简化器 +^^^^^^^^^^^^^^^^^^^^^^^^ + +这个优化器使用SMT求解器æ¥æ£€æŸ¥ ``if`` æ¡ä»¶æ˜¯å¦ä¸ºå¸¸æ•°ã€‚ + +- 如果 ``é™åˆ¶æ¡ä»¶å’Œæ¡ä»¶`` 是ä¸æ»¡è¶³çš„(UNSAT),那么æ¡ä»¶æ°¸è¿œä¸ä¼šæ˜¯çœŸçš„,整个主体å¯ä»¥è¢«åˆ é™¤ã€‚ +- 如果 ``é™åˆ¶æ¡ä»¶å’Œéžé™åˆ¶æ¡ä»¶`` 是ä¸æ»¡è¶³çš„(UNSAT),那么æ¡ä»¶æ°¸è¿œæ˜¯çœŸçš„,å¯ä»¥ç”¨ ``1`` 代替。 -Works best if the code is in SSA form. +åªæœ‰åœ¨æ¡ä»¶æ˜¯å¯ç§»åŠ¨çš„情况下,上é¢çš„简化æ‰èƒ½é€‚用。 -Prerequisite: Disambiguator, ForLoopInitRewriter. +它åªå¯¹EVM语言有效,但在其他语言上使用是安全的。 +先决æ¡ä»¶ï¼šæ¶ˆæ­§å™¨ï¼ŒSSA转æ¢ã€‚ + +声明规模的简化 +======= Statement-Scale Simplifications +>>>>>>> english/develop ------------------------------- .. _circular-reference-pruner: -CircularReferencesPruner +å¾ªçŽ¯å¼•ç”¨ç¨‹åº ^^^^^^^^^^^^^^^^^^^^^^^^ -This stage removes functions that call each other but are -neither externally referenced nor referenced from the outermost context. +这个阶段删除了那些互相调用但既没有外部引用也没有从最外层上下文中引用的函数。 .. _conditional-simplifier: -ConditionalSimplifier +æ¡ä»¶ç®€åŒ–器 ^^^^^^^^^^^^^^^^^^^^^ -The Conditional Simplifier inserts assignments to condition variables if the value can be determined -from the control-flow. +如果å¯ä»¥ä»ŽæŽ§åˆ¶æµä¸­ç¡®å®šæ•°å€¼ï¼Œæ¡ä»¶ç®€åŒ–器就会æ’入对æ¡ä»¶å˜é‡çš„赋值。 -Destroys SSA form. +销æ¯SSA表格。 -Currently, this tool is very limited, mostly because we do not yet have support -for boolean types. Since conditions only check for expressions being nonzero, -we cannot assign a specific value. +ç›®å‰ï¼Œè¿™ä¸ªå·¥å…·æ˜¯éžå¸¸æœ‰é™çš„,主è¦æ˜¯å› ä¸ºæˆ‘们还没有支æŒå¸ƒå°”类型。 +由于æ¡ä»¶åªæ£€æŸ¥è¡¨è¾¾å¼æ˜¯å¦ä¸ºéžé›¶ï¼Œæˆ‘们ä¸èƒ½æŒ‡å®šä¸€ä¸ªç‰¹å®šçš„值。 -Current features: +当å‰çš„特性: -- switch cases: insert " := " -- after if statement with terminating control-flow, insert " := 0" +- 切æ¢æ¡ä»¶ï¼šæ’å…¥ “<æ¡ä»¶> := <æ¡ä»¶æ ‡ç­¾>†+- 在带有终止控制æµçš„if语å¥åŽï¼Œæ’入“<æ¡ä»¶> : =0†-Future features: +未æ¥çš„特性: -- allow replacements by "1" -- take termination of user-defined functions into account +- å…许用 "1" æ›¿æ¢ +- 考虑到用户定义的终止函数 -Works best with SSA form and if dead code removal has run before. +如果之å‰å·²ç»è¿è¡Œè¿‡æ­»ä»£ç çš„删除,那么使用SSA表å•æ•ˆæžœæœ€å¥½ã€‚ -Prerequisite: Disambiguator. +先决æ¡ä»¶ï¼šæ¶ˆæ­§å™¨ã€‚ .. _conditional-unsimplifier: -ConditionalUnsimplifier +有æ¡ä»¶çš„éžå¯¹ç§°æ€§æ”¾å¤§å™¨ ^^^^^^^^^^^^^^^^^^^^^^^ -Reverse of Conditional Simplifier. +æ¡ä»¶ç®€åŒ–器的åé¢ã€‚ .. _control-flow-simplifier: -ControlFlowSimplifier +控制æµç®€åŒ–器 ^^^^^^^^^^^^^^^^^^^^^ -Simplifies several control-flow structures: +简化了几个控制æµç»“构: -- 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. +- 用pop(æ¡ä»¶ï¼‰ä»£æ›¿if,用空的程åºä½“代替if +- 移除空的默认switch情况 +- 如果ä¸å­˜åœ¨é»˜è®¤æƒ…况,则删除空的switch情况 +- 用pop(表达å¼ï¼‰ä»£æ›¿æ²¡æœ‰æ¡ä»¶çš„switch +- 把å•ä¾‹çš„switchå˜æˆif +- 用pop(表达å¼ï¼‰å’Œç¨‹åºä½“代替switch,åªç”¨é»˜è®¤æƒ…况 +- 用匹é…çš„æ¡ä»¶ç¨‹åºä½“的常é‡è¡¨è¾¾å¼æ›¿æ¢switch +- å°† ``for`` 替æ¢ä¸ºç»ˆæ­¢æŽ§åˆ¶æµï¼Œåœ¨æ²¡æœ‰å…¶ä»– break/continue 的情况下替æ¢ä¸º ``if`` +- 移除函数末尾的 ``leave`` -None of these operations depend on the data flow. The StructuralSimplifier -performs similar tasks that do depend on data flow. +这些æ“作都ä¸ä¾èµ–于数æ®æµã€‚然而结构简化器执行类似的任务,确实ä¾èµ–于数æ®æµã€‚ -The ControlFlowSimplifier does record the presence or absence of ``break`` -and ``continue`` statements during its traversal. +控制æµç®€åŒ–器在其é历过程中确实记录了是å¦å­˜åœ¨ ``break`` å’Œ ``continue`` 语å¥ã€‚ -Prerequisite: Disambiguator, FunctionHoister, ForLoopInitRewriter. -Important: Introduces EVM opcodes and thus can only be used on EVM code for now. +先决æ¡ä»¶ï¼šæ¶ˆæ­§å™¨ï¼Œå‡½æ•°æå‡å™¨ï¼Œ 循环åˆå§‹é‡å†™å™¨ã€‚ +é‡è¦æ示:引入了EVMæ“作代ç ï¼Œå› æ­¤ç›®å‰åªèƒ½ç”¨äºŽEVM代ç ã€‚ .. _dead-code-eliminator: -DeadCodeEliminator +死代ç æ¶ˆé™¤å™¨ ^^^^^^^^^^^^^^^^^^ -This optimization stage removes unreachable code. +这个优化阶段删除了ä¸å¯åˆ°è¾¾çš„代ç ã€‚ -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. +无法访问的代ç æ˜¯æŒ‡åœ¨ä¸€ä¸ªåŒºå—内的任何代ç ï¼Œ +å…¶å‰é¢æœ‰ leave,return,invalid,break,continue,selfdestruct,revert 或调用用户定义的函数,并无é™åœ°é€’归。 -Function definitions are retained as they might be called by earlier -code and thus are considered reachable. +函数定义被ä¿ç•™ä¸‹æ¥ï¼Œå› ä¸ºå®ƒä»¬å¯èƒ½è¢«æ—©æœŸçš„代ç è°ƒç”¨ï¼Œå› æ­¤è¢«è®¤ä¸ºæ˜¯å¯è®¿é—®çš„。 -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. +因为在for循环的initå—中声明的å˜é‡ï¼Œå…¶èŒƒå›´ä¼šæ‰©å±•åˆ°å¾ªçŽ¯ä½“, +所以我们è¦æ±‚ 循环åˆå§‹é‡å†™å™¨ 在此步骤之å‰è¿è¡Œã€‚ -Prerequisite: ForLoopInitRewriter, Function Hoister, Function Grouper +先决æ¡ä»¶ï¼š 循环åˆå§‹é‡å†™å™¨, 函数æå‡å™¨, 函数分组器 .. _equal-store-eliminator: -EqualStoreEliminator +等价的存储清除器 ^^^^^^^^^^^^^^^^^^^^ -This steps removes ``mstore(k, v)`` and ``sstore(k, v)`` calls if -there was a previous call to ``mstore(k, v)`` / ``sstore(k, v)``, -no other store in between and the values of ``k`` and ``v`` did not change. +如果之å‰æœ‰å¯¹ ``mstore(k, v)`` / ``sstore(k, v)`` 的调用, +但中间没有其他存储,并且 ``k`` å’Œ ``v`` 的值没有å˜åŒ–, +则该步骤将删除 ``mstore(k, v)`` å’Œ ``sstore(k, v)`` 的调用。 -This simple step is effective if run after the SSA transform and the -Common Subexpression Eliminator, because SSA will make sure that the variables -will not change and the Common Subexpression Eliminator re-uses exactly the same -variable if the value is known to be the same. +如果在SSA转æ¢å’Œé€šç”¨å­è¡¨è¾¾å¼æ¶ˆé™¤å™¨ä¹‹åŽè¿è¡Œï¼Œè¿™ä¸ªç®€å•çš„步骤是有效的, +因为SSA将确ä¿å˜é‡ä¸ä¼šæ”¹å˜ï¼Œè€Œé€šç”¨å­è¡¨è¾¾å¼æ¶ˆé™¤å™¨åœ¨å·²çŸ¥å€¼ç›¸åŒçš„情况下会é‡æ–°ä½¿ç”¨å®Œå…¨ç›¸åŒçš„å˜é‡ã€‚ -Prerequisites: Disambiguator, ForLoopInitRewriter +先决æ¡ä»¶ï¼š 消歧器, 循环åˆå§‹é‡å†™å™¨ .. _unused-pruner: -UnusedPruner -^^^^^^^^^^^^ +未使用过的处ç†å™¨ +^^^^^^^^^^^^^^^^ -This step removes the definitions of all functions that are never referenced. +这一步删除了所有从未被引用的函数的定义。 -It also removes the declaration of variables that are never referenced. -If the declaration assigns a value that is not movable, the expression is retained, -but its value is discarded. +它还删除了从未被引用的å˜é‡çš„声明。如果声明指定了一个ä¸å¯ç§»åŠ¨çš„值, +表达å¼å°†è¢«ä¿ç•™ï¼Œä½†å…¶å€¼å°†è¢«ä¸¢å¼ƒã€‚ -All movable expression statements (expressions that are not assigned) are removed. +所有å¯ç§»åŠ¨çš„表达å¼è¯­å¥ï¼ˆæœªè¢«èµ‹å€¼çš„表达å¼ï¼‰éƒ½è¢«åˆ é™¤ã€‚ .. _structural-simplifier: -StructuralSimplifier +结构简化器 ^^^^^^^^^^^^^^^^^^^^ -This is a general step that performs various kinds of simplifications on -a structural level: +这是一个一般的步骤,在结构层é¢ä¸Šè¿›è¡Œå„ç§ç®€åŒ–: -- 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 +- 用 ``pop(æ¡ä»¶)`` 代替 if 语å¥çš„空程åºä½“。 +- 用其主体替æ¢å¸¦æœ‰çœŸå®žæ¡ä»¶çš„ifè¯­å¥ +- 删除带有错误æ¡ä»¶çš„ifè¯­å¥ +- 把å•ä¾‹çš„switchå˜æˆif +- 用 ``pop(表达å¼)`` 和程åºä½“代替switch,åªç”¨é»˜è®¤æƒ…况 +- 通过匹é…çš„æ¡ä»¶ç¨‹åºä½“,用字é¢è¡¨è¾¾å¼æ›¿æ¢switch +- 用其åˆå§‹åŒ–部分å–代带有错误æ¡ä»¶çš„for循环 -This component uses the Dataflow Analyzer. +该组件使用数æ®æµåˆ†æžå™¨ã€‚ .. _block-flattener: -BlockFlattener +å—展平器 ^^^^^^^^^^^^^^ -This stage eliminates nested blocks by inserting the statement in the -inner block at the appropriate place in the outer block. It depends on the -FunctionGrouper and does not flatten the outermost block to keep the form -produced by the FunctionGrouper. +这个阶段通过在外部å—的适当ä½ç½®æ’入内部å—的语å¥æ¥æ¶ˆé™¤åµŒå¥—å—。 +它ä¾èµ–于函数分组器,并ä¸å¯¹æœ€å¤–层的å—进行展平,以ä¿æŒå‡½æ•°åˆ†ç»„器产生的形å¼ã€‚ .. code-block:: yul @@ -1017,7 +1046,7 @@ produced by the FunctionGrouper. } } -is transformed to +被转化为 .. code-block:: yul @@ -1029,37 +1058,36 @@ is transformed to } } -As long as the code is disambiguated, this does not cause a problem because -the scopes of variables can only grow. +åªè¦ä»£ç æ²¡æœ‰æ­§ä¹‰ï¼Œè¿™å°±ä¸ä¼šé€ æˆé—®é¢˜ï¼Œå› ä¸ºå˜é‡çš„作用域åªèƒ½å¢žé•¿ã€‚ .. _loop-invariant-code-motion: -LoopInvariantCodeMotion +循环ä¸å˜ä»£ç æ¨¡å¼ ^^^^^^^^^^^^^^^^^^^^^^^ -This optimization moves movable SSA variable declarations outside the loop. +è¿™ç§ä¼˜åŒ–å°†å¯ç§»åŠ¨çš„SSAå˜é‡å£°æ˜Žç§»åˆ°å¾ªçŽ¯ä¹‹å¤–。 -Only statements at the top level in a loop's body or post block are considered, i.e variable -declarations inside conditional branches will not be moved out of the loop. +åªæœ‰åœ¨å¾ªçŽ¯ä½“或åŽå—中的最高级别的语å¥è¢«è€ƒè™‘, +å³æ¡ä»¶åˆ†æ”¯å†…çš„å˜é‡å£°æ˜Žä¸ä¼šè¢«ç§»å‡ºå¾ªçŽ¯ã€‚ -Requirements: +è¦æ±‚: -- The Disambiguator, ForLoopInitRewriter and FunctionHoister must be run upfront. -- Expression splitter and SSA transform should be run upfront to obtain better result. +- 消歧器, 循环åˆå§‹é‡å†™å™¨å’Œå‡½æ•°æå‡å™¨å¿…é¡»æå‰è¿è¡Œã€‚ +- 表达å¼æ‹†åˆ†å™¨å’ŒSSA转æ¢åº”在å‰æœŸè¿è¡Œä»¥èŽ·å¾—更好的结果。 -Function-Level Optimizations +函数级的优化 ---------------------------- .. _function-specializer: -FunctionSpecializer +函数特殊化器 ^^^^^^^^^^^^^^^^^^^ -This step specializes the function with its literal arguments. +这一步是用字é¢å‚æ•°æ¥å®žçŽ°å‡½æ•°çš„专业化。 -If a function, say, ``function f(a, b) { sstore (a, b) }``, is called with literal arguments, for -example, ``f(x, 5)``, where ``x`` is an identifier, it could be specialized by creating a new -function ``f_1`` that takes only one argument, i.e., +如果一个函数,例如, ``function f(a, b) { sstore (a, b) }``,被调用时有字é¢å‚数, +例如, ``f(x, 5)``,其中 ``x`` 是一个标识符,å¯ä»¥é€šè¿‡åˆ›å»ºä¸€ä¸ªæ–°å‡½æ•° ``f_1`` æ¥ä¸“门化, +该函数åªéœ€è¦ä¸€ä¸ªå‚数,å³ï¼š .. code-block:: yul @@ -1068,54 +1096,53 @@ function ``f_1`` that takes only one argument, i.e., sstore(a_1, b_1) } -Other optimization steps will be able to make more simplifications to the function. The -optimization step is mainly useful for functions that would not be inlined. +其他优化步骤将能够对函数进行更多的简化。 +优化步骤主è¦å¯¹é‚£äº›ä¸ä¼šè¢«å†…è”的函数有用。 -Prerequisites: Disambiguator, FunctionHoister +先决æ¡ä»¶ï¼š 消歧器, 函数æå‡å™¨ -LiteralRematerialiser is recommended as a prerequisite, even though it's not required for -correctness. +建议将字é¢æ„义上的å†ç‰©è´¨åŒ–器(LiteralRematerialiser)作为先决æ¡ä»¶ï¼Œå°½ç®¡å®ƒä¸æ˜¯æ­£ç¡®æ€§çš„å¿…è¦æ¡ä»¶ã€‚ .. _unused-function-parameter-pruner: -UnusedFunctionParameterPruner +未使用的函数å‚数管ç†å™¨ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This step removes unused parameters in a function. +这一步是删除一个函数中未使用的å‚数。 -If a parameter is unused, like ``c`` and ``y`` in, ``function f(a,b,c) -> x, y { x := div(a,b) }``, we -remove the parameter and create a new "linking" function as follows: +如果一个å‚数没有使用, +比如在 ``function f(a,b,c) -> x, y { x := div(a,b) }`` 中的 ``c`` å’Œ ``y``, +我们删除该å‚数并创建一个新的 "连接" 函数,如下所示: .. code-block:: yul function f(a,b) -> x { x := div(a,b) } function f2(a,b,c) -> x, y { x := f(a,b) } -and replace all references to ``f`` by ``f2``. -The inliner should be run afterwards to make sure that all references to ``f2`` are replaced by -``f``. +并将所有对 ``f`` 的引用替æ¢ä¸º ``f2``。 +之åŽåº”该è¿è¡Œå†…è”,以确ä¿æ‰€æœ‰å¯¹ ``f2`` 的引用都被 ``f`` 替æ¢ã€‚ -Prerequisites: Disambiguator, FunctionHoister, LiteralRematerialiser. +先决æ¡ä»¶ï¼š 消歧器, 函数æå‡å™¨ï¼Œ å­—é¢æ„义上的å†ç‰©è´¨åŒ–器 -The step LiteralRematerialiser is not required for correctness. It helps deal with cases such as: -``function f(x) -> y { revert(y, y} }`` where the literal ``y`` will be replaced by its value ``0``, -allowing us to rewrite the function. +å­—é¢æ„义上的å†ç‰©è´¨åŒ–器这个步骤对于正确性æ¥è¯´ä¸æ˜¯å¿…需的。 +它有助于处ç†è¯¸å¦‚以下情况: +``function f(x) -> y { revert(y, y} }`` 其中字é¢æ„æ€ ``y`` 将被其值 ``0`` å–代, +使我们能够é‡å†™è¯¥å‡½æ•°ã€‚ .. index:: ! unused store eliminator .. _unused-store-eliminator: -UnusedStoreEliminator +未使用的存储清除器 ^^^^^^^^^^^^^^^^^^^^^ -Optimizer component that removes redundant ``sstore`` and memory store statements. -In case of an ``sstore``, if all outgoing code paths revert (due to an explicit ``revert()``, ``invalid()``, or infinite recursion) or -lead to another ``sstore`` for which the optimizer can tell that it will overwrite the first store, the statement will be removed. -However, if there is a read operation between the initial ``sstore`` and the revert, or the overwriting ``sstore``, the statement -will not be removed. -Such read operations include: external calls, user-defined functions with any storage access, and ``sload`` of a slot that cannot be -proven to differ from the slot written by the initial ``sstore``. +优化器组件,删除多余的 ``sstore`` 和内存存储语å¥ã€‚ +对于一个 ``sstore``,如果所有传出的代ç è·¯å¾„都æ¢å¤äº†ï¼ˆç”±äºŽæ˜¾å¼çš„çš„ ``revert()``, ``invalid()``, 或无é™é€’归) +或导致å¦ä¸€ä¸ª ``sstore``,优化器å¯ä»¥çŸ¥é“它将覆写第一个存储,该语å¥å°†è¢«åˆ é™¤ã€‚ +然而,如果在åˆå§‹ ``sstore`` å’Œæ¢å¤ä¹‹é—´æœ‰è¯»æ“作,或者覆写的 ``sstore``, +该语å¥å°†ä¸ä¼šè¢«åˆ é™¤ã€‚ +这样的读æ“作包括:外部调用,有任何存储访问的用户定义的函数,以åŠä¸èƒ½è¯æ˜Žä¸Žåˆå§‹ ``sstore`` 写的槽ä¸åŒçš„ ``sload``。 -For example, the following code +例如,下é¢çš„ä»£ç  .. code-block:: yul @@ -1128,7 +1155,7 @@ For example, the following code sstore(c, 3) } -will be transformed into the code below after the Unused Store Eliminator step is run +在è¿è¡Œæœªä½¿ç”¨çš„存储消除器步骤åŽï¼Œå°†è¢«è½¬åŒ–ä¸ºä»¥ä¸‹ä»£ç  .. code-block:: yul @@ -1138,144 +1165,148 @@ will be transformed into the code below after the Unused Store Eliminator step i sstore(c, 3) } -For memory store operations, things are generally simpler, at least in the outermost yul block as all such -statements will be removed if they are never read from in any code path. -At function analysis level, however, the approach is similar to ``sstore``, as we do not know whether the memory location will -be read once we leave the function's scope, so the statement will be removed only if all code paths lead to a memory overwrite. +对于内存存储æ“作,事情一般比较简å•ï¼Œè‡³å°‘在最外层的yulå—中是这样, +因为如果在任何代ç è·¯å¾„中从未被读å–,所有这样的语å¥éƒ½å°†è¢«åˆ é™¤ã€‚ +然而,在函数分æžå±‚é¢ï¼Œå…¶æ–¹æ³•ä¸Ž ``sstore`` 类似,因为我们ä¸çŸ¥é“一旦离开函数的范围,内存ä½ç½®æ˜¯å¦ä¼šè¢«è¯»å–, +所以åªæœ‰å½“所有的代ç è·¯å¾„都导致内存被覆写时,语å¥æ‰ä¼šè¢«åˆ é™¤ã€‚ -Best run in SSA form. +最好以SSAå½¢å¼è¿è¡Œã€‚ -Prerequisites: Disambiguator, ForLoopInitRewriter. +先决æ¡ä»¶ï¼š Disambiguator, ForLoopInitRewriter. .. _equivalent-function-combiner: -EquivalentFunctionCombiner +等价函数组åˆå™¨ ^^^^^^^^^^^^^^^^^^^^^^^^^^ -If two functions are syntactically equivalent, while allowing variable -renaming but not any re-ordering, then any reference to one of the -functions is replaced by the other. +如果两个函数在语法上是等价的, +åŒæ—¶å…许å˜é‡é‡å‘½å,但ä¸å…许任何é‡æ–°æŽ’åºï¼Œ +那么对其中一个函数的任何引用都会被å¦ä¸€ä¸ªå‡½æ•°å–代。 -The actual removal of the function is performed by the Unused Pruner. +实际删除的功能是由未使用过的处ç†å™¨æ‰§è¡Œçš„。 -Function Inlining +å‡½æ•°å†…è” ----------------- .. _expression-inliner: -ExpressionInliner +表达å¼å†…è” ^^^^^^^^^^^^^^^^^ -This component of the optimizer performs restricted function inlining by inlining functions that can be -inlined inside functional expressions, i.e. functions that: +优化器的这个组件通过内è”å¯ä»¥åœ¨å‡½æ•°è¡¨è¾¾å¼ä¸­å†…è”的函数æ¥æ‰§è¡Œé™åˆ¶æ€§çš„函数内è”,函数为: -- return a single value. -- have a body like ``r := ``. -- neither reference themselves nor ``r`` in the right hand side. +- 返回一个å•ä¸€çš„值。 +- æœ‰ä¸€ä¸ªåƒ ``r := <函数表达å¼>`` 的主体。 +- 既没有æ到自己,也没有æ到å³è¾¹çš„ ``r``。 -Furthermore, for all parameters, all of the following need to be true: +此外,对于所有的å‚数,以下å„项都需è¦ä¸ºçœŸï¼š -- 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). +- å‚数是å¯ç§»åŠ¨çš„。 +- 该å‚数在函数体中被引用ä¸åˆ°ä¸¤æ¬¡ï¼Œæˆ–者该å‚数相当便宜 + ( "æˆæœ¬" 最多为1,就åƒä¸€ä¸ª0xff以下的常数)。 -Example: The function to be inlined has the form of ``function f(...) -> r { r := E }`` where -``E`` is an expression that does not reference ``r`` and all arguments in the function call are movable expressions. +例如:è¦è¢«å†…è”的函数的形å¼æ˜¯ï¼š ``function f(...) -> r { r := E }`` +其中 ``E`` 是一个ä¸å¼•ç”¨ ``r`` 的表达å¼ï¼Œå‡½æ•°è°ƒç”¨ä¸­çš„所有å‚数都是å¯ç§»åŠ¨è¡¨è¾¾å¼ã€‚ -The result of this inlining is always a single expression. +è¿™ç§å†…è”的结果总是一个å•ä¸€çš„表达å¼ã€‚ -This component can only be used on sources with unique names. +该组件åªèƒ½ç”¨äºŽå…·æœ‰å”¯ä¸€å称的æºç ã€‚ .. _full-inliner: -FullInliner +å®Œå…¨å†…è” ^^^^^^^^^^^ +<<<<<<< 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 same cases, though, inlining a function +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 -During inlining, a heuristic is used to tell if the function call -should be inlined or not. -The current heuristic does not inline into "large" functions unless -the called function is tiny. Functions that are only used once -are inlined, as well as medium-sized functions, while function -calls with constant arguments allow slightly larger functions. +在内è”过程中,一个å¯å‘å¼æ–¹æ³•è¢«ç”¨æ¥åˆ¤æ–­å‡½æ•°è°ƒç”¨æ˜¯å¦åº”该被内è”。 +ç›®å‰çš„å¯å‘å¼æ–¹æ³•æ˜¯ä¸å†…è”到 "大" 函数,除éžè¢«è°ƒç”¨çš„函数很å°ã€‚ +åªä½¿ç”¨ä¸€æ¬¡çš„函数以åŠä¸­ç­‰å¤§å°çš„函数被内è”,而带有常数å‚数的函数调用å…许ç¨å¤§çš„函数。 -In the future, we may include a backtracking component -that, instead of inlining a function right away, only specializes it, -which means that a copy of the function is generated where -a certain parameter is always replaced by a constant. After that, -we can run the optimizer on this specialized function. If it -results in heavy gains, the specialized function is kept, -otherwise the original function is used instead. +在未æ¥ï¼Œæˆ‘们å¯èƒ½ä¼šåŠ å…¥ä¸€ä¸ªå›žæº¯ç»„件, +它ä¸ä¼šç«‹å³å¯¹ä¸€ä¸ªå‡½æ•°è¿›è¡Œå†…è”,而åªæ˜¯å¯¹å…¶è¿›è¡Œä¸“业化处ç†ï¼Œ +è¿™æ„味ç€ä¼šç”Ÿæˆä¸€ä¸ªå‡½æ•°çš„æ‹·è´ï¼Œå…¶ä¸­æŸä¸ªå‚数总是被一个常数å–代。 +之åŽï¼Œæˆ‘们å¯ä»¥åœ¨è¿™ä¸ªä¸“用函数上è¿è¡Œä¼˜åŒ–器。 +如果结果有很大的收益,那么这个专门化的函数就被ä¿ç•™ä¸‹æ¥ï¼Œå¦åˆ™å°±ç”¨åŽŸæ¥çš„函数代替。 +<<<<<<< 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 ------- -The cleanup is performed at the end of the optimizer run. It tries -to combine split expressions into deeply nested ones again and also -improves the "compilability" for stack machines by eliminating -variables as much as possible. +清ç†å·¥ä½œæ˜¯åœ¨ä¼˜åŒ–器è¿è¡Œç»“æŸæ—¶è¿›è¡Œçš„。 +它试图将分割的表达å¼å†æ¬¡ç»„åˆæˆæ·±åº¦åµŒå¥—的表达å¼ï¼Œ +并且通过尽å¯èƒ½åœ°æ¶ˆé™¤å˜é‡æ¥æ高堆栈机的 "å¯ç¼–译性"。 .. _expression-joiner: -ExpressionJoiner +表达å¼è¿žæŽ¥å™¨ ^^^^^^^^^^^^^^^^ -This is the opposite operation of the expression splitter. 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. +这是与表达å¼åˆ†å‰²å™¨ç›¸åçš„æ“作。它把正好有一个引用的å˜é‡å£°æ˜Žåºåˆ—å˜æˆä¸€ä¸ªå¤æ‚的表达å¼ã€‚ +这个阶段完全ä¿ç•™äº†å‡½æ•°è°ƒç”¨å’Œæ“作ç æ‰§è¡Œçš„顺åºã€‚它ä¸ä½¿ç”¨ä»»ä½•å…³äºŽæ“作ç çš„互æ¢æ€§çš„ä¿¡æ¯ï¼› +如果将一个å˜é‡çš„值移到它的使用ä½ç½®ä¼šæ”¹å˜ä»»ä½•å‡½æ•°è°ƒç”¨æˆ–æ“作ç æ‰§è¡Œçš„顺åºï¼Œåˆ™ä¸æ‰§è¡Œè½¬æ¢ã€‚ -Note that the component will not move the assigned value of a variable assignment -or a variable that is referenced more than once. +注æ„,组件ä¸ä¼šç§»åŠ¨å˜é‡èµ‹å€¼æˆ–被多次引用的å˜é‡çš„赋值。 -The snippet ``let x := add(0, 2) let y := mul(x, mload(2))`` is not transformed, -because it would cause the order of the call to the opcodes ``add`` and -``mload`` to be swapped - even though this would not make a difference -because ``add`` is movable. +片段 ``let x := add(0, 2) let y := mul(x, mload(2))`` ä¸èƒ½è½¬æ¢ï¼Œ +因为它将导致调用æ“ä½œç  ``add`` å’Œ ``mload`` 的顺åºè¢«è°ƒæ¢--尽管这ä¸ä¼šæœ‰ä»€ä¹ˆå½±å“, +因为 ``add`` 是å¯ç§»åŠ¨çš„。 -When reordering opcodes like that, variable references and literals are ignored. -Because of that, the snippet ``let x := add(0, 2) let y := mul(x, 3)`` is -transformed to ``let y := mul(add(0, 2), 3)``, even though the ``add`` opcode -would be executed after the evaluation of the literal ``3``. +当åƒè¿™æ ·é‡æŽ’æ“作ç æ—¶ï¼Œå˜é‡å¼•ç”¨å’Œå­—é¢æ„义被忽略了。 +因此,片段 ``let x := add(0, 2) let y := mul(x, 3)`` 被转æ¢ä¸º +``let y := mul(add(0, 2), 3)``,尽管 ``add`` æ“作ç å°†åœ¨è®¡ç®—å­—é¢æ„义 ``3`` åŽæ‰§è¡Œã€‚ .. _SSA-reverser: -SSAReverser +SSAå转器 ^^^^^^^^^^^ -This is a tiny step that helps in reversing the effects of the SSA transform -if it is combined with the Common Subexpression Eliminator and the -Unused Pruner. +这是一个微å°çš„步骤,如果它与通用å­è¡¨è¾¾å¼æ¶ˆé™¤å™¨å’Œæœªä½¿ç”¨è¿‡çš„处ç†å™¨ç›¸ç»“åˆï¼Œ +则有助于扭转SSA转æ¢çš„å½±å“。 +<<<<<<< HEAD +我们生æˆçš„SSAå½¢å¼å¯¹EVMå’ŒWebAssembly的代ç ç”Ÿæˆæ˜¯ä¸åˆ©çš„, +因为它生æˆäº†è®¸å¤šå±€éƒ¨å˜é‡ã€‚最好的办法是用赋值é‡æ–°ä½¿ç”¨çŽ°æœ‰çš„å˜é‡ï¼Œ +而ä¸æ˜¯ç”¨æ–°çš„å˜é‡å£°æ˜Žã€‚ +======= The SSA form we generate is detrimental to code generation because it produces many local variables. It would be better to just re-use existing variables with assignments instead of fresh variable declarations. +>>>>>>> english/develop -The SSA transform rewrites +SSA转æ¢æ”¹å†™ .. code-block:: yul let a := calldataload(0) mstore(a, 1) -to +为 .. code-block:: yul @@ -1285,10 +1316,9 @@ to let a_2 := calldataload(0x20) a := a_2 -The problem is that instead of ``a``, the variable ``a_1`` is used -whenever ``a`` was referenced. The SSA transform changes statements -of this form by just swapping out the declaration and the assignment. The above -snippet is turned into +问题是在引用 ``a`` 时使用了å˜é‡ ``a_1``,而ä¸æ˜¯ ``a``。 +SSA转æ¢æ”¹å˜äº†è¿™ç§å½¢å¼çš„语å¥ï¼Œåªéœ€å°†å£°æ˜Žå’Œèµ‹å€¼äº’æ¢ã€‚ +上é¢çš„片段被转化为 .. code-block:: yul @@ -1298,56 +1328,51 @@ snippet is turned into a := calldataload(0x20) let a_2 := a -This is a very simple equivalence transform, but when we now run the -Common Subexpression Eliminator, it will replace all occurrences of ``a_1`` -by ``a`` (until ``a`` is re-assigned). The Unused Pruner will then -eliminate the variable ``a_1`` altogether and thus fully reverse the -SSA transform. +这是一个éžå¸¸ç®€å•çš„等价转æ¢ï¼Œä½†æ˜¯å½“我们现在è¿è¡Œé€šç”¨å­è¡¨è¾¾å¼æ¶ˆé™¤å™¨æ—¶ï¼Œ +它将用 ``a`` 替æ¢æ‰€æœ‰å‡ºçŽ°çš„ ``a_1`` (直到 ``a`` 被é‡æ–°èµ‹å€¼ï¼‰ã€‚ +然åŽï¼Œæœªä½¿ç”¨è¿‡çš„处ç†å™¨å°†å®Œå…¨æ¶ˆé™¤å˜é‡ ``a_1``,从而完全逆转SSA的转æ¢ã€‚ .. _stack-compressor: -StackCompressor +堆栈压缩器 ^^^^^^^^^^^^^^^ -One problem that makes code generation for the Ethereum Virtual Machine -hard is the fact that there is a hard limit of 16 slots for reaching -down the expression stack. This more or less translates to a limit -of 16 local variables. The stack compressor takes Yul code and -compiles it to EVM bytecode. Whenever the stack difference is too -large, it records the function this happened in. +让以太åŠè™šæ‹Ÿæœºçš„代ç ç”Ÿæˆå˜å¾—困难的一个问题是, +在表达å¼å †æ ˆä¸­ï¼Œæœ‰16个æ’槽的硬性é™åˆ¶ï¼Œå¯ä»¥å‘下延伸。 +这或多或少转化为16个局部å˜é‡çš„é™åˆ¶ã€‚ +堆栈压缩器采用Yul代ç å¹¶å°†å…¶ç¼–译为EVM字节ç ã€‚ +æ¯å½“堆栈差异过大时,它就会记录å‘生在哪个函数中。 -For each function that caused such a problem, the Rematerialiser -is called with a special request to aggressively eliminate specific -variables sorted by the cost of their values. +对于æ¯ä¸€ä¸ªé€ æˆè¿™ç§é—®é¢˜çš„函数,å†ç‰©è´¨åŒ–都会被调用, +并æ出特殊è¦æ±‚,以积æžæ¶ˆé™¤æŒ‰å…¶å€¼çš„æˆæœ¬æŽ’åºçš„特定å˜é‡ã€‚ -On failure, this procedure is repeated multiple times. +一旦失败,这个程åºä¼šé‡å¤å¤šæ¬¡ã€‚ .. _rematerialiser: -Rematerialiser +å†ç‰©è´¨åŒ– ^^^^^^^^^^^^^^ -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. +å†ç‰©è´¨åŒ–阶段试图用最åŽåˆ†é…ç»™å˜é‡çš„表达å¼æ¥æ›¿æ¢å˜é‡å¼•ç”¨ã€‚ +当然,这åªæœ‰åœ¨è¿™ä¸ªè¡¨è¾¾å¼çš„评估费用相对较低的情况下æ‰æ˜¯æœ‰ç›Šçš„。 +此外,åªæœ‰å½“表达å¼çš„值在赋值点和使用点之间没有å˜åŒ–时, +它æ‰å…·æœ‰è¯­ä¹‰ä¸Šçš„ç­‰åŒæ€§ã€‚这个阶段的主è¦å¥½å¤„是, +如果它导致一个å˜é‡è¢«å®Œå…¨æ¶ˆé™¤ï¼Œå®ƒå¯ä»¥èŠ‚çœå †æ ˆæ§½ï¼ˆè§ä¸‹æ–‡ï¼‰ï¼Œ +但是如果表达å¼éžå¸¸ä¾¿å®œï¼Œå®ƒä¹Ÿå¯ä»¥åœ¨EVM上节çœä¸€ä¸ªDUPæ“作ç ã€‚ -The Rematerialiser uses the Dataflow Analyzer 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. +å†ç‰©è´¨åŒ–使用数æ®æµåˆ†æžå™¨æ¥è·Ÿè¸ªå˜é‡çš„当å‰å€¼ï¼Œ +这些å˜é‡æ€»æ˜¯å¯ç§»åŠ¨çš„。 +如果数值éžå¸¸ä¾¿å®œæˆ–者å˜é‡è¢«æ˜Žç¡®è¦æ±‚消除, +那么å˜é‡çš„引用就会被其当å‰å€¼æ‰€å–代。 .. _for-loop-condition-out-of-body: -ForLoopConditionOutOfBody +体外循环æ¡ä»¶ ^^^^^^^^^^^^^^^^^^^^^^^^^ -Reverses the transformation of ForLoopConditionIntoBody. +逆转体外循环æ¡ä»¶çš„转æ¢ã€‚ -For any movable ``c``, it turns +对于任何å¯ç§»åŠ¨çš„ ``c``ï¼Œå®ƒè½¬æ¢ .. code-block:: none @@ -1356,7 +1381,7 @@ For any movable ``c``, it turns ... } -into +为 .. code-block:: none @@ -1364,7 +1389,7 @@ into ... } -and it turns +而它åˆè½¬æ¢ .. code-block:: none @@ -1373,7 +1398,7 @@ and it turns ... } -into +为 .. code-block:: none @@ -1381,4 +1406,76 @@ into ... } -The LiteralRematerialiser should be run before this step. +å­—é¢æ„义上的å†ç‰©è´¨åŒ–器应在此步骤之å‰è¿è¡Œã€‚ + +Codegen-Based Optimizer Module +============================== + +<<<<<<< HEAD +特定的WebAssembly +-------------------- + +主è¦åŠŸèƒ½ +^^^^^^^^^^^^ + +将最上é¢çš„å—改å˜ä¸ºä¸€ä¸ªå…·æœ‰ç‰¹å®šå称(“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/internals/source_mappings.rst b/docs/internals/source_mappings.rst index 68c29d955e34..6c25b05f4f19 100644 --- a/docs/internals/source_mappings.rst +++ b/docs/internals/source_mappings.rst @@ -1,70 +1,53 @@ .. index:: source mappings *************** -Source Mappings +æºä»£ç æ˜ å°„ *************** -As part of the AST output, the compiler provides the range of the source -code that is represented by the respective node in the AST. This can be -used for various purposes ranging from static analysis tools that report -errors based on the AST and debugging tools that highlight local variables -and their uses. +作为AST输出的一部分,编译器æ供了AST中相应节点所代表的æºä»£ç çš„范围。 +è¿™å¯ä»¥ç”¨äºŽå„ç§ç›®çš„,包括基于AST报告错误的é™æ€åˆ†æžå·¥å…·å’Œçªå‡ºå±€éƒ¨å˜é‡åŠå…¶ç”¨é€”的调试工具。 -Furthermore, the compiler can also generate a mapping from the bytecode -to the range in the source code that generated the instruction. This is again -important for static analysis tools that operate on bytecode level and -for displaying the current position in the source code inside a debugger -or for breakpoint handling. This mapping also contains other information, -like the jump type and the modifier depth (see below). +此外,编译器还å¯ä»¥ç”Ÿæˆä»Žå­—节ç åˆ°ç”Ÿæˆè¯¥æŒ‡ä»¤çš„æºä»£ç èŒƒå›´çš„映射。 +这对于在字节ç å±‚次上æ“作的é™æ€åˆ†æžå·¥å…·å’Œåœ¨è°ƒè¯•å™¨ä¸­æ˜¾ç¤ºæºä»£ç ä¸­çš„当å‰ä½ç½®æˆ–断点处ç†æ¥è¯´ï¼Œ +也是很é‡è¦çš„。这个映射还包å«å…¶ä»–ä¿¡æ¯ï¼Œå¦‚跳转类型和修改器深度(è§ä¸‹æ–‡ï¼‰ã€‚ -Both kinds of source mappings use integer identifiers to refer to source files. -The identifier of a source file is stored in -``output['sources'][sourceName]['id']`` where ``output`` is the output of the -standard-json compiler interface parsed as JSON. -For some utility routines, the compiler generates "internal" source files -that are not part of the original input but are referenced from the source -mappings. These source files together with their identifiers can be -obtained via ``output['contracts'][sourceName][contractName]['evm']['bytecode']['generatedSources']``. +这两ç§æºç æ˜ å°„都使用整数标识符æ¥æŒ‡ä»£æºç æ–‡ä»¶ã€‚æºæ–‡ä»¶çš„标识符存储在 ``output['sources'][sourceName]['id']`` 中, +其中 ``output`` 是标准json编译器接å£çš„输出,被解æžæˆJSON。 +对于一些实用程åºï¼Œç¼–è¯‘å™¨ä¼šç”Ÿæˆ "内部" æºæ–‡ä»¶ï¼Œ +这些文件ä¸æ˜¯åŽŸå§‹è¾“入的一部分,而是从æºæ˜ å°„中引用的。 +这些æºæ–‡ä»¶åŠå…¶æ ‡è¯†ç¬¦å¯ä»¥é€šè¿‡ ``output['contracts'][sourceName][contractName]['evm']['bytecode']['generatedSources']`` 获得。 .. note:: - In the case of instructions that are not associated with any particular source file, - the source mapping assigns an integer identifier of ``-1``. This may happen for - bytecode sections stemming from compiler-generated inline assembly statements. + 如果指令没有与任何特定的æºæ–‡ä»¶ç›¸å…³è”, + æºæ˜ å°„将分é…一个整数标识符 ``-1``。 + è¿™å¯èƒ½å‘生在编译器生æˆçš„内è”汇编语å¥æ‰€äº§ç”Ÿçš„字节ç éƒ¨åˆ†ã€‚ -The source mappings inside the AST use the following -notation: +AST内部的æºæ˜ å°„使用以下符å·ï¼š ``s:l:f`` -Where ``s`` is the byte-offset to the start of the range in the source file, -``l`` is the length of the source range in bytes and ``f`` is the source -index mentioned above. +其中, ``s`` 是æºä»£ç æ–‡ä»¶ä¸­èŒƒå›´èµ·å§‹å¤„的字节å移é‡ï¼Œ +``l`` 是以字节为å•ä½çš„æºä»£ç èŒƒå›´çš„长度, ``f`` 是上述æºä»£ç ç´¢å¼•ã€‚ -The encoding in the source mapping for the bytecode is more complicated: -It is a list of ``s:l:f:j:m`` separated by ``;``. Each of these -elements corresponds to an instruction, i.e. you cannot use the byte offset -but have to use the instruction offset (push instructions are longer than a single byte). -The fields ``s``, ``l`` and ``f`` are as above. ``j`` can be either -``i``, ``o`` or ``-`` signifying whether a jump instruction goes into a -function, returns from a function or is a regular jump as part of e.g. a loop. -The last field, ``m``, is an integer that denotes the "modifier depth". This depth -is increased whenever the placeholder statement (``_``) is entered in a modifier -and decreased when it is left again. This allows debuggers to track tricky cases -like the same modifier being used twice or multiple placeholder statements being -used in a single modifier. +æºç æ˜ å°„中的字节ç çš„ç¼–ç æ›´ä¸ºå¤æ‚。它是一个由 ``s:l:f:j:m`` 组æˆçš„列表,用 ``;`` 分隔。 +这些元素中的æ¯ä¸€ä¸ªéƒ½å¯¹åº”ç€ä¸€æ¡æŒ‡ä»¤ï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œæ‚¨ä¸èƒ½ä½¿ç”¨å­—节å移é‡ï¼Œ +而必须使用指令å移é‡ï¼ˆæŽ¨é€æŒ‡ä»¤æ¯”å•ä¸ªå­—节长)。字段 ``s`` , ``l`` å’Œ ``f`` åŒä¸Šã€‚ +``j`` å¯ä»¥æ˜¯ ``i``, ``o`` 或 ``-``,表示跳转指令是进入一个函数, +从一个函数返回,还是作为一个循环的一部分的普通跳转。 +最åŽä¸€ä¸ªå­—段, ``m``,是一个整数,表示 "修改器深度"。 +当å ä½ç¬¦è¯­å¥( ``_`` )进入修改器时,这个深度会增加,当它å†æ¬¡ç¦»å¼€æ—¶ï¼Œæ·±åº¦ä¼šå‡å°‘。 +这使得调试器å¯ä»¥è·Ÿè¸ªä¸€äº›æ£˜æ‰‹çš„情况,如åŒä¸€ä¸ªä¿®æ”¹å™¨è¢«ä½¿ç”¨ä¸¤æ¬¡ï¼Œæˆ–在一个修改器中使用多个å ä½ç¬¦è¯­å¥ã€‚ -In order to compress these source mappings especially for bytecode, the -following rules are used: +为了压缩这些æºç æ˜ å°„,特别是字节ç çš„æºç æ˜ å°„,使用了以下规则: -- If a field is empty, the value of the preceding element is used. -- If a ``:`` is missing, all following fields are considered empty. +- 如果一个字段为空,则使用å‰ä¸€ä¸ªå…ƒç´ çš„值。 +- 如果缺少 ``:`` ,以下所有字段都被认为是空的。 -This means the following source mappings represent the same information: +è¿™æ„味ç€ä¸‹é¢çš„æºç æ˜ å°„代表了相åŒçš„ä¿¡æ¯ï¼š ``1:2:1;1:9:1;2:1:2;2:1:2;2:1:2`` ``1:2:1;:9;2:1:2;;`` -Important to note is that when the :ref:`verbatim ` builtin is used, -the source mappings will be invalid: The builtin is considered a single -instruction instead of potentially multiple. +需è¦æ³¨æ„的是,当使用 :ref:`é€å­—(verbatim) ` 内建程åºæ—¶ï¼Œ +æºç æ˜ å°„将是无效的。内建程åºè¢«è®¤ä¸ºæ˜¯ä¸€æ¡æŒ‡ä»¤ï¼Œè€Œä¸æ˜¯æ½œåœ¨çš„多æ¡æŒ‡ä»¤ã€‚ diff --git a/docs/internals/variable_cleanup.rst b/docs/internals/variable_cleanup.rst index bab3c8bef2ef..14f3ccf6dcc7 100644 --- a/docs/internals/variable_cleanup.rst +++ b/docs/internals/variable_cleanup.rst @@ -1,61 +1,47 @@ .. index: variable cleanup ********************* -Cleaning Up Variables +清ç†å˜é‡ ********************* -Ultimately, all values in the EVM are stored in 256 bit words. -Thus, in some cases, when the type of a value has less than 256 bits, -it is necessary to clean the remaining bits. -The Solidity compiler is designed to do such cleaning before any operations -that might be adversely affected by the potential garbage in the remaining bits. -For example, before writing a value to memory, the remaining bits need -to be cleared because the memory contents can be used for computing -hashes or sent as the data of a message call. Similarly, before -storing a value in the storage, the remaining bits need to be cleaned -because otherwise the garbled value can be observed. - -Note that access via inline assembly is not considered such an operation: -If you use inline assembly to access Solidity variables -shorter than 256 bits, the compiler does not guarantee that -the value is properly cleaned up. - -Moreover, we do not clean the bits if the immediately -following operation is not affected. For instance, since any non-zero -value is considered ``true`` by ``JUMPI`` instruction, we do not clean -the boolean values before they are used as the condition for -``JUMPI``. - -In addition to the design principle above, the Solidity compiler -cleans input data when it is loaded onto the stack. - -The following table describes the cleaning rules applied to different types, -where ``higher bits`` refers to the remaining bits in case the type has less than 256 bits. - -+---------------+---------------+-------------------------+ -|Type |Valid Values |Cleanup of Invalid Values| -+===============+===============+=========================+ -|enum of n |0 until n - 1 |throws exception | -|members | | | -+---------------+---------------+-------------------------+ -|bool |0 or 1 |results in 1 | -+---------------+---------------+-------------------------+ -|signed integers|higher bits |currently silently | -| |set to the |signextends to a valid | -| |sign bit |value, i.e. all higher | -| | |bits are set to the sign | -| | |bit; may throw an | -| | |exception in the future | -+---------------+---------------+-------------------------+ -|unsigned |higher bits |currently silently masks | -|integers |zeroed |to a valid value, i.e. | -| | |all higher bits are set | -| | |to zero; may throw an | -| | |exception in the future | -+---------------+---------------+-------------------------+ - -Note that valid and invalid values are dependent on their type size. -Consider ``uint8``, the unsigned 8-bit type, which has the following valid values: +最终,EVM中的所有数值都被存储在256ä½çš„字中。 +因此,在æŸäº›æƒ…况下,当一个值的类型少于256比特时, +有必è¦æ¸…ç†å‰©ä½™çš„比特ä½ã€‚ +Solidity 编译器被设计为在任何å¯èƒ½å—到剩余ä½ä¸­æ½œåœ¨åžƒåœ¾çš„ä¸åˆ©å½±å“çš„æ“作之å‰æ‰§è¡Œè¿™æ ·çš„清ç†ã€‚ +例如,在将一个值写入内存之å‰ï¼Œå‰©ä½™çš„ä½éœ€è¦è¢«æ¸…除, +因为内存的内容å¯ä»¥è¢«ç”¨æ¥è®¡ç®—哈希值或作为消æ¯è°ƒç”¨çš„æ•°æ®å‘é€ã€‚ +åŒæ ·åœ°ï¼Œåœ¨å°†ä¸€ä¸ªå€¼å­˜å‚¨åˆ°å­˜å‚¨å™¨ä¸­ä¹‹å‰ï¼Œå‰©ä½™çš„ä½éœ€è¦è¢«æ¸…ç†ï¼Œ +å¦åˆ™å°±ä¼šçœ‹åˆ°è¢«æ··æ·†çš„数值。 + +注æ„,通过内è”汇编的访问ä¸è¢«è®¤ä¸ºæ˜¯è¿™ç§æ“作。 +如果您使用内è”汇编æ¥è®¿é—®çŸ­äºŽ256ä½çš„Solidityå˜é‡ï¼Œç¼–译器ä¸ä¿è¯è¯¥å€¼è¢«æ­£ç¡®æ¸…ç†ã€‚ + +此外,如果接下æ¥çš„æ“作ä¸å—å½±å“,我们就ä¸æ¸…ç†è¿™äº›ä½ã€‚ +例如,由于任何éžé›¶å€¼éƒ½è¢« ``JUMPI`` 指令认为是 ``true``, +所以在布尔值被用作 ``JUMPI`` çš„æ¡ä»¶ä¹‹å‰ï¼Œæˆ‘们ä¸å¯¹å®ƒä»¬è¿›è¡Œæ¸…ç†ã€‚ + +除了上é¢çš„设计原则外,Solidity编译器在输入数æ®è¢«åŠ è½½åˆ°å †æ ˆæ—¶ä¹Ÿä¼šå¯¹å…¶è¿›è¡Œæ¸…ç†ã€‚ + +下表æ述了适用于ä¸åŒç±»åž‹çš„清ç†è§„则,其中 ``高ä½`` 指的是在类型少于256ä½çš„情况下的剩余ä½ã€‚ + ++----------------+------------------+--------------------------------+ +| 类型 | 有效的值 | 清ç†æ— æ•ˆå€¼ | ++================+==================+================================+ +| n 个æˆå‘˜çš„枚举 | 0,直到n - 1 | 抛出异常 | ++----------------+------------------+--------------------------------+ +| 布尔 | 0 或 1 | 结果为1 | ++----------------+------------------+--------------------------------+ +| 有符å·æ•´æ•° | 高ä½è®¾ç½®ä¸ºç¬¦å·ä½ | ç›®å‰é»˜è®¸ç¬¦å·åŒ–扩展到一个有效值 | +| | | å³æ‰€æœ‰é«˜ä½è¢«è®¾ç½®ä¸ºç¬¦å·ä½ï¼› | +| | | å°†æ¥å¯èƒ½ä¼šæŠ›å‡ºä¸€ä¸ªå¼‚常。 | ++----------------+------------------+--------------------------------+ +| 无符å·æ•´æ•° | 高ä½è¢«æ¸…零 | ç›®å‰é»˜è®¸ä¸ºæœ‰æ•ˆå€¼ï¼Œ | +| | | å³æ‰€æœ‰é«˜ä½è¢«è®¾ç½®ä¸ºé›¶ï¼› | +| | | å°†æ¥å¯èƒ½ä¼šæŠ›å‡ºä¸€ä¸ªå¼‚常。 | ++----------------+------------------+--------------------------------+ + +请注æ„,有效和无效的值å–决于其类型大å°ã€‚ +å‡è®¾ç±»åž‹ä¸º ``uint8``,å³æ— ç¬¦å·çš„8ä½ç±»åž‹ï¼Œå®ƒæœ‰ä»¥ä¸‹æœ‰æ•ˆå€¼ï¼š .. code-block:: none @@ -65,16 +51,16 @@ Consider ``uint8``, the unsigned 8-bit type, which has the following valid value .... 0000...0000 1111 1111 -Any invalid value will have the higher bits set to zero: +任何无效的值都将把高ä½è®¾ç½®ä¸ºé›¶ï¼š .. code-block:: none - 0101...1101 0010 1010 invalid value - 0000...0000 0010 1010 cleaned value + 0101...1101 0010 1010 无效的值 + 0000...0000 0010 1010 清ç†è¿‡çš„值 -For ``int8``, the signed 8-bit type, the valid values are: +对于 ``int8``,å³æœ‰ç¬¦å·çš„8ä½ç±»åž‹ï¼Œæœ‰æ•ˆå€¼æ˜¯ï¼š -Negative +è´Ÿæ•° .. code-block:: none @@ -83,7 +69,7 @@ Negative .... 1111...1111 1000 0000 -Positive +正数 .. code-block:: none @@ -93,19 +79,18 @@ Positive .... 0000...0000 1111 1111 -The compiler will ``signextend`` the sign bit, which is 1 for negative and 0 for -positive values, overwriting the higher bits: +编译器将 ``符å·åŒ–扩展(signextend)`` 符å·ä½ï¼Œå³è´Ÿå€¼ä¸º1,正值为0,覆盖高ä½ï¼š -Negative +è´Ÿæ•° .. code-block:: none - 0010...1010 1111 1111 invalid value - 1111...1111 1111 1111 cleaned value + 0010...1010 1111 1111 无效的值 + 1111...1111 1111 1111 清ç†è¿‡çš„值 -Positive +正数 .. code-block:: none - 1101...0101 0000 0100 invalid value - 0000...0000 0000 0100 cleaned value + 1101...0101 0000 0100 无效的值 + 0000...0000 0000 0100 清ç†è¿‡çš„值 diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index c4cc1201b02a..7e02a2b04d8e 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -1,18 +1,17 @@ ############################### -Introduction to Smart Contracts +智能åˆçº¦æ¦‚è¿° ############################### .. _simple-smart-contract: *********************** -A Simple Smart Contract +简å•çš„智能åˆçº¦ *********************** -Let us begin with a basic example that sets the value of a variable and exposes -it for other contracts to access. It is fine if you do not understand -everything right now, we will go into more details later. +让我们从一个基本的例å­å¼€å§‹ï¼Œè¿™ä¸ªä¾‹å­è®¾ç½®äº†ä¸€ä¸ªå˜é‡çš„值,并将其暴露给其他åˆçº¦æ¥è®¿é—®ã€‚ +如果您现在ä¸ç†è§£è¿™äº›ä¸œè¥¿ä¹Ÿæ²¡å…³ç³»ï¼Œæˆ‘们ç¨åŽä¼šè®¨è®ºæ›´å¤šç»†èŠ‚。 -Storage Example +存储åˆçº¦ç¤ºä¾‹ =============== .. code-block:: solidity @@ -32,55 +31,49 @@ Storage Example } } -The first line tells you that the source code is licensed under the -GPL version 3.0. Machine-readable license specifiers are important -in a setting where publishing the source code is the default. - -The next line specifies that the source code is written for -Solidity version 0.4.16, or a newer version of the language up to, but not including version 0.9.0. -This is to ensure that the contract is not compilable with a new (breaking) compiler version, where it could behave differently. -:ref:`Pragmas` are common instructions for compilers about how to treat the -source code (e.g. `pragma once `_). - -A contract in the sense of Solidity is a collection of code (its *functions*) and -data (its *state*) that resides at a specific address on the Ethereum -blockchain. The line ``uint storedData;`` declares a state variable called ``storedData`` of -type ``uint`` (*u*\nsigned *int*\eger of *256* bits). You can think of it as a single slot -in a database that you can query and alter by calling functions of the -code that manages the database. In this example, the contract defines the -functions ``set`` and ``get`` that can be used to modify -or retrieve the value of the variable. - -To access a member (like a state variable) of the current contract, you do not typically add the ``this.`` prefix, -you just access it directly via its name. -Unlike in some other languages, omitting it is not just a matter of style, -it results in a completely different way to access the member, but more on this later. - -This contract does not do much yet apart from (due to the infrastructure -built by Ethereum) allowing anyone to store a single number that is accessible by -anyone in the world without a (feasible) way to prevent you from publishing -this number. Anyone could call ``set`` again with a different value -and overwrite your number, but the number is still stored in the history -of the blockchain. Later, you will see how you can impose access restrictions -so that only you can alter the number. +第一行告诉您,æºä»£ç æ˜¯æ ¹æ®GPL3.0版本授æƒçš„。 +在å‘布æºä»£ç æ˜¯é»˜è®¤çš„情况下,机器å¯è¯»çš„许å¯è¯è¯´æ˜Žæ˜¯å¾ˆé‡è¦çš„。 + +下一行指定æºä»£ç æ˜¯ä¸ºSolidity 0.4.16版本编写的,或该语言的较新版本,直到但ä¸åŒ…括0.9.0版本。 +这是为了确ä¿åˆçº¦ä¸èƒ½è¢«æ–°çš„(有é‡å¤§æ”¹å˜çš„)编译器版本编译,在那里它å¯èƒ½ä¼šæœ‰ä¸åŒçš„表现。 +:ref:`Pragmas ` 是编译器关于如何处ç†æºä»£ç çš„常用指令 +(例如, `pragma once `_ )。 + +Solidityæ„义上的åˆçº¦æ˜¯ä»£ç ï¼ˆå…¶ *函数*)和数æ®ï¼ˆå…¶ *状æ€*)的集åˆï¼Œ +驻留在以太åŠåŒºå—链的一个特定地å€ã€‚ +这一行 ``uint storedData;`` 声明了一个å为 ``storedData`` 的状æ€å˜é‡ï¼Œ +类型为 ``uint`` ( *u*\nsigned *int*\eger,共 *256* ä½ï¼‰ã€‚ +您å¯ä»¥æŠŠå®ƒçœ‹ä½œæ˜¯æ•°æ®åº“中的一个槽,您å¯ä»¥é€šè¿‡è°ƒç”¨ç®¡ç†æ•°æ®åº“的代ç å‡½æ•°æ¥æŸ¥è¯¢å’Œæ”¹å˜å®ƒã€‚ +在这个例å­ä¸­ï¼Œåˆçº¦å®šä¹‰äº†å¯ä»¥ç”¨æ¥ä¿®æ”¹æˆ–检索å˜é‡å€¼çš„函数 ``set`` å’Œ ``get``。 + +è¦è®¿é—®å½“å‰åˆçº¦çš„一个æˆå‘˜ï¼ˆå¦‚状æ€å˜é‡ï¼‰ï¼Œé€šå¸¸ä¸éœ€è¦æ·»åŠ  ``this.`` å‰ç¼€ï¼Œ +åªéœ€è¦é€šè¿‡å®ƒçš„å字直接访问它。 +与其他一些语言ä¸åŒçš„是,çœç•¥å®ƒä¸ä»…仅是一个风格问题, +它导致了一ç§å®Œå…¨ä¸åŒçš„访问æˆå‘˜çš„æ–¹å¼ï¼Œä½†åŽé¢ä¼šæœ‰æ›´å¤šå…³äºŽè¿™ä¸ªé—®é¢˜ã€‚ + +该åˆçº¦èƒ½å®Œæˆçš„事情并ä¸å¤šï¼ˆç”±äºŽä»¥å¤ªåŠæž„建的基础架构的原因), +它能å…许任何人在åˆçº¦ä¸­å­˜å‚¨ä¸€ä¸ªå•ç‹¬çš„数字,并且这个数字å¯ä»¥è¢«ä¸–界上任何人访问, +且没有å¯è¡Œçš„办法阻止您å‘布这个数字。 +当然,任何人都å¯ä»¥å†æ¬¡è°ƒç”¨ ``set`` ,传入ä¸åŒçš„值,覆盖您的数字, +但是这个数字ä»ä¼šè¢«å­˜å‚¨åœ¨åŒºå—链的历å²è®°å½•ä¸­ã€‚ +éšåŽï¼Œæˆ‘们会看到怎样施加访问é™åˆ¶ï¼Œä»¥ç¡®ä¿åªæœ‰æ‚¨æ‰èƒ½æ”¹å˜è¿™ä¸ªæ•°å­—。 .. warning:: - Be careful with using Unicode text, as similar looking (or even identical) characters can - have different code points and as such are encoded as a different byte array. + å°å¿ƒä½¿ç”¨Unicode文本,因为有些字符虽然长得相似(甚至一样), + 但其字符ç æ˜¯ä¸åŒçš„,其编ç åŽçš„字符数组也会ä¸ä¸€æ ·ã€‚ .. note:: - All identifiers (contract names, function names and variable names) are restricted to - the ASCII character set. It is possible to store UTF-8 encoded data in string variables. + 所有的标识符(åˆçº¦å称,函数å称和å˜é‡å称)都åªèƒ½ä½¿ç”¨ASCII字符集。 + UTF-8ç¼–ç çš„æ•°æ®å¯ä»¥ç”¨å­—符串å˜é‡çš„å½¢å¼å­˜å‚¨ã€‚ .. index:: ! subcurrency -Subcurrency Example -=================== +å­è´§å¸ï¼ˆSubcurrencyï¼‰ä¾‹å­ +=========================== -The following contract implements the simplest form of a -cryptocurrency. The contract allows only its creator to create new coins (different issuance schemes are possible). -Anyone can send coins to each other without a need for -registering with a username and password, all you need is an Ethereum keypair. +下é¢çš„åˆçº¦å®žçŽ°äº†ä¸€ä¸ªæœ€ç®€å•çš„加密货å¸ã€‚ +这里,å¸ç¡®å®žå¯ä»¥æ— ä¸­ç”Ÿæœ‰åœ°äº§ç”Ÿï¼Œä½†æ˜¯åªæœ‰åˆ›å»ºåˆçº¦çš„人æ‰èƒ½åšåˆ°ï¼ˆå®žçŽ°ä¸€ä¸ªä¸åŒçš„å‘行计划也ä¸éš¾ï¼‰ã€‚ +而且,任何人都å¯ä»¥ç»™å…¶ä»–人转å¸ï¼Œä¸éœ€è¦æ³¨å†Œç”¨æˆ·å和密ç ï¼Œæ‰€éœ€è¦çš„åªæ˜¯ä»¥å¤ªåŠå¯†é’¥å¯¹ã€‚ .. code-block:: solidity @@ -88,35 +81,30 @@ registering with a username and password, all you need is an Ethereum keypair. pragma solidity ^0.8.4; contract Coin { - // The keyword "public" makes variables - // accessible from other contracts + // 关键字 "public" 使å˜é‡å¯ä»¥ä»Žå…¶ä»–åˆçº¦ä¸­è®¿é—®ã€‚ address public minter; mapping(address => uint) public balances; - // Events allow clients to react to specific - // contract changes you declare + // 事件å…许客户端对您声明的特定åˆçº¦å˜åŒ–åšå‡ºå应 event Sent(address from, address to, uint amount); - // Constructor code is only run when the contract - // is created + // 构造函数代ç åªæœ‰åœ¨åˆçº¦åˆ›å»ºæ—¶è¿è¡Œ constructor() { minter = msg.sender; } - // Sends an amount of newly created coins to an address - // Can only be called by the contract creator + // å‘一个地å€å‘é€ä¸€å®šæ•°é‡çš„æ–°åˆ›å»ºçš„ä»£å¸ + // 但åªèƒ½ç”±åˆçº¦åˆ›å»ºè€…调用 function mint(address receiver, uint amount) public { require(msg.sender == minter); balances[receiver] += amount; } - // Errors allow you to provide information about - // why an operation failed. They are returned - // to the caller of the function. + // 错误类型å˜é‡å…许您æ供关于æ“作失败原因的信æ¯ã€‚ + // 它们会返回给函数的调用者。 error InsufficientBalance(uint requested, uint available); - // Sends an amount of existing coins - // from any caller to an address + // 从任何调用者那里å‘é€ä¸€å®šæ•°é‡çš„代å¸åˆ°ä¸€ä¸ªåœ°å€ function send(address receiver, uint amount) public { if (amount > balances[msg.sender]) revert InsufficientBalance({ @@ -130,41 +118,46 @@ registering with a username and password, all you need is an Ethereum keypair. } } -This contract introduces some new concepts, let us go through them one by one. +这个åˆçº¦å¼•å…¥äº†ä¸€äº›æ–°çš„概念,让我们é€ä¸€è§£è¯»ã€‚ -The line ``address public minter;`` declares a state variable of type :ref:`address
`. -The ``address`` type is a 160-bit value that does not allow any arithmetic operations. -It is suitable for storing addresses of contracts, or a hash of the public half -of a keypair belonging to :ref:`external accounts`. +``address public minter;`` 这一行声明了一个å¯ä»¥è¢«å…¬å¼€è®¿é—®çš„ :ref:`address
` 类型的状æ€å˜é‡ã€‚ +``address`` 类型是一个160ä½çš„值,且ä¸å…许任何算数æ“作。 +è¿™ç§ç±»åž‹é€‚åˆå­˜å‚¨åˆçº¦åœ°å€æˆ– :ref:`外部账户 ` 的密钥对。 -The keyword ``public`` automatically generates a function that allows you to access the current value of the state -variable from outside of the contract. Without this keyword, other contracts have no way to access the variable. -The code of the function generated by the compiler is equivalent -to the following (ignore ``external`` and ``view`` for now): +关键字 ``public`` 自动生æˆä¸€ä¸ªå‡½æ•°ï¼Œå…许您在这个åˆçº¦ä¹‹å¤–访问这个状æ€å˜é‡çš„当å‰å€¼ã€‚ +如果没有这个关键字,其他的åˆçº¦æ²¡æœ‰åŠžæ³•è®¿é—®è¿™ä¸ªå˜é‡ã€‚ +由编译器生æˆçš„函数的代ç å¤§è‡´å¦‚下所示(暂时忽略 ``external`` å’Œ ``view``): .. code-block:: solidity function minter() external view returns (address) { return minter; } -You could add a function like the above yourself, but you would have a function and state variable with the same name. -You do not need to do this, the compiler figures it out for you. +您å¯ä»¥è‡ªå·±æ·»åŠ ä¸€ä¸ªç±»ä¼¼ä¸Šè¿°çš„函数,但您会有åŒå的一个函数和一个å˜é‡ã€‚ +您ä¸éœ€è¦è¿™æ ·åšï¼Œç¼–译器会帮您解决这个问题。 .. index:: mapping -The next line, ``mapping(address => uint) public balances;`` also -creates a public state variable, but it is a more complex datatype. -The :ref:`mapping ` type maps addresses to :ref:`unsigned integers `. - +下一行, ``mapping(address => uint) public balances;`` 也创建了一个公共状æ€å˜é‡ï¼Œ +但它是一个更å¤æ‚çš„æ•°æ®ç±»åž‹ã€‚ +:ref:`映射 ` 类型将地å€æ˜ å°„到 :ref:`无符å·æ•´æ•° `。 + +<<<<<<< HEAD +映射å¯ä»¥è¢«çœ‹ä½œæ˜¯ `哈希表 `_, +它实际上是被åˆå§‹åŒ–的,因此æ¯ä¸€ä¸ªå¯èƒ½çš„键从一开始就存在,并被映射到一个值,其字节表示为全零的值。 +然而,它既ä¸å¯èƒ½èŽ·å¾—一个映射的所有键的列表,也ä¸å¯èƒ½èŽ·å¾—所有值的列表。 +因此,è¦ä¹ˆè®°ä½æ‚¨æ·»åŠ åˆ°æ˜ å°„中的内容,è¦ä¹ˆåœ¨ä¸éœ€è¦çš„情况下使用它。 +甚至更好的是,ä¿ç•™ä¸€ä¸ªåˆ—表,或者使用一个更åˆé€‚çš„æ•°æ®ç±»åž‹ã€‚ +======= Mappings can be seen as `hash tables `_ which are -virtually initialised such that every possible key exists from the start and is mapped to a +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 -The :ref:`getter function` created by the ``public`` keyword -is more complex in the case of a mapping. It looks like the -following: +而由 ``public`` 关键字创建的 :ref:`getter 函数 ` 则是更å¤æ‚一些的情况, +它大致如下所示: .. code-block:: solidity @@ -172,21 +165,17 @@ following: return balances[account]; } -You can use this function to query the balance of a single account. +您å¯ä»¥ç”¨è¿™ä¸ªå‡½æ•°æ¥æŸ¥è¯¢å•ä¸ªè´¦æˆ·çš„ä½™é¢ã€‚ .. index:: event -The line ``event Sent(address from, address to, uint amount);`` declares -an :ref:`"event" `, which is emitted in the last line of the function -``send``. Ethereum clients such as web applications can -listen for these events emitted on the blockchain without much -cost. As soon as it is emitted, the listener receives the -arguments ``from``, ``to`` and ``amount``, which makes it possible to track -transactions. +这一行 ``event Sent(address from, address to, uint amount);`` 声明了一个 :ref:`"事件" `, +它是在函数 ``send`` 的最åŽä¸€è¡Œå‘出的。以太åŠå®¢æˆ·ç«¯ï¼Œå¦‚网络应用,å¯ä»¥ç›‘å¬åŒºå—链上å‘出的这些事件,而ä¸éœ€è¦å¤ªå¤šçš„æˆæœ¬ã€‚ +一旦å‘出,监å¬å™¨å°±ä¼šæ”¶åˆ°å‚æ•° ``from``, ``to`` å’Œ ``amount``,这使得跟踪交易æˆä¸ºå¯èƒ½ã€‚ -To listen for this event, you could use the following -JavaScript code, which uses `web3.js `_ to create the ``Coin`` contract object, -and any user interface calls the automatically generated ``balances`` function from above: +为了监å¬è¿™ä¸ªäº‹ä»¶ï¼Œæ‚¨å¯ä»¥ä½¿ç”¨ä»¥ä¸‹æ–¹æ³• JavaScript 代ç ï¼Œ +使用 `web3.js `_ æ¥åˆ›å»º ``Coin`` åˆçº¦å¯¹è±¡ï¼Œ +然åŽåœ¨ä»»ä½•ç”¨æˆ·ç•Œé¢è°ƒç”¨ä¸Šé¢è‡ªåŠ¨ç”Ÿæˆçš„ ``balances`` 函数: .. code-block:: javascript @@ -203,400 +192,365 @@ and any user interface calls the automatically generated ``balances`` function f .. index:: coin -The :ref:`constructor` is a special function that is executed during the creation of the contract and -cannot be called afterwards. In this case, it permanently stores the address of the person creating the -contract. The ``msg`` variable (together with ``tx`` and ``block``) is a -:ref:`special global variable ` that -contains properties which allow access to the blockchain. ``msg.sender`` is -always the address where the current (external) function call came from. - -The functions that make up the contract, and that users and contracts can call are ``mint`` and ``send``. - -The ``mint`` function sends an amount of newly created coins to another address. The :ref:`require -` function call defines conditions that reverts all changes if not met. In this -example, ``require(msg.sender == minter);`` ensures that only the creator of the contract can call -``mint``. In general, the creator can mint as many tokens as they like, but at some point, this will -lead to a phenomenon called "overflow". Note that because of the default :ref:`Checked arithmetic -`, the transaction would revert if the expression ``balances[receiver] += amount;`` -overflows, i.e., when ``balances[receiver] + amount`` in arbitrary precision arithmetic is larger -than the maximum value of ``uint`` (``2**256 - 1``). This is also true for the statement -``balances[receiver] += amount;`` in the function ``send``. - -:ref:`Errors ` allow you to provide more information to the caller about -why a condition or operation failed. Errors are used together with the -:ref:`revert statement `. The ``revert`` statement unconditionally -aborts and reverts all changes similar to the ``require`` function, but it also -allows you to provide the name of an error and additional data which will be supplied to the caller -(and eventually to the front-end application or block explorer) so that -a failure can more easily be debugged or reacted upon. - -The ``send`` function can be used by anyone (who already -has some of these coins) to send coins to anyone else. If the sender does not have -enough coins to send, the ``if`` condition evaluates to true. As a result, the ``revert`` will cause the operation to fail -while providing the sender with error details using the ``InsufficientBalance`` error. +:ref:`constructor ` 是一个特殊的函数,åªåœ¨åˆ›å»ºåˆçº¦çš„过程中执行,事åŽä¸èƒ½å†è¢«è°ƒç”¨ã€‚ +在这ç§æƒ…况下,它永久地存储了创建åˆçº¦çš„人的地å€ã€‚ +``msg`` å˜é‡ï¼ˆä¸Ž ``tx`` å’Œ ``block`` 一起)是一个 :ref:`特殊全局å˜é‡ `, +其中包å«å…许访问区å—链的属性。 ``msg.sender`` 总是当å‰ï¼ˆå¤–部)函数调用的地å€ã€‚ + +最åŽï¼ŒçœŸæ­£è¢«ç”¨æˆ·æˆ–其他åˆçº¦æ‰€è°ƒç”¨çš„,以完æˆæœ¬åˆçº¦åŠŸèƒ½çš„方法是 ``mint`` å’Œ ``send``。 + +``mint`` 函数å‘é€ä¸€å®šæ•°é‡çš„新创建的代å¸åˆ°å¦ä¸€ä¸ªåœ°å€ã€‚ +:ref:`require ` 函数调用定义了一些æ¡ä»¶ï¼Œå¦‚æžœä¸æ»¡è¶³è¿™äº›æ¡ä»¶å°±ä¼šæ¢å¤æ‰€æœ‰çš„å˜åŒ–。 +在这个例å­ä¸­ï¼Œ ``require(msg.sender == minter);`` ç¡®ä¿åªæœ‰åˆçº¦çš„创建者å¯ä»¥è°ƒç”¨ ``mint``。 +一般æ¥è¯´ï¼Œåˆ›å»ºè€…å¯ä»¥éšå¿ƒæ‰€æ¬²åœ°é“¸é€ ä»£å¸ï¼Œä½†åœ¨æŸäº›æ—¶å€™ï¼Œè¿™å°†å¯¼è‡´ä¸€ç§å«åš "溢出" 的现象。 +请注æ„,由于默认的 :ref:`检查过的算术 `ï¼Œå¦‚æžœè¡¨è¾¾å¼ ``balances[receiver] += amount;`` 溢出, +å³å½“ä»»æ„精度算术中的 ``balances[receiver] + amount`` 大于 ``uint`` 的最大值( ``2**256 - 1``)时, +交易将被æ¢å¤ã€‚对于函数 ``send`` ä¸­çš„è¯­å¥ ``balances[receiver] += amount;`` 也是如此。 + +:ref:`错误(Errors) ` å…许您å‘调用者æ供更多关于一个æ¡ä»¶æˆ–æ“作失败原因的信æ¯ã€‚ +错误与 :ref:`æ¢å¤çŠ¶æ€ ` 一起使用。 ``revert`` 语å¥æ— æ¡ä»¶åœ°ä¸­æ­¢å’Œæ¢å¤æ‰€æœ‰çš„å˜åŒ–, +类似于 ``require`` 函数,但它也å…许您æ供错误的å称和é¢å¤–çš„æ•°æ®ï¼Œ +这些数æ®å°†æ供给调用者(并最终æ供给å‰ç«¯åº”用程åºæˆ–区å—资æºç®¡ç†å™¨ï¼‰ï¼Œä»¥ä¾¿æ›´å®¹æ˜“调试失败或åšå‡ºå应。 + +任何人(已ç»æ‹¥æœ‰ä¸€äº›è¿™æ ·çš„代å¸ï¼‰éƒ½å¯ä»¥ä½¿ç”¨ ``send`` 函数æ¥å‘é€ä»£å¸ç»™å…¶ä»–任何人。 +如果å‘é€è€…没有足够的代å¸å¯ä»¥å‘é€ï¼Œ 那么 ``if`` æ¡ä»¶å°±ä¼šä¸ºçœŸã€‚ +因此, ``revert`` 将导致æ“作失败,åŒæ—¶ä½¿ç”¨ ``InsufficientBalance`` 错误å‘å‘é€è€…æ供错误细节。 .. note:: - If you use - this contract to send coins to an address, you will not see anything when you - look at that address on a blockchain explorer, because the record that you sent - coins and the changed balances are only stored in the data storage of this - particular coin contract. By using events, you can create - a "blockchain explorer" that tracks transactions and balances of your new coin, - but you have to inspect the coin contract address and not the addresses of the - coin owners. + 如果您用这个åˆçº¦å‘一个地å€å‘é€ä»£å¸ï¼Œå½“您在区å—链æµè§ˆå™¨ä¸ŠæŸ¥çœ‹è¯¥åœ°å€æ—¶ï¼Œ + 您ä¸ä¼šçœ‹åˆ°ä»»ä½•ä¸œè¥¿ï¼Œå› ä¸ºæ‚¨å‘é€ä»£å¸çš„记录和å˜åŒ–çš„ä½™é¢åªå­˜å‚¨åœ¨è¿™ä¸ªç‰¹å®šçš„代å¸åˆçº¦çš„æ•°æ®å­˜å‚¨ä¸­ã€‚ + 通过使用事件,您å¯ä»¥åˆ›å»ºä¸€ä¸ª "区å—链æµè§ˆå™¨",跟踪您的新å¸çš„交易和余é¢ï¼Œ + 但您必须检查å¸åˆçº¦åœ°å€ï¼Œè€Œä¸æ˜¯å¸ä¸»çš„地å€ã€‚ .. _blockchain-basics: ***************** -Blockchain Basics +区å—链基础 ***************** -Blockchains as a concept are not too hard to understand for programmers. The reason is that -most of the complications (mining, `hashing `_, -`elliptic-curve cryptography `_, -`peer-to-peer networks `_, etc.) -are just there to provide a certain set of features and promises for the platform. Once you accept these -features as given, you do not have to worry about the underlying technology - or do you have -to know how Amazon's AWS works internally in order to use it? +对于程åºå‘˜æ¥è¯´ï¼ŒåŒºå—链这个概念并ä¸éš¾ç†è§£ï¼Œè¿™æ˜¯å› ä¸ºå¤§å¤šæ•°éš¾æ‡‚的东西 +(挖矿, `哈希 `_ , +`椭圆曲线密ç å­¦ `_, +`点对点网络(P2P) `_ 等) +都åªæ˜¯ç”¨äºŽæ供特定的功能和承诺。 +您åªéœ€æŽ¥å—这些既有的特性功能,ä¸å¿…关心底层技术, +比如,难é“您必须知é“亚马逊的 AWS 内部原ç†ï¼Œæ‚¨æ‰èƒ½ä½¿ç”¨å®ƒå—? .. index:: transaction -Transactions +交易/事务 ============ -A blockchain is a globally shared, transactional database. -This means that everyone can read entries in the database just by participating in the network. -If you want to change something in the database, you have to create a so-called transaction -which has to be accepted by all others. -The word transaction implies that the change you want to make (assume you want to change -two values at the same time) is either not done at all or completely applied. Furthermore, -while your transaction is being applied to the database, no other transaction can alter it. - -As an example, imagine a table that lists the balances of all accounts in an -electronic currency. If a transfer from one account to another is requested, -the transactional nature of the database ensures that if the amount is -subtracted from one account, it is always added to the other account. If due -to whatever reason, adding the amount to the target account is not possible, -the source account is also not modified. - +区å—链是全çƒå…±äº«çš„事务性数æ®åº“,这æ„味ç€æ¯ä¸ªäººéƒ½å¯åŠ å…¥ç½‘络æ¥é˜…读数æ®åº“中的记录。 +如果您想改å˜æ•°æ®åº“中的æŸäº›ä¸œè¥¿ï¼Œæ‚¨å¿…须创建一个被所有其他人所接å—的事务。 +事务一è¯æ„味ç€æ‚¨æƒ³åšçš„(å‡è®¾æ‚¨æƒ³è¦åŒæ—¶æ›´æ”¹ä¸¤ä¸ªå€¼ï¼‰ï¼Œè¦ä¹ˆä¸€ç‚¹æ²¡åšï¼Œè¦ä¹ˆå…¨éƒ¨å®Œæˆã€‚ +此外,当您的事务被应用到数æ®åº“时,其他事务ä¸èƒ½ä¿®æ”¹æ•°æ®åº“。 + +举个例å­ï¼Œè®¾æƒ³ä¸€å¼ è¡¨ï¼Œåˆ—出电å­è´§å¸ä¸­æ‰€æœ‰è´¦æˆ·çš„ä½™é¢ã€‚ +如果请求从一个账户转移到å¦ä¸€ä¸ªè´¦æˆ·ï¼Œ +æ•°æ®åº“的事务特性确ä¿äº†å¦‚果从一个账户扣除金é¢ï¼Œå®ƒæ€»è¢«æ·»åŠ åˆ°å¦ä¸€ä¸ªè´¦æˆ·ã€‚ +如果由于æŸäº›åŽŸå› ï¼Œæ— æ³•æ·»åŠ é‡‘é¢åˆ°ç›®æ ‡è´¦æˆ·æ—¶ï¼Œæºè´¦æˆ·ä¹Ÿä¸ä¼šå‘生任何å˜åŒ–。 + +<<<<<<< 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 -Blocks +åŒºå— ====== -One major obstacle to overcome is what (in Bitcoin terms) is called a "double-spend attack": -What happens if two transactions exist in the network that both want to empty an account? -Only one of the transactions can be valid, typically the one that is accepted first. -The problem is that "first" is not an objective term in a peer-to-peer network. - -The abstract answer to this is that you do not have to care. A globally accepted order of the transactions -will be selected for you, solving the conflict. The transactions will be bundled into what is called a "block" -and then they will be executed and distributed among all participating nodes. -If two transactions contradict each other, the one that ends up being second will -be rejected and not become part of the block. - -These blocks form a linear sequence in time, and that is where the word "blockchain" derives from. -Blocks are added to the chain at regular intervals, although these intervals may be subject to change in the future. -For the most up-to-date information, it is recommended to monitor the network, for example, on `Etherscan `_. - -As part of the "order selection mechanism" (which is called "mining") it may happen that +è¦å…‹æœçš„一个主è¦éšœç¢æ˜¯ï¼ˆç”¨æ¯”特å¸çš„术语)所谓的 “åŒèŠ±æ”»å‡» (double-spend attack)â€ï¼š +如果网络中存在两个交易,都想清空一个账户,会å‘生什么? +åªæœ‰å…¶ä¸­ä¸€ä¸ªäº¤æ˜“是有效的,通常是最先被接å—的那个。 +问题是,在点对点的网络中,"第一" ä¸æ˜¯ä¸€ä¸ªå®¢è§‚的术语。 + +对此,抽象的答案是,您ä¸å¿…在æ„。一个全çƒå…¬è®¤çš„交易顺åºå°†ä¸ºæ‚¨é€‰æ‹©ï¼Œ +解决这样的冲çªã€‚这些交易将被æ†ç»‘æˆæ‰€è°“çš„ "区å—", +然åŽå®ƒä»¬å°†åœ¨æ‰€æœ‰å‚与节点中执行和分å‘。 +如果两个交易相互矛盾,最终排在第二ä½çš„那个交易将被拒ç»ï¼Œä¸ä¼šæˆä¸ºåŒºå—的一部分。 + +这些区å—按时间形æˆäº†ä¸€ä¸ªçº¿æ€§åºåˆ—,这就是 “区å—链†一è¯çš„ç”±æ¥ã€‚ +区å—æ¯éš”一段时间就会被添加到链上,但这些时间间隔在未æ¥å¯èƒ½ä¼šå‘生å˜åŒ–。 +如需了解最新信æ¯ï¼Œå»ºè®®åœ¨ `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:: - Transactions are not guaranteed to be included in the next block or any specific future block, - since it is not up to the submitter of a transaction, but up to the miners to determine in which block the transaction is included. + 交易ä¸ä¿è¯è¢«åŒ…括在下一个区å—或任何特定的未æ¥åŒºå—中, + 因为这ä¸æ˜¯ç”±äº¤æ˜“çš„æ交者决定的,而是由矿工æ¥å†³å®šäº¤æ˜“被包括在哪个区å—中。 - If you want to schedule future calls of your contract, you can use - a smart contract automation tool or an oracle service. + 如果您想安排您的åˆçº¦çš„未æ¥è°ƒç”¨ï¼Œæ‚¨å¯ä»¥ä½¿ç”¨æ™ºèƒ½åˆçº¦è‡ªåŠ¨åŒ–工具或oracleæœåŠ¡ã€‚ .. _the-ethereum-virtual-machine: .. index:: !evm, ! ethereum virtual machine **************************** -The Ethereum Virtual Machine +以太åŠè™šæ‹Ÿæœº **************************** -Overview +概述 ======== -The Ethereum Virtual Machine or EVM is the runtime environment -for smart contracts in Ethereum. It is not only sandboxed but -actually completely isolated, which means that code running -inside the EVM has no access to network, filesystem or other processes. -Smart contracts even have limited access to other smart contracts. +以太åŠè™šæ‹Ÿæœºæˆ–EVM是以太åŠæ™ºèƒ½åˆçº¦çš„è¿è¡ŒçŽ¯å¢ƒã€‚ +它ä¸ä»…是沙盒å°è£…的,而且实际上是完全隔离的, +è¿™æ„味ç€åœ¨EVM内è¿è¡Œçš„代ç ä¸èƒ½è®¿é—®ç½‘络,文件系统或其他进程。 +甚至智能åˆçº¦ä¹‹é—´çš„访问也是å—é™çš„。 .. index:: ! account, address, storage, balance .. _accounts: -Accounts +账户 ======== -There are two kinds of accounts in Ethereum which share the same -address space: **External accounts** that are controlled by -public-private key pairs (i.e. humans) and **contract accounts** which are -controlled by the code stored together with the account. +在以太åŠæœ‰ä¸¤ç§å…±äº«åŒä¸€åœ°å€ç©ºé—´çš„账户: +**外部账户**,由公钥-ç§é’¥å¯¹ï¼ˆä¹Ÿå°±æ˜¯äººï¼‰æŽ§åˆ¶ï¼› +**åˆçº¦è´¦æˆ·**,由与账户一起存储的代ç æŽ§åˆ¶ã€‚ -The address of an external account is determined from -the public key while the address of a contract is -determined at the time the contract is created -(it is derived from the creator address and the number -of transactions sent from that address, the so-called "nonce"). +外部账户的地å€æ˜¯ç”±å…¬é’¥ç¡®å®šçš„, +而åˆçº¦çš„地å€æ˜¯åœ¨åˆçº¦åˆ›å»ºæ—¶ç¡®å®šçš„ +(它是由创建者地å€å’Œä»Žè¯¥åœ°å€å‘出的交易数é‡å¾—出的,å³æ‰€è°“çš„ "nonce")。 -Regardless of whether or not the account stores code, the two types are -treated equally by the EVM. +无论账户是å¦å­˜å‚¨ä»£ç ï¼Œè¿™ä¸¤ç§ç±»åž‹éƒ½è¢«EVM平等对待。 -Every account has a persistent key-value store mapping 256-bit words to 256-bit -words called **storage**. +æ¯ä¸ªè´¦æˆ·éƒ½æœ‰ä¸€ä¸ªæŒä¹…的键值存储,将256ä½çš„字映射到256ä½çš„字,称为 **存储**。 -Furthermore, every account has a **balance** in -Ether (in "Wei" to be exact, ``1 ether`` is ``10**18 wei``) which can be modified by sending transactions that -include Ether. +此外,æ¯ä¸ªè´¦æˆ·æœ‰ä¸€ä¸ªä»¥å¤ª **ä½™é¢** ( balance )(å•ä½æ˜¯â€œWeiâ€ï¼Œ ``1 ether`` 是 ``10**18 wei``), +ä½™é¢ä¼šå› ä¸ºå‘é€åŒ…å«ä»¥å¤ªå¸çš„交易而改å˜ã€‚ .. index:: ! transaction -Transactions +交易 ============ -A transaction is a message that is sent from one account to another -account (which might be the same or empty, see below). -It can include binary data (which is called "payload") and Ether. - -If the target account contains code, that code is executed and -the payload is provided as input data. - -If the target account is not set (the transaction does not have -a recipient or the recipient is set to ``null``), the transaction -creates a **new contract**. -As already mentioned, the address of that contract is not -the zero address but an address derived from the sender and -its number of transactions sent (the "nonce"). The payload -of such a contract creation transaction is taken to be -EVM bytecode and executed. The output data of this execution is -permanently stored as the code of the contract. -This means that in order to create a contract, you do not -send the actual code of the contract, but in fact code that -returns that code when executed. +交易å¯ä»¥çœ‹ä½œæ˜¯ä»Žä¸€ä¸ªå¸æˆ·å‘é€åˆ°å¦ä¸€ä¸ªå¸æˆ·çš„æ¶ˆæ¯ +(这里的账户,å¯èƒ½æ˜¯ç›¸åŒçš„或特殊的零å¸æˆ·ï¼Œè¯·å‚阅下文)。 +它能包å«ä¸€ä¸ªäºŒè¿›åˆ¶æ•°æ®ï¼ˆè¢«ç§°ä¸ºâ€œåˆçº¦è´Ÿè½½â€ï¼‰å’Œä»¥å¤ªã€‚ + +如果目标账户å«æœ‰ä»£ç ï¼Œæ­¤ä»£ç ä¼šè¢«æ‰§è¡Œï¼Œå¹¶ä»¥åˆçº¦è´Ÿè½½ï¼ˆäºŒè¿›åˆ¶æ•°æ®ï¼‰ 作为入å‚。 + +如果目标账户没有设置(交易没有接收者或接收者被设置为 ``null``), +交易会创建一个 **æ–°åˆçº¦**。 +正如已ç»æ到的,该åˆçº¦çš„地å€ä¸æ˜¯é›¶åœ°å€ï¼Œ +而是从å‘é€è€…和其å‘é€çš„交易数é‡ï¼ˆâ€œnonceâ€ï¼‰ä¸­å¾—出的地å€ã€‚ +è¿™ç§åˆçº¦åˆ›å»ºäº¤æ˜“的有效负载被认为是EVM字节ç å¹¶è¢«æ‰§è¡Œã€‚ +该执行的输出数æ®è¢«æ°¸ä¹…地存储为åˆçº¦çš„代ç ã€‚ +è¿™æ„味ç€ï¼Œä¸ºåˆ›å»ºä¸€ä¸ªåˆçº¦ï¼Œæ‚¨ä¸éœ€è¦å‘é€å®žé™…çš„åˆçº¦ä»£ç ï¼Œè€Œæ˜¯å‘é€èƒ½å¤Ÿäº§ç”Ÿåˆçº¦ä»£ç çš„代ç ã€‚ .. note:: - While a contract is being created, its code is still empty. - Because of that, you should not call back into the - contract under construction until its constructor has - finished executing. + 在åˆçº¦åˆ›å»ºçš„过程中,它的代ç è¿˜æ˜¯ç©ºçš„。 + 所以直到构造函数执行结æŸï¼Œæ‚¨éƒ½ä¸åº”该在其中调用åˆçº¦è‡ªå·±å‡½æ•°ã€‚ .. index:: ! gas, ! gas price Gas === -Upon creation, each transaction is charged with a certain amount of **gas** -that has to be paid for by the originator of the transaction (``tx.origin``). -While the EVM executes the -transaction, the gas is gradually depleted according to specific rules. -If the gas is used up at any point (i.e. it would be negative), -an out-of-gas exception is triggered, which ends execution and reverts all modifications -made to the state in the current call frame. +一ç»åˆ›å»ºï¼Œæ¯ç¬”交易都会被收å–一定数é‡çš„ **gas**, +这些 gas 必须由交易的å‘起人 ( ``tx.origin``)支付。 +在 EVM 执行交易时,gas æ ¹æ®ç‰¹å®šè§„则é€æ¸è€—尽。 +如果 gas 在æŸä¸€ç‚¹è¢«ç”¨å®Œï¼ˆå³å®ƒä¼šä¸ºè´Ÿï¼‰ï¼Œ +将触å‘一个 gas 耗尽异常, +这将结æŸæ‰§è¡Œå¹¶æ’¤é”€å½“å‰è°ƒç”¨æ ˆä¸­å¯¹çŠ¶æ€æ‰€åšçš„所有修改。 -This mechanism incentivizes economical use of EVM execution time -and also compensates EVM executors (i.e. miners / stakers) for their work. -Since each block has a maximum amount of gas, it also limits the amount -of work needed to validate a block. +此机制激励了对 EVM 执行时间的ç»æµŽåˆ©ç”¨ï¼Œ +并为 EVM 执行器(å³çŸ¿å·¥/æŒå¸è€…)的工作æ供补å¿ã€‚ +由于æ¯ä¸ªåŒºå—都有最大 gas é‡ï¼Œå› æ­¤è¿˜é™åˆ¶äº†éªŒè¯å—所需的工作é‡ã€‚ -The **gas price** is a value set by the originator of the transaction, who -has to pay ``gas_price * gas`` up front to the EVM executor. -If some gas is left after execution, it is refunded to the transaction originator. -In case of an exception that reverts changes, already used up gas is not refunded. +**gas price** 是交易å‘起人设定的值, +ä»–å¿…é¡»æå‰å‘ EVM 执行器支付 ``gas_price * gas``。 +如果执行åŽè¿˜å‰©ä¸‹ä¸€äº› gas,则退还给交易å‘起人。 +如果å‘生撤销更改的异常,已ç»ä½¿ç”¨çš„ gas ä¸ä¼šé€€è¿˜ã€‚ -Since EVM executors can choose to include a transaction or not, -transaction senders cannot abuse the system by setting a low gas price. +由于 EVM 执行器å¯ä»¥é€‰æ‹©åŒ…å«ä¸€ç¬”交易, +因此交易å‘é€è€…无法通过设置低 gas 价格滥用系统。 .. index:: ! storage, ! memory, ! stack -Storage, Memory and the Stack +存储,内存和栈 ============================= -The Ethereum Virtual Machine has three areas where it can store data: -storage, memory and the stack. - -Each account has a data area called **storage**, which is persistent between function calls -and transactions. -Storage is a key-value store that maps 256-bit words to 256-bit words. -It is not possible to enumerate storage from within a contract, it is -comparatively costly to read, and even more to initialise and modify storage. Because of this cost, -you should minimize what you store in persistent storage to what the contract needs to run. -Store data like derived calculations, caching, and aggregates outside of the contract. -A contract can neither read nor write to any storage apart from its own. - -The second data area is called **memory**, of which a contract obtains -a freshly cleared instance for each message call. Memory is linear and can be -addressed at byte level, but reads are limited to a width of 256 bits, while writes -can be either 8 bits or 256 bits wide. Memory is expanded by a word (256-bit), when -accessing (either reading or writing) a previously untouched memory word (i.e. any offset -within a word). At the time of expansion, the cost in gas must be paid. Memory is more -costly the larger it grows (it scales quadratically). - -The EVM is not a register machine but a stack machine, so all -computations are performed on a data area called the **stack**. It has a maximum size of -1024 elements and contains words of 256 bits. Access to the stack is -limited to the top end in the following way: -It is possible to copy one of -the topmost 16 elements to the top of the stack or swap the -topmost element with one of the 16 elements below it. -All other operations take the topmost two (or one, or more, depending on -the operation) elements from the stack and push the result onto the stack. -Of course it is possible to move stack elements to storage or memory -in order to get deeper access to the stack, -but it is not possible to just access arbitrary elements deeper in the stack -without first removing the top of the stack. +以太åŠè™šæ‹Ÿæœºæœ‰ä¸‰ä¸ªå­˜å‚¨æ•°æ®çš„区域:存储器,内存和堆栈。 + +æ¯ä¸ªè´¦æˆ·éƒ½æœ‰ä¸€ä¸ªç§°ä¸º **存储** çš„æ•°æ®åŒºï¼Œåœ¨å‡½æ•°è°ƒç”¨å’Œäº¤æ˜“之间是æŒä¹…的。 +存储是一个键值存储,将256ä½çš„字映射到256ä½çš„字。 +在åˆçº¦ä¸­æžšä¸¾å­˜å‚¨æ˜¯ä¸å¯èƒ½çš„,读å–çš„æˆæœ¬ç›¸å¯¹è¾ƒé«˜ï¼Œåˆå§‹åŒ–和修改存储的æˆæœ¬æ›´é«˜ã€‚ +由于这ç§æˆæœ¬ï¼Œæ‚¨åº”该把您存储在æŒä¹…性存储中的内容å‡å°‘到åˆçº¦è¿è¡Œæ‰€éœ€çš„程度。 +在åˆçº¦ä¹‹å¤–存储åƒæ´¾ç”Ÿè®¡ç®—,缓存和èšåˆçš„æ•°æ®ã€‚åˆçº¦æ—¢ä¸èƒ½è¯»ä¹Ÿä¸èƒ½å†™åˆ°é™¤å…¶è‡ªèº«ä»¥å¤–的任何存储。 + +第二个数æ®åŒºè¢«ç§°ä¸º **内存**,åˆçº¦åœ¨æ¯æ¬¡æ¶ˆæ¯è°ƒç”¨æ—¶éƒ½ä¼šèŽ·å¾—一个新清除的实例。 +内存是线性的,å¯ä»¥åœ¨å­—节级寻å€ï¼Œä½†è¯»çš„宽度é™åˆ¶åœ¨256ä½ï¼Œ +而写的宽度å¯ä»¥æ˜¯8ä½æˆ–256ä½ã€‚当访问(无论是读还是写)一个先å‰æœªè§¦åŠçš„内存字(å³ä¸€ä¸ªå­—内的任何å移)时, +内存被扩展一个字(256ä½ï¼‰ã€‚在扩展的时候,必须支付gasæˆæœ¬ã€‚ +内存越大,æˆæœ¬å°±è¶Šé«˜ï¼ˆå®ƒä»¥å¹³æ–¹çº§åˆ«æ‰©å±•ï¼‰ã€‚ + +EVM ä¸æ˜¯åŸºäºŽå¯„存器的,而是基于栈的,因此所有的计算都在一个被称为 **栈(stack)** 的区域执行。 +栈最大有1024个元素,æ¯ä¸ªå…ƒç´ é•¿åº¦æ˜¯ä¸€ä¸ªå­—(256ä½ï¼‰ã€‚对栈的访问åªé™äºŽå…¶é¡¶ç«¯ï¼Œé™åˆ¶æ–¹å¼ä¸ºï¼š +å…许拷è´æœ€é¡¶ç«¯çš„16个元素中的一个到栈顶,或者是交æ¢æ ˆé¡¶å…ƒç´ å’Œä¸‹é¢16个元素中的一个。 +所有其他æ“作都åªèƒ½å–最顶的两个(或一个,或更多,å–决于具体的æ“作)元素, +è¿ç®—åŽï¼ŒæŠŠç»“果压入栈顶。当然å¯ä»¥æŠŠæ ˆä¸Šçš„元素放到存储或内存中。 +但是无法åªè®¿é—®æ ˆä¸ŠæŒ‡å®šæ·±åº¦çš„那个元素,除éžå…ˆä»Žæ ˆé¡¶ç§»é™¤å…¶ä»–元素。 .. index:: ! instruction -Instruction Set +指令集 =============== -The instruction set of the EVM is kept minimal in order to avoid -incorrect or inconsistent implementations which could cause consensus problems. -All instructions operate on the basic data type, 256-bit words or on slices of memory -(or other byte arrays). -The usual arithmetic, bit, logical and comparison operations are present. -Conditional and unconditional jumps are possible. Furthermore, -contracts can access relevant properties of the current block -like its number and timestamp. +EVM的指令集应尽é‡ä¿æŒæœ€å°ï¼Œä»¥é¿å…ä¸æ­£ç¡®æˆ–ä¸ä¸€è‡´çš„实现,这å¯èƒ½å¯¼è‡´å…±è¯†é—®é¢˜ã€‚ +所有的指令都是在基本的数æ®ç±»åž‹ä¸Šæ“作的,256ä½çš„字或内存的片断(或其他字节数组)。 +具备常用的算术,ä½ï¼Œé€»è¾‘和比较æ“作。也å¯ä»¥åšåˆ°æœ‰æ¡ä»¶å’Œæ— æ¡ä»¶è·³è½¬ã€‚ +此外,åˆçº¦å¯ä»¥è®¿é—®å½“å‰åŒºå—的相关属性,比如它的编å·å’Œæ—¶é—´æˆ³ã€‚ -For a complete list, please see the :ref:`list of opcodes ` as part of the inline -assembly documentation. +关于完整的列表,请å‚è§ :ref:`æ“作ç åˆ—表 `,它是内è”汇编文档的一部分。 .. index:: ! message call, function;call -Message Calls +消æ¯è°ƒç”¨ ============= -Contracts can call other contracts or send Ether to non-contract -accounts by the means of message calls. Message calls are similar -to transactions, in that they have a source, a target, data payload, -Ether, gas and return data. In fact, every transaction consists of -a top-level message call which in turn can create further message calls. - -A contract can decide how much of its remaining **gas** should be sent -with the inner message call and how much it wants to retain. -If an out-of-gas exception happens in the inner call (or any -other exception), this will be signaled by an error value put onto the stack. -In this case, only the gas sent together with the call is used up. -In Solidity, the calling contract causes a manual exception by default in -such situations, so that exceptions "bubble up" the call stack. - -As already said, the called contract (which can be the same as the caller) -will receive a freshly cleared instance of memory and has access to the -call payload - which will be provided in a separate area called the **calldata**. -After it has finished execution, it can return data which will be stored at -a location in the caller's memory preallocated by the caller. -All such calls are fully synchronous. - -Calls are **limited** to a depth of 1024, which means that for more complex -operations, loops should be preferred over recursive calls. Furthermore, -only 63/64th of the gas can be forwarded in a message call, which causes a -depth limit of a little less than 1000 in practice. +åˆçº¦å¯ä»¥é€šè¿‡æ¶ˆæ¯è°ƒç”¨çš„æ–¹å¼æ¥è°ƒç”¨å…¶å®ƒåˆçº¦æˆ–者å‘é€ä»¥å¤ªå¸åˆ°éžåˆçº¦è´¦æˆ·ã€‚ +消æ¯è°ƒç”¨å’Œäº¤æ˜“éžå¸¸ç±»ä¼¼ï¼Œå®ƒä»¬éƒ½æœ‰ä¸€ä¸ªæºï¼Œç›®æ ‡ï¼Œæ•°æ®ï¼Œä»¥å¤ªå¸ï¼Œgas和返回数æ®ã€‚ +事实上æ¯ä¸ªäº¤æ˜“都由一个顶层消æ¯è°ƒç”¨ç»„æˆï¼Œè¿™ä¸ªæ¶ˆæ¯è°ƒç”¨åˆå¯åˆ›å»ºæ›´å¤šçš„消æ¯è°ƒç”¨ã€‚ + +åˆçº¦å¯ä»¥å†³å®šå®ƒå‰©ä½™çš„ **gas** 有多少应该éšå†…部消æ¯è°ƒç”¨ä¸€èµ·å‘é€ï¼Œæœ‰å¤šå°‘它想ä¿ç•™ã€‚ +如果在内部调用中å‘生了out-of-gas的异常(或任何其他异常),这将由一个被压入栈顶的错误值æ¥è¡¨ç¤ºã€‚ +在这ç§æƒ…况下,åªæœ‰ä¸Žè°ƒç”¨ä¸€èµ·å‘é€çš„gas被用完。 +在Solidity中,在这ç§æƒ…况下,å‘起调用的åˆçº¦é»˜è®¤ä¼šå¼•èµ·ä¸€ä¸ªæ‰‹åŠ¨å¼‚常, +所以异常会在调用栈上 "冒泡出æ¥"。 + +如å‰æ–‡æ‰€è¿°ï¼Œè¢«è°ƒç”¨çš„åˆçº¦ï¼ˆå¯ä»¥ä¸Žè°ƒç”¨è€…是åŒä¸€ä¸ªåˆçº¦ï¼‰å°†æ”¶åˆ°ä¸€ä¸ªæ–°æ¸…空的内存实例, +并å¯ä»¥è®¿é—®è°ƒç”¨çš„有效负载-由被称为 **calldata** 的独立区域所æ供的数æ®ã€‚ +在它执行完毕åŽï¼Œå®ƒå¯ä»¥è¿”回数æ®ï¼Œè¿™äº›æ•°æ®å°†è¢«å­˜å‚¨åœ¨è°ƒç”¨è€…内存中由调用者预先分é…çš„ä½ç½®ã€‚ +所有这样的调用都是完全åŒæ­¥çš„。 + +调用被 **é™åˆ¶** 在1024的深度,这æ„味ç€å¯¹äºŽæ›´å¤æ‚çš„æ“作,循环应优先于递归调用。 +此外,在一个消æ¯è°ƒç”¨ä¸­ï¼Œåªæœ‰63/64çš„gaså¯ä»¥è¢«è½¬å‘,这导致在实践中,深度é™åˆ¶ç•¥ä½ŽäºŽ1000。 .. index:: delegatecall, library -Delegatecall and Libraries +委托调用和库 ========================== -There exists a special variant of a message call, named **delegatecall** -which is identical to a message call apart from the fact that -the code at the target address is executed in the context (i.e. at the address) of the calling -contract and ``msg.sender`` and ``msg.value`` do not change their values. +存在一ç§ç‰¹æ®Šçš„消æ¯è°ƒç”¨ï¼Œè¢«ç§°ä¸º **委托调用(delegatecall)**, +除了目标地å€çš„代ç æ˜¯åœ¨è°ƒç”¨åˆçº¦çš„上下文(å³åœ°å€ï¼‰ä¸­æ‰§è¡Œï¼Œ +``msg.sender`` å’Œ ``msg.value`` 的值ä¸ä¼šæ›´æ”¹ä¹‹å¤–,其他与消æ¯è°ƒç”¨ç›¸åŒã€‚ -This means that a contract can dynamically load code from a different -address at runtime. Storage, current address and balance still -refer to the calling contract, only the code is taken from the called address. +è¿™æ„味ç€åˆçº¦å¯ä»¥åœ¨è¿è¡Œæ—¶åŠ¨æ€åœ°ä»Žä¸åŒçš„地å€åŠ è½½ä»£ç ã€‚ +存储,当å‰åœ°å€å’Œä½™é¢ä»ç„¶æŒ‡çš„是调用åˆçº¦ï¼Œåªæ˜¯ä»£ç å–自被调用的地å€ã€‚ -This makes it possible to implement the "library" feature in Solidity: -Reusable library code that can be applied to a contract's storage, e.g. in -order to implement a complex data structure. +这使得在Solidity中实现 “库†的功能æˆä¸ºå¯èƒ½ï¼š +å¯é‡å¤ä½¿ç”¨çš„库代ç ï¼Œå¯ä»¥æ”¾åœ¨ä¸€ä¸ªåˆçº¦çš„存储上,例如,用æ¥å®žçŽ°å¤æ‚çš„æ•°æ®ç»“构的库。 .. index:: log -Logs +日志 ==== -It is possible to store data in a specially indexed data structure -that maps all the way up to the block level. This feature called **logs** -is used by Solidity in order to implement :ref:`events `. -Contracts cannot access log data after it has been created, but they -can be efficiently accessed from outside the blockchain. -Since some part of the log data is stored in `bloom filters `_, it is -possible to search for this data in an efficient and cryptographically -secure way, so network peers that do not download the whole blockchain -(so-called "light clients") can still find these logs. +有一ç§ç‰¹æ®Šçš„å¯ç´¢å¼•çš„æ•°æ®ç»“构,其存储的数æ®å¯ä»¥ä¸€è·¯æ˜ å°„直到区å—层级。 +这个特性被称为 **日志(logs)** ,Solidity用它æ¥å®žçŽ° :ref:`事件 `。 +åˆçº¦åˆ›å»ºä¹‹åŽå°±æ— æ³•è®¿é—®æ—¥å¿—æ•°æ®ï¼Œä½†æ˜¯è¿™äº›æ•°æ®å¯ä»¥ä»ŽåŒºå—链外高效的访问。 +因为部分日志数æ®è¢«å­˜å‚¨åœ¨ `布隆过滤器(bloom filter) `_ 中, +我们å¯ä»¥é«˜æ•ˆå¹¶ä¸”加密安全地æœç´¢æ—¥å¿—,所以那些没有下载整个区å—链的网络节点(轻客户端)也å¯ä»¥æ‰¾åˆ°è¿™äº›æ—¥å¿—。 .. index:: contract creation -Create +创建 ====== -Contracts can even create other contracts using a special opcode (i.e. -they do not simply call the zero address as a transaction would). The only difference between -these **create calls** and normal message calls is that the payload data is -executed and the result stored as code and the caller / creator -receives the address of the new contract on the stack. +åˆçº¦ç”šè‡³å¯ä»¥é€šè¿‡ä¸€ä¸ªç‰¹æ®Šçš„指令æ¥åˆ›å»ºå…¶ä»–åˆçº¦ï¼ˆä¸æ˜¯ç®€å•çš„调用零地å€ï¼‰ã€‚ +创建åˆçº¦çš„调用 **create calls** 和普通消æ¯è°ƒç”¨çš„唯一区别在于,负载会被执行, +执行的结果被存储为åˆçº¦ä»£ç ï¼Œè°ƒç”¨è€…/创建者在栈上得到新åˆçº¦çš„地å€ã€‚ .. index:: ! selfdestruct, deactivate -Deactivate and Self-destruct +åœç”¨å’Œè‡ªæ¯ ============================ -The only way to remove code from the blockchain is when a contract at that -address performs the ``selfdestruct`` operation. The remaining Ether stored -at that address is sent to a designated target and then the storage and code -is removed from the state. Removing the contract in theory sounds like a good -idea, but it is potentially dangerous, as if someone sends Ether to removed -contracts, the Ether is forever lost. +从区å—链上删除代ç çš„唯一方法是当该地å€çš„åˆçº¦æ‰§è¡Œ ``selfdestruct`` æ“作。 +存储在该地å€çš„剩余以太å¸è¢«å‘é€åˆ°ä¸€ä¸ªæŒ‡å®šçš„目标,然åŽå­˜å‚¨å’Œä»£ç è¢«ä»ŽçŠ¶æ€ä¸­åˆ é™¤ã€‚ +删除åˆçº¦åœ¨ç†è®ºä¸Šå¬èµ·æ¥æ˜¯ä¸ªå¥½ä¸»æ„,但它有潜在的å±é™©æ€§ï¼Œ +因为如果有人å‘被删除的åˆçº¦å‘é€ä»¥å¤ªå¸ï¼Œä»¥å¤ªå¸å°±ä¼šæ°¸è¿œä¸¢å¤±ã€‚ .. warning:: - From version 0.8.18 and up, the use of ``selfdestruct`` in both Solidity and Yul will trigger a - deprecation warning, since the ``SELFDESTRUCT`` opcode will eventually undergo breaking changes in behavior - as stated in `EIP-6049 `_. +<<<<<<< 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:: - Even if a contract is removed by ``selfdestruct``, it is still part of the - history of the blockchain and probably retained by most Ethereum nodes. - So using ``selfdestruct`` is not the same as deleting data from a hard disk. + å³ä½¿ä¸€ä¸ªåˆçº¦é€šè¿‡ ``selfdestruct`` 删除,它ä»ç„¶æ˜¯åŒºå—链历å²çš„一部分, + å¯èƒ½è¢«å¤§å¤šæ•°ä»¥å¤ªåŠèŠ‚点ä¿ç•™ã€‚ + 因此,使用 ``selfdestruct`` 与从硬盘上删除数æ®ä¸ä¸€æ ·ã€‚ .. note:: - Even if a contract's code does not contain a call to ``selfdestruct``, - it can still perform that operation using ``delegatecall`` or ``callcode``. + 尽管一个åˆçº¦çš„代ç ä¸­æ²¡æœ‰æ˜¾å¼åœ°è°ƒç”¨ ``selfdestruct`` , + 它ä»ç„¶æœ‰å¯èƒ½é€šè¿‡ ``delegatecall`` 或 ``callcode`` 执行自æ¯æ“作。 -If you want to deactivate your contracts, you should instead **disable** them -by changing some internal state which causes all functions to revert. This -makes it impossible to use the contract, as it returns Ether immediately. +如果您想åœç”¨æ‚¨çš„åˆçº¦ï¼Œæ‚¨å¯ä»¥é€šè¿‡æ”¹å˜ä¸€äº›å†…部状æ€æ¥ **åœç”¨** 它们, +从而使å†æ¬¡è°ƒç”¨æ‰€æœ‰çš„功能都会被æ¢å¤ã€‚这样就无法使用åˆçº¦äº†ï¼Œå› ä¸ºå®ƒç«‹å³è¿”回以太。 .. index:: ! precompiled contracts, ! precompiles, ! contract;precompiled .. _precompiledContracts: -Precompiled Contracts +预编译åˆçº¦ ===================== +<<<<<<< HEAD +有一å°ç¾¤åˆçº¦åœ°å€æ˜¯ç‰¹æ®Šçš„。 ``1`` 和(包括) ``8`` 之间的地å€èŒƒå›´åŒ…å« â€œé¢„ç¼–è¯‘åˆçº¦â€œï¼Œ +å¯ä»¥åƒå…¶ä»–åˆçº¦ä¸€æ ·è¢«è°ƒç”¨ï¼Œä½†å®ƒä»¬çš„行为(和它们的gas消耗) +ä¸æ˜¯ç”±å­˜å‚¨åœ¨è¯¥åœ°å€çš„EVM代ç å®šä¹‰çš„(它们ä¸åŒ…å«ä»£ç ï¼‰ï¼Œ +而是由EVM执行环境本身实现。 +======= There is a small set of contract addresses that are special: The address range between ``1`` and (including) ``8`` contains "precompiled contracts" that can be called as any other contract but their behavior (and their gas consumption) is not defined by EVM code stored at that address (they do not contain code) but instead is implemented in the EVM execution environment itself. +>>>>>>> english/develop -Different EVM-compatible chains might use a different set of -precompiled contracts. It might also be possible that new -precompiled contracts are added to the Ethereum main chain in the future, -but you can reasonably expect them to always be in the range between -``1`` and ``0xffff`` (inclusive). +ä¸åŒçš„EVM兼容链å¯èƒ½ä½¿ç”¨ä¸åŒçš„预编译åˆçº¦é›†ã€‚ +未æ¥ä¹Ÿæœ‰å¯èƒ½åœ¨ä»¥å¤ªåŠä¸»é“¾ä¸Šæ·»åŠ æ–°çš„预编译åˆçº¦ï¼Œ +但您å¯ä»¥åˆç†åœ°é¢„期它们总是在 ``1`` å’Œ ``0xffff`` (包括)之间。 diff --git a/docs/ir-breaking-changes.rst b/docs/ir-breaking-changes.rst index 4917cfc7158d..952632f5b14b 100644 --- a/docs/ir-breaking-changes.rst +++ b/docs/ir-breaking-changes.rst @@ -3,18 +3,26 @@ .. _ir-breaking-changes: -********************************* -Solidity IR-based Codegen Changes -********************************* - -Solidity can generate EVM bytecode in two different ways: -Either directly from Solidity to EVM opcodes ("old codegen") or through -an intermediate representation ("IR") in Yul ("new codegen" or "IR-based codegen"). - -The IR-based code generator was introduced with an aim to not only allow -code generation to be more transparent and auditable but also -to enable more powerful optimization passes that span across functions. - +************************************* +基于 Solidity 中间表å¾çš„ Codegen å˜åŒ– +************************************* + +Solidity å¯ä»¥é€šè¿‡ä¸¤ç§ä¸åŒçš„æ–¹å¼ç”Ÿæˆ EVM 字节ç ï¼š +è¦ä¹ˆç›´æŽ¥ä»Ž Solidity 到 EVM æ“作ç ï¼ˆâ€œæ—§ç¼–ç â€ï¼‰ï¼Œ +è¦ä¹ˆé€šè¿‡åœ¨ Yul 中的中间表示法(“IRâ€ï¼‰ï¼ˆâ€œæ–°ç¼–ç â€ 或 “基于IRçš„ç¼–ç â€ï¼‰ã€‚ + +引入基于 IR 的代ç ç”Ÿæˆå™¨çš„目的是,ä¸ä»…使代ç ç”Ÿæˆæ›´åŠ é€æ˜Žå’Œå¯å®¡è®¡ï¼Œ +而且能够实现更强大的跨函数的优化通é“。 + +<<<<<<< HEAD +您å¯ä»¥åœ¨å‘½ä»¤è¡Œä¸­ä½¿ç”¨ ``--via-ir`` +或在 standard-json 中使用 ``{"viaIR": true}`` 选项æ¥å¯ç”¨å®ƒï¼Œ +我们鼓励大家å°è¯•ä¸€ä¸‹ï¼ + +由于一些原因,旧的和基于 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! @@ -23,35 +31,38 @@ 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 -Semantic Only Changes +仅有语义上的å˜åŒ– ===================== -This section lists the changes that are semantic-only, thus potentially -hiding new and different behavior in existing code. +本节列出了仅有语义的å˜åŒ–,从而有å¯èƒ½åœ¨çŽ°æœ‰çš„代ç ä¸­éšè—æ–°çš„å’Œä¸åŒçš„行为。 +<<<<<<< HEAD +- 在继承的情况下,状æ€å˜é‡åˆå§‹åŒ–的顺åºå·²ç»æ”¹å˜ã€‚ +======= .. _state-variable-initialization-order: - The order of state variable initialization has changed in case of inheritance. +>>>>>>> english/develop - The order used to be: + 以å‰çš„顺åºæ˜¯ï¼š - - All state variables are zero-initialized at the beginning. - - Evaluate base constructor arguments from most derived to most base contract. - - Initialize all state variables in the whole inheritance hierarchy from most base to most derived. - - Run the constructor, if present, for all contracts in the linearized hierarchy from most base to most derived. + - 所有的状æ€å˜é‡åœ¨å¼€å§‹æ—¶éƒ½è¢«é›¶åˆå§‹åŒ–。 + - 从最终派生åˆçº¦åˆ°æœ€åŸºç¡€çš„åˆçº¦è¯„估基础构造函数å‚数。 + - 从最基础的继承关系到最终派生的继承关系åˆå§‹åŒ–整个继承层次结构中的所有状æ€å˜é‡ã€‚ + - 如果存在,在线性化层次结构中从最基础的åˆçº¦åˆ°æœ€ç»ˆæ´¾ç”Ÿçš„åˆçº¦ä¾æ¬¡è¿è¡Œæž„造函数。 - New order: + 新的顺åºï¼š - - All state variables are zero-initialized at the beginning. - - Evaluate base constructor arguments from most derived to most base contract. - - For every contract in order from most base to most derived in the linearized hierarchy: + - 所有的状æ€å˜é‡åœ¨å¼€å§‹æ—¶éƒ½è¢«é›¶åˆå§‹åŒ–。 + - 从最终派生åˆçº¦åˆ°æœ€åŸºç¡€çš„åˆçº¦è¯„估基础构造函数å‚数。 + - 对于æ¯ä¸€ä¸ªåˆçº¦ï¼ŒæŒ‰ç…§ä»Žæœ€åŸºç¡€åˆ°æœ€ç»ˆæ´¾ç”Ÿçš„åˆçº¦çš„线性化层次结构的顺åºæ‰§è¡Œï¼š - 1. Initialize state variables. - 2. Run the constructor (if present). + 1. åˆå§‹åŒ–状æ€å˜é‡ã€‚ + 2. è¿è¡Œæž„造函数(如果存在)。 - This causes differences in contracts where the initial value of a state - variable relies on the result of the constructor in another contract: + 这导致了åˆçº¦ä¸­çš„差异,å³ä¸€ä¸ªçŠ¶æ€å˜é‡çš„åˆå§‹å€¼ä¾èµ–于å¦ä¸€ä¸ªåˆçº¦ä¸­æž„造函数的结果: .. code-block:: solidity @@ -71,16 +82,13 @@ hiding new and different behavior in existing code. uint public y = f(); } - Previously, ``y`` would be set to 0. This is due to the fact that we would first initialize state variables: First, ``x`` is set to 0, and when initializing ``y``, ``f()`` would return 0 causing ``y`` to be 0 as well. - With the new rules, ``y`` will be set to 42. We first initialize ``x`` to 0, then call A's constructor which sets ``x`` to 42. Finally, when initializing ``y``, ``f()`` returns 42 causing ``y`` to be 42. + 以å‰ï¼Œ ``y`` 会被设置为0。这是由于我们会先åˆå§‹åŒ–状æ€å˜é‡ï¼šé¦–先, ``x`` 被设置为0,当åˆå§‹åŒ– ``y`` 时, ``f()`` 将返回0,导致 ``y`` 也为0。 + 在新的规则下, ``y`` 将被设置为42。我们首先将 ``x`` åˆå§‹åŒ–为0,然åŽè°ƒç”¨ A 的构造函数,将 ``x`` 设置为42。最åŽï¼Œåœ¨åˆå§‹åŒ– ``y`` 时, ``f()`` 返回42,导致 ``y`` 为42。 -- When storage structs are deleted, every storage slot that contains - a member of the struct is set to zero entirely. Formerly, padding space - was left untouched. - Consequently, if the padding space within a struct is used to store data - (e.g. in the context of a contract upgrade), you have to be aware that - ``delete`` will now also clear the added member (while it wouldn't - have been cleared in the past). +- 当存储结构被删除时,包å«è¯¥ç»“æž„æˆå‘˜çš„æ¯ä¸ªå­˜å‚¨æ§½éƒ½è¢«å®Œå…¨è®¾ç½®ä¸ºé›¶ã€‚ + 以å‰ï¼Œå¡«å……空间是ä¸è¢«è§¦åŠ¨çš„。 + 因此,如果结构中的填充空间被用æ¥å­˜å‚¨æ•°æ®ï¼ˆä¾‹å¦‚在åˆçº¦å‡çº§çš„背景下), + 您必须注æ„, ``delete`` 现在也会清除添加的æˆå‘˜ï¼ˆè€Œåœ¨è¿‡åŽ»ä¸ä¼šè¢«æ¸…除)。 .. code-block:: solidity @@ -96,22 +104,21 @@ hiding new and different behavior in existing code. function f() public { // ... delete s; - // s occupies only first 16 bytes of the 32 bytes slot - // delete will write zero to the full slot + // såªå ç”¨äº†32个字节槽的å‰16个字节 + // delete 将把零写到完整的æ’槽中 } } - We have the same behavior for implicit delete, for example when array of structs is shortened. + 我们对éšå¼åˆ é™¤ä¹Ÿæœ‰åŒæ ·çš„行为,例如当结构体的数组被缩短时。 -- Function modifiers are implemented in a slightly different way regarding function parameters and return variables. - This especially has an effect if the placeholder ``_;`` is evaluated multiple times in a modifier. - In the old code generator, each function parameter and return variable has a fixed slot on the stack. - If the function is run multiple times because ``_;`` is used multiple times or used in a loop, then a - change to the function parameter's or return variable's value is visible in the next execution of the function. - The new code generator implements modifiers using actual functions and passes function parameters on. - This means that multiple evaluations of a function's body will get the same values for the parameters, - and the effect on return variables is that they are reset to their default (zero) value for each - execution. +- 关于函数å‚数和返回å˜é‡ï¼Œå‡½æ•°ä¿®æ”¹å™¨çš„实现方å¼ç•¥æœ‰ä¸åŒã€‚ + 如果å ä½ç¬¦ ``_;`` 在一个修饰符中被多次使用,这尤其有影å“。 + 在旧的代ç ç”Ÿæˆå™¨ä¸­ï¼Œæ¯ä¸ªå‡½æ•°å‚数和返回å˜é‡åœ¨å †æ ˆä¸­éƒ½æœ‰ä¸€ä¸ªå›ºå®šçš„槽。 + 如果因为多次使用 ``_;`` 而使函数è¿è¡Œå¤šæ¬¡ï¼Œæˆ–者在一个循环中使用, + 那么函数å‚数或返回å˜é‡çš„值的å˜åŒ–在函数的下一次执行中是å¯è§çš„。 + 新的代ç ç”Ÿæˆå™¨ä½¿ç”¨å®žé™…的函数æ¥å®žçŽ°ä¿®æ”¹å™¨ï¼Œå¹¶å°†å‡½æ•°å‚数传递下去。 + è¿™æ„味ç€å¯¹ä¸€ä¸ªå‡½æ•°ä¸»ä½“的多次使用将得到相åŒçš„å‚数值,而对返回å˜é‡çš„å½±å“是, + 它们在æ¯æ¬¡æ‰§è¡Œæ—¶éƒ½è¢«é‡ç½®ä¸ºå…¶é»˜è®¤å€¼ï¼ˆé›¶ï¼‰ã€‚ .. code-block:: solidity @@ -124,8 +131,8 @@ hiding new and different behavior in existing code. modifier mod() { _; _; } } - If you execute ``f(0)`` in the old code generator, it will return ``1``, while - it will return ``0`` when using the new code generator. + 如果您在旧的代ç ç”Ÿæˆå™¨ä¸­æ‰§è¡Œ ``f(0)``,它将返回 ``1``, + 而在使用新的代ç ç”Ÿæˆå™¨æ—¶ï¼Œå®ƒå°†è¿”回 ``0``。 .. code-block:: solidity @@ -143,26 +150,24 @@ hiding new and different behavior in existing code. function foo() external mod() returns (uint ret) { if (active) - ret = 1; // Same as ``return 1`` + ret = 1; // 与 ``return 1`` ç›¸åŒ } } - The function ``C.foo()`` returns the following values: + 函数 ``C.foo()`` 返回以下值: - - Old code generator: ``1`` as the return variable is initialized to ``0`` only once before the first ``_;`` - evaluation and then overwritten by the ``return 1;``. It is not initialized again for the second ``_;`` - evaluation and ``foo()`` does not explicitly assign it either (due to ``active == false``), thus it keeps - its first value. - - New code generator: ``0`` as all parameters, including return parameters, will be re-initialized before - each ``_;`` evaluation. + - 旧的代ç ç”Ÿæˆå™¨ï¼š ``1`` 作为返回å˜é‡åœ¨ç¬¬ä¸€æ¬¡ ``_;`` 使用å‰åªè¢«åˆå§‹åŒ–为 ``0``, + 然åŽè¢« ``return 1;`` 覆盖。在第二次 ``_;`` 使用时,它没有被å†æ¬¡åˆå§‹åŒ–, + 而且 ``foo()`` 也没有明确地分é…给它(由于 ``active == false``),因此它ä¿æŒäº†å®ƒçš„第一个值。 + - 新的代ç ç”Ÿæˆå™¨ï¼š ``0`` 作为所有å‚数,包括返回å‚数,将在æ¯æ¬¡ ``_;`` 使用å‰è¢«é‡æ–°åˆå§‹åŒ–。 .. index:: ! evaluation order; expression -- For the old code generator, the evaluation order of expressions is unspecified. - For the new code generator, we try to evaluate in source order (left to right), but do not guarantee it. - This can lead to semantic differences. +- 对于旧的代ç ç”Ÿæˆå™¨ï¼Œè¡¨è¾¾å¼çš„评估顺åºæ˜¯æ²¡æœ‰è§„定的。 + 对于新的代ç ç”Ÿæˆå™¨ï¼Œæˆ‘们试图按照æºé¡ºåºï¼ˆä»Žå·¦åˆ°å³ï¼‰è¿›è¡Œè¯„估,但并ä¸ä¿è¯è¿™ä¸€ç‚¹ã€‚ + è¿™å¯èƒ½ä¼šå¯¼è‡´è¯­ä¹‰ä¸Šçš„差异。 - For example: + 例如: .. code-block:: solidity @@ -174,16 +179,15 @@ hiding new and different behavior in existing code. } } - The function ``preincr_u8(1)`` returns the following values: + 函数 ``preincr_u8(1)`` 返回以下值: - - Old code generator: ``3`` (``1 + 2``) but the return value is unspecified in general - - New code generator: ``4`` (``2 + 2``) but the return value is not guaranteed + - 旧的代ç ç”Ÿæˆå™¨ï¼š ``3`` ( ``1 + 2`` ),但一般情况下返回值是ä¸æŒ‡å®šçš„ + - 新的代ç ç”Ÿæˆå™¨ï¼š ``4`` ( ``2 + 2`` ),但ä¸èƒ½ä¿è¯è¿”回值 .. index:: ! evaluation order; function arguments - On the other hand, function argument expressions are evaluated in the same order - by both code generators with the exception of the global functions ``addmod`` and ``mulmod``. - For example: + å¦ä¸€æ–¹é¢ï¼Œé™¤äº†å…¨å±€å‡½æ•° ``addmod`` å’Œ ``mulmod`` 外,两个代ç ç”Ÿæˆå™¨å¯¹å‡½æ•°å‚数表达å¼çš„评估顺åºæ˜¯ä¸€æ ·çš„。 + 例如: .. code-block:: solidity @@ -198,14 +202,13 @@ hiding new and different behavior in existing code. } } - The function ``g(1, 2)`` returns the following values: + 函数 ``g(1, 2)`` 返回以下值: - - Old code generator: ``10`` (``add(2 + 3, 2 + 3)``) but the return value is unspecified in general - - New code generator: ``10`` but the return value is not guaranteed + - 旧的代ç ç”Ÿæˆå™¨ï¼š ``10`` ( ``add(2+3, 2+3)`` ),但返回值一般ä¸æŒ‡å®šã€‚ + - 新的代ç ç”Ÿæˆå™¨ï¼š ``10``,但ä¸èƒ½ä¿è¯è¿”回值 - The arguments to the global functions ``addmod`` and ``mulmod`` are evaluated right-to-left by the old code generator - and left-to-right by the new code generator. - For example: + 全局函数 ``addmod`` å’Œ ``mulmod`` çš„å‚数由旧代ç ç”Ÿæˆå™¨ä»Žå³å‘左评估,新代ç ç”Ÿæˆå™¨ä»Žå·¦å‘å³è¯„估。 + 例如: .. code-block:: solidity @@ -214,24 +217,23 @@ hiding new and different behavior in existing code. contract C { function f() public pure returns (uint256 aMod, uint256 mMod) { uint256 x = 3; - // Old code gen: add/mulmod(5, 4, 3) - // New code gen: add/mulmod(4, 5, 5) + // 旧的代ç ç”Ÿæˆå™¨ï¼š add/mulmod(5, 4, 3) + // 新的代ç ç”Ÿæˆå™¨ï¼š add/mulmod(4, 5, 5) aMod = addmod(++x, ++x, x); mMod = mulmod(++x, ++x, x); } } - The function ``f()`` returns the following values: + 函数 ``f()`` 返回以下值: - - Old code generator: ``aMod = 0`` and ``mMod = 2`` - - New code generator: ``aMod = 4`` and ``mMod = 0`` + - 旧的代ç ç”Ÿæˆå™¨ï¼š ``aMod = 0`` å’Œ ``mMod = 2`` + - 新的代ç ç”Ÿæˆå™¨ï¼š ``aMod = 4`` å’Œ ``mMod = 0`` -- The new code generator imposes a hard limit of ``type(uint64).max`` - (``0xffffffffffffffff``) for the free memory pointer. Allocations that would - increase its value beyond this limit revert. The old code generator does not - have this limit. +- 新的代ç ç”Ÿæˆå™¨å¯¹è‡ªç”±å†…存指针施加了一个硬性é™åˆ¶ ``type(uint64).max`` + ( ``0xffffffffffffffff``)。其增加值超过这个é™åˆ¶çš„分é…会被æ¢å¤ã€‚ + 旧的代ç ç”Ÿæˆå™¨æ²¡æœ‰è¿™ä¸ªé™åˆ¶ã€‚ - For example: + 例如: .. code-block:: solidity :force: @@ -241,51 +243,51 @@ hiding new and different behavior in existing code. contract C { function f() public { uint[] memory arr; - // allocation size: 576460752303423481 - // assumes freeMemPtr points to 0x80 initially + // 分é…空间: 576460752303423481 + // å‡è®¾freeMemPtr最åˆæŒ‡å‘0x80 uint solYulMaxAllocationBeforeMemPtrOverflow = (type(uint64).max - 0x80 - 31) / 32; - // freeMemPtr overflows UINT64_MAX + // freeMemPtr å›  UINT64_MAX é™åˆ¶æº¢å‡º arr = new uint[](solYulMaxAllocationBeforeMemPtrOverflow); } } - The function ``f()`` behaves as follows: + 函数 ``f()`` 的作用如下: - - Old code generator: runs out of gas while zeroing the array contents after the large memory allocation - - New code generator: reverts due to free memory pointer overflow (does not run out of gas) + - 旧的代ç ç”Ÿæˆå™¨ï¼šåœ¨å¤§å†…存分é…åŽå¯¹æ•°ç»„内容进行清零时耗尽了gas + - 新的代ç ç”Ÿæˆå™¨ï¼šç”±äºŽè‡ªç”±å†…存指针溢出而还原(ä¸ä¼šè€—å°½gas)。 -Internals +内部结构 ========= -Internal function pointers +内部函数指针 -------------------------- .. index:: function pointers -The old code generator uses code offsets or tags for values of internal function pointers. This is especially complicated since -these offsets are different at construction time and after deployment and the values can cross this border via storage. -Because of that, both offsets are encoded at construction time into the same value (into different bytes). +旧的代ç ç”Ÿæˆå™¨å¯¹å†…部函数指针的值使用代ç å移é‡æˆ–标签。 +这一点特别å¤æ‚,因为这些å移é‡åœ¨æž„造时和部署åŽæ˜¯ä¸åŒçš„,而且这些值å¯ä»¥é€šè¿‡å­˜å‚¨è·¨è¶Šè¿™ä¸ªè¾¹ç•Œã€‚ +正因为如此,这两个å移é‡åœ¨æž„造时被编ç ä¸ºåŒä¸€ä¸ªå€¼ï¼ˆè¿›å…¥ä¸åŒçš„字节)。 -In the new code generator, function pointers use internal IDs that are allocated in sequence. Since calls via jumps are not possible, -calls through function pointers always have to use an internal dispatch function that uses the ``switch`` statement to select -the right function. +在新的代ç ç”Ÿæˆå™¨ä¸­ï¼Œå‡½æ•°æŒ‡é’ˆä½¿ç”¨ä¾æ¬¡åˆ†é…的内部ID。 +由于通过跳转的调用是ä¸å¯èƒ½çš„,通过函数指针的调用总是è¦ä½¿ç”¨å†…部调度函数, +使用 ``switch`` 语å¥æ¥é€‰æ‹©æ­£ç¡®çš„函数。 -The ID ``0`` is reserved for uninitialized function pointers which then cause a panic in the dispatch function when called. +ID ``0`` 是为未åˆå§‹åŒ–的函数指针ä¿ç•™çš„,这些指针在被调用时,会引起调度函数的panic错误。 -In the old code generator, internal function pointers are initialized with a special function that always causes a panic. -This causes a storage write at construction time for internal function pointers in storage. +在旧的代ç ç”Ÿæˆå™¨ä¸­ï¼Œå†…部函数指针是用一个特殊的函数åˆå§‹åŒ–的,它总是引起panic错误。 +这导致在构造时对存储中的内部函数指针进行存储写入。 -Cleanup +æ¸…ç† ------- .. index:: cleanup, dirty bits -The old code generator only performs cleanup before an operation whose result could be affected by the values of the dirty bits. -The new code generator performs cleanup after any operation that can result in dirty bits. -The hope is that the optimizer will be powerful enough to eliminate redundant cleanup operations. +旧的代ç ç”Ÿæˆå™¨åªåœ¨æ“作å‰æ‰§è¡Œæ¸…ç†ï¼Œè€Œæ“作的结果å¯èƒ½ä¼šå—到è„ä½å€¼çš„å½±å“。 +新的代ç ç”Ÿæˆå™¨åœ¨ä»»ä½•å¯èƒ½å¯¼è‡´è„ä½çš„æ“作之åŽæ‰§è¡Œæ¸…ç†ã€‚ +我们希望优化器能够强大到足以消除多余的清ç†æ“作。 -For example: +例如: .. code-block:: solidity :force: @@ -303,11 +305,11 @@ For example: } } -The function ``f(1)`` returns the following values: +函数 ``f(1)`` 返回以下值: -- Old code generator: (``fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe``, ``00000000000000000000000000000000000000000000000000000000000000fe``) -- New code generator: (``00000000000000000000000000000000000000000000000000000000000000fe``, ``00000000000000000000000000000000000000000000000000000000000000fe``) +- 旧的代ç ç”Ÿæˆå™¨ï¼šï¼ˆ ``fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe``, ``00000000000000000000000000000000000000000000000000000000000000fe``) +- 新的代ç ç”Ÿæˆå™¨ï¼šï¼ˆ ``00000000000000000000000000000000000000000000000000000000000000fe``, ``00000000000000000000000000000000000000000000000000000000000000fe``) -Note that, unlike the new code generator, the old code generator does not perform a cleanup after the bit-not assignment (``a = ~a``). -This results in different values being assigned (within the inline assembly block) to return value ``r1`` between the old and new code generators. -However, both code generators perform a cleanup before the new value of ``a`` is assigned to ``r2``. +请注æ„,与新的代ç ç”Ÿæˆå™¨ä¸åŒï¼Œæ—§çš„代ç ç”Ÿæˆå™¨åœ¨ä½å–å赋值( ``a = ~a`` )åŽæ²¡æœ‰è¿›è¡Œæ¸…ç†ã€‚ +这导致新旧代ç ç”Ÿæˆå™¨ä¹‹é—´å¯¹è¿”回值 ``r1`` 的赋值(在内è”汇编å—内)ä¸åŒã€‚ +然而,两个代ç ç”Ÿæˆå™¨åœ¨ ``a`` 的新值被分é…到 ``r2`` 之å‰éƒ½è¿›è¡Œäº†æ¸…ç†ã€‚ diff --git a/docs/language-influences.rst b/docs/language-influences.rst index e4f0ab69023b..9e6bf59b29ac 100644 --- a/docs/language-influences.rst +++ b/docs/language-influences.rst @@ -1,25 +1,20 @@ ################### -Language Influences +语言的影å“å› ç´  ################### -Solidity is a `curly-bracket language `_ -that has been influenced and inspired by several well-known programming languages. +Solidityæ˜¯ä¸€ç§ `花括å·è¯­è¨€ `_, +å—到几ç§è‘—å编程语言的影å“å’Œå¯å‘。 -Solidity is most profoundly influenced by C++, but also borrowed concepts from languages like -Python, JavaScript, and others. +Solidityå—C++çš„å½±å“最深,但也借用了Python,JavaScript等语言的概念。 -The influence from C++ can be seen in the syntax for variable declarations, for loops, the concept -of overloading functions, implicit and explicit type conversions and many other details. +从å˜é‡å£°æ˜Žçš„语法,for循环,é‡è½½å‡½æ•°çš„概念,éšå¼å’Œæ˜¾å¼ç±»åž‹è½¬æ¢ä»¥åŠè®¸å¤šå…¶ä»–细节中å¯ä»¥çœ‹å‡ºC++çš„å½±å“。 -In the early days of the language, Solidity used to be partly influenced by JavaScript. -This was due to function-level scoping of variables and the use of the keyword ``var``. -The JavaScript influence was reduced starting from version 0.4.0. -Now, the main remaining similarity to JavaScript is that functions are defined using the keyword -``function``. Solidity also supports import syntax and semantics that -are similar to those available in JavaScript. Besides those points, Solidity looks like -most other curly-bracket languages and has no major JavaScript influence anymore. +这是由于å˜é‡çš„函数级范围和关键字 ``var`` 的使用。 +从0.4.0版本开始,JavaScriptçš„å½±å“å·²ç»å‡å°‘。 +现在,剩下的与JavaScript的主è¦ç›¸ä¼¼ä¹‹å¤„是,使用关键字 ``function`` æ¥å®šä¹‰å‡½æ•°ã€‚ +Solidity还支æŒå¯¼å…¥è¯­æ³•å’Œè¯­ä¹‰ï¼Œè¿™äº›éƒ½ä¸ŽJavaScript中的相似。 +除了这些点,Solidity看起æ¥å’Œå…¶ä»–大多数花括å·è¯­è¨€ä¸€æ ·ï¼Œä¸å†æœ‰ä¸»è¦çš„JavaScriptå½±å“。 -Another influence to Solidity was Python. Solidity's modifiers were added trying to model -Python's decorators with a much more restricted functionality. Furthermore, multiple inheritance, C3 linearization, -and the ``super`` keyword are taken from Python as well as the general assignment and copy semantics of value -and reference types. +对Solidityçš„å¦ä¸€ä¸ªå½±å“是Python。 +Solidity的修改器是为了模拟Python的装饰器而添加的,但其功能å—到很大é™åˆ¶ã€‚ +此外,多é‡ç»§æ‰¿ï¼ŒC3线性化和 ``super`` 关键字以åŠå€¼å’Œå¼•ç”¨ç±»åž‹çš„一般赋值和å¤åˆ¶è¯­ä¹‰éƒ½æ¥è‡ªPython。 diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst index 600f2ed0f453..b094b78eb154 100644 --- a/docs/layout-of-source-files.rst +++ b/docs/layout-of-source-files.rst @@ -1,223 +1,215 @@ -******************************** -Layout of a Solidity Source File -******************************** +********************** +Solidity æºæ–‡ä»¶ç»“æž„ +********************** -Source files can contain an arbitrary number of -:ref:`contract definitions`, import_ , -:ref:`pragma` and :ref:`using for` directives and -:ref:`struct`, :ref:`enum`, :ref:`function`, :ref:`error` -and :ref:`constant variable` definitions. +æºæ–‡ä»¶å¯ä»¥åŒ…å«ä»»æ„æ•°é‡çš„ +:ref:`contract 定义`, import_ 指令, +:ref:`pragma ` 指令和 :ref:`using for` 指令 +å’Œ :ref:`struct`, :ref:`enum`, :ref:`function`, :ref:`error` +ä»¥åŠ :ref:`constant å˜é‡` 的定义。 .. index:: ! license, spdx -SPDX License Identifier +SPDX 许å¯æ ‡è¯†ç¬¦ ======================= -Trust in smart contracts can be better established if their source code -is available. Since making source code available always touches on legal problems -with regards to copyright, the Solidity compiler encourages the use -of machine-readable `SPDX license identifiers `_. -Every source file should start with a comment indicating its license: +如果智能åˆçº¦çš„æºä»£ç æ˜¯å…¬å¼€çš„,就å¯ä»¥æ›´å¥½åœ°å»ºç«‹å¯¹æ™ºèƒ½åˆçº¦çš„信任。 +由于æä¾›æºä»£ç æ€»æ˜¯æ¶‰åŠåˆ°ç‰ˆæƒæ–¹é¢çš„法律问题, +Solidity 编译器鼓励使用机器å¯è¯»çš„ `SPDX 许å¯æ ‡è¯†ç¬¦ `_ 。 +æ¯ä¸ªæºæ–‡ä»¶éƒ½åº”该以一个注释开始,表明其许å¯è¯ ``// SPDX-License-Identifier: MIT`` -The compiler does not validate that the license is part of the -`list allowed by SPDX `_, but -it does include the supplied string in the :ref:`bytecode metadata `. +编译器ä¸ä¼šéªŒè¯è®¸å¯è¯æ˜¯å¦å±žäºŽ `SPDX许å¯çš„列表 `_, +但它确实包括在 :ref:`字节ç å…ƒæ•°æ®ï¼ˆbytecode metadata) ` æ供的字符串中。 -If you do not want to specify a license or if the source code is -not open-source, please use the special value ``UNLICENSED``. -Note that ``UNLICENSED`` (no usage allowed, not present in SPDX license list) -is different from ``UNLICENSE`` (grants all rights to everyone). -Solidity follows `the npm recommendation `_. +如果您ä¸æƒ³æŒ‡å®šä¸€ä¸ªè®¸å¯ï¼Œæˆ–者æºä»£ç ä¸æ˜¯å¼€æºçš„, +请使用特殊值 ``UNLICENSED``。请注æ„, ``UNLICENSED`` (ä¸å…许使用, +ä¸å­˜åœ¨äºŽSPDX许å¯è¯åˆ—表中)与 ``UNLICENSE`` (授予所有人所有æƒåˆ©ï¼‰ä¸åŒã€‚ +Solidity éµå¾ª `npm 的推è `_。 -Supplying this comment of course does not free you from other -obligations related to licensing like having to mention -a specific license header in each source file or the -original copyright holder. +æ供这个注释并ä¸èƒ½ä½¿æ‚¨æ‘†è„±ä¸Žè®¸å¯æœ‰å…³çš„其他义务, +如必须在æ¯ä¸ªæºæ–‡ä»¶ä¸­æ到特定的许å¯å¤´æˆ–原始版æƒäººã€‚ -The comment is recognized by the compiler anywhere in the file at the -file level, but it is recommended to put it at the top of the file. +编译器å¯ä»¥åœ¨æ–‡ä»¶çš„任何ä½ç½®è¯†åˆ«è¯¥æ³¨é‡Šï¼Œ +但建议把它放在文件的顶部。 +<<<<<<< HEAD +关于如何使用 SPDX 许å¯è¯æ ‡è¯†çš„更多信æ¯å¯ä»¥åœ¨ `SPDX 网站 `_ 中找到。 +======= More information about how to use SPDX license identifiers can be found at the `SPDX website `_. +>>>>>>> english/develop .. index:: ! pragma .. _pragma: -Pragmas -======= +编译指示 +========== -The ``pragma`` keyword is used to enable certain compiler features -or checks. A pragma directive is always local to a source file, so -you have to add the pragma to all your files if you want to enable it -in your whole project. If you :ref:`import` another file, the pragma -from that file does *not* automatically apply to the importing file. +``pragma`` 关键字用于å¯ç”¨æŸäº›ç¼–译器特性或检查。 +一个 pragma 指令始终是æºæ–‡ä»¶çš„本地指令, +所以如果您想在整个项目中使用 pragma 指令, +您必须在您的所有文件中添加这个指令。 +如果您 :ref:`import` å¦ä¸€ä¸ªæ–‡ä»¶ï¼Œ +该文件的 pragma 指令 *ä¸ä¼š* 自动应用于导入文件。 .. index:: ! pragma;version .. _version_pragma: -Version Pragma +版本编译指示 -------------- -Source files can (and should) be annotated with a version pragma to reject -compilation with future compiler versions that might introduce incompatible -changes. We try to keep these to an absolute minimum and -introduce them in a way that changes in semantics also require changes -in the syntax, but this is not always possible. Because of this, it is always -a good idea to read through the changelog at least for releases that contain -breaking changes. These releases always have versions of the form -``0.x.0`` or ``x.0.0``. +æºæ–‡ä»¶å¯ä»¥ï¼ˆè€Œä¸”应该)用版本 pragma 指令æ¥æ³¨é‡Šï¼Œ +以拒ç»ç”¨æœªæ¥çš„编译器版本进行编译,因为这å¯èƒ½ä¼šå¼•å…¥ä¸å…¼å®¹çš„å˜åŒ–。 +我们力图把这类å˜æ›´åšåˆ°å°½å¯èƒ½å°ï¼Œ +我们需è¦ä»¥ä¸€ç§å½“修改语义时必须åŒæ­¥ä¿®æ”¹è¯­æ³•çš„æ–¹å¼å¼•å…¥å˜æ›´ï¼Œ +当然这有时候也难以åšåˆ°ã€‚正因为如此, +至少在包å«é‡å¤§å˜åŒ–的版本中,通读一下更新日志总是一个好主æ„。 +这些版本总是有 ``0.x.0`` 或 ``x.0.0`` å½¢å¼çš„版本。 -The version pragma is used as follows: ``pragma solidity ^0.5.2;`` +版本编译指示使用如下: ``pragma solidity ^0.5.2;`` -A source file with the line above does not compile with a compiler earlier than version 0.5.2, -and it also does not work on a compiler starting from version 0.6.0 (this -second condition is added by using ``^``). Because -there will be no breaking changes until version ``0.6.0``, you can -be sure that your code compiles the way you intended. The exact version of the -compiler is not fixed, so that bugfix releases are still possible. +带有上述代ç çš„æºæ–‡ä»¶åœ¨ 0.5.2 版本之å‰çš„编译器上ä¸èƒ½ç¼–译, +在 0.6.0 版本之åŽçš„编译器上也ä¸èƒ½å·¥ä½œï¼ˆè¿™ç¬¬äºŒä¸ªæ¡ä»¶æ˜¯é€šè¿‡ä½¿ç”¨ ``^`` 添加的)。 +因为在 ``0.6.0`` 版本之å‰ä¸ä¼šæœ‰ä»»ä½•é‡å¤§çš„å˜åŒ–, +所以您å¯ä»¥ç¡®ä¿¡æ‚¨çš„代ç æ˜¯æŒ‰ç…§æ‚¨çš„预期编译的。 +上é¢ä¾‹å­ä¸­ä¸å›ºå®šç¼–译器的具体版本å·ï¼Œå› æ­¤ç¼–译器的补ä¸ç‰ˆä¹Ÿå¯ä»¥ä½¿ç”¨ã€‚ -It is possible to specify more complex rules for the compiler version, -these follow the same syntax used by `npm `_. +å¯ä»¥ä¸ºç¼–译器版本指定更å¤æ‚的规则, +这些规则与 `npm `_ 使用相åŒçš„语法。 .. note:: - Using the version pragma *does not* change the version of the compiler. - It also *does not* enable or disable features of the compiler. It just - instructs the compiler to check whether its version matches the one - required by the pragma. If it does not match, the compiler issues - an error. + 使用版本 pragma 指令 *ä¸ä¼š* 改å˜ç¼–译器的版本。 + 它也 *ä¸ä¼š* å¯ç”¨æˆ–ç¦ç”¨ç¼–译器的功能。 + 它åªæ˜¯æŒ‡ç¤ºç¼–译器检查它的版本是å¦ä¸Žç¼–译指示所è¦æ±‚的版本一致。 + 如果ä¸åŒ¹é…,编译器会å‘出一个错误。 .. index:: ! ABI coder, ! pragma; abicoder, pragma; ABIEncoderV2 .. _abi_coder: -ABI Coder Pragma +ABIç¼–ç ç¼–译指示 ---------------- -By using ``pragma abicoder v1`` or ``pragma abicoder v2`` you can -select between the two implementations of the ABI encoder and decoder. +通过使用 ``pragma abicoder v1`` 或 ``pragma abicoder v2`` , +您å¯ä»¥é€‰æ‹©ABIç¼–ç å™¨å’Œè§£ç å™¨çš„两ç§å®žçŽ°ã€‚ -The new ABI coder (v2) is able to encode and decode arbitrarily nested -arrays and structs. Apart from supporting more types, it involves more extensive -validation and safety checks, which may result in higher gas costs, but also heightened -security. It is considered -non-experimental as of Solidity 0.6.0 and it is enabled by default starting -with Solidity 0.8.0. The old ABI coder can still be selected using ``pragma abicoder v1;``. +æ–°çš„ ABI ç¼–ç å™¨ï¼ˆv2)能够对任æ„嵌套的数组和结构进行编ç å’Œè§£ç ã€‚ +除了支æŒæ›´å¤šçš„类型外,它还涉åŠæ›´å¹¿æ³›çš„验è¯å’Œå®‰å…¨æ£€æŸ¥ï¼Œ +è¿™å¯èƒ½å¯¼è‡´æ›´é«˜çš„气体æˆæœ¬ï¼Œä½†ä¹Ÿæ高了安全性。 +从 Solidity 0.6.0 开始,它被认为是éžå®žéªŒæ€§çš„, +并且从 Solidity 0.8.0 开始,它被默认å¯ç”¨ã€‚ +旧的 ABI ç¼–ç å™¨ä»ç„¶å¯ä»¥ä½¿ç”¨ ``pragma abicoder v1;`` æ¥é€‰æ‹©ã€‚ -The set of types supported by the new encoder is a strict superset of -the ones supported by the old one. Contracts that use it can interact with ones -that do not without limitations. The reverse is possible only as long as the -non-``abicoder v2`` contract does not try to make calls that would require -decoding types only supported by the new encoder. The compiler can detect this -and will issue an error. Simply enabling ``abicoder v2`` for your contract is -enough to make the error go away. +æ–°ç¼–ç å™¨æ‰€æ”¯æŒçš„类型集是旧编ç å™¨æ‰€æ”¯æŒçš„类型的一个严格超集。 +使用新编ç å™¨çš„åˆçº¦å¯ä»¥ä¸Žä¸ä½¿ç”¨æ–°ç¼–ç å™¨çš„åˆçº¦è¿›è¡Œäº¤äº’,没有任何é™åˆ¶ã€‚ +åªæœ‰å½“éž ``abicoder v2`` çš„åˆçº¦ä¸è¯•å›¾è¿›è¡Œéœ€è¦è§£ç æ–°ç¼–ç å™¨æ”¯æŒçš„类型的调用时, +æ‰æœ‰å¯èƒ½å‡ºçŽ°ç›¸å的情况。 +编译器å¯ä»¥æ£€æµ‹åˆ°è¿™ä¸€ç‚¹ï¼Œå¹¶ä¼šå‘出一个错误。 +åªè¦ä¸ºæ‚¨çš„åˆåŒå¯ç”¨ ``abicoder v2`` ,就足以使错误消失。 .. note:: - This pragma applies to all the code defined in the file where it is activated, - regardless of where that code ends up eventually. This means that a contract - whose source file is selected to compile with ABI coder v1 - can still contain code that uses the new encoder - by inheriting it from another contract. This is allowed if the new types are only - used internally and not in external function signatures. + 这个编译指示适用于激活它的文件中定义的所有代ç ï¼Œ + 无论这些代ç æœ€ç»ˆåœ¨å“ªé‡Œç»“æŸã€‚è¿™æ„味ç€ï¼Œ + 一个åˆçº¦çš„æºæ–‡ä»¶è¢«é€‰æ‹©ç”¨ ABI ç¼–ç å™¨v1编译, + 它ä»ç„¶å¯ä»¥åŒ…å«é€šè¿‡ä»Žå¦ä¸€ä¸ªåˆçº¦ç»§æ‰¿æ¥ä½¿ç”¨æ–°ç¼–ç å™¨çš„代ç ã€‚ + 如果新类型åªåœ¨å†…部使用,而ä¸æ˜¯åœ¨å¤–部函数签å中使用, + 这是被å…许的。 .. note:: - Up to Solidity 0.7.4, it was possible to select the ABI coder v2 - by using ``pragma experimental ABIEncoderV2``, but it was not possible - to explicitly select coder v1 because it was the default. + 到 Solidity 0.7.4 为止,å¯ä»¥é€šè¿‡ä½¿ç”¨ ``pragma experimental ABIEncoderV2`` + æ¥é€‰æ‹© ABI ç¼–ç å™¨v2,但ä¸å¯èƒ½æ˜Žç¡®é€‰æ‹©ç¼–ç å™¨v1,因为它是默认的。 .. index:: ! pragma; experimental .. _experimental_pragma: -Experimental Pragma +实验性编译指示 ------------------- -The second pragma is the experimental pragma. It can be used to enable -features of the compiler or language that are not yet enabled by default. -The following experimental pragmas are currently supported: +第二个编译指示是实验性的编译指示。 +它å¯ä»¥ç”¨æ¥å¯ç”¨ç¼–译器或语言中尚未默认å¯ç”¨çš„功能。 +ç›®å‰æ”¯æŒä»¥ä¸‹å®žéªŒæ€§ç¼–译指示: .. index:: ! pragma; ABIEncoderV2 -ABIEncoderV2 -~~~~~~~~~~~~ +ABI ç¼–ç å™¨ V2 +~~~~~~~~~~~~~ -Because the ABI coder v2 is not considered experimental anymore, -it can be selected via ``pragma abicoder v2`` (please see above) -since Solidity 0.7.4. +因为 ABI ç¼–ç å™¨v2ä¸å†è¢«è®¤ä¸ºæ˜¯å®žéªŒæ€§çš„, +它å¯ä»¥é€šè¿‡ ``pragma abicoder v2`` (请è§ä¸Šæ–‡ï¼‰ä»Ž Solidity 0.7.4 开始选择。 .. index:: ! pragma; SMTChecker .. _smt_checker: -SMTChecker +SMT检查器 ~~~~~~~~~~ -This component has to be enabled when the Solidity compiler is built -and therefore it is not available in all Solidity binaries. -The :ref:`build instructions` explain how to activate this option. -It is activated for the Ubuntu PPA releases in most versions, -but not for the Docker images, Windows binaries or the -statically-built Linux binaries. It can be activated for solc-js via the -`smtCallback `_ if you have an SMT solver -installed locally and run solc-js via node (not via the browser). - -If you use ``pragma experimental SMTChecker;``, then you get additional -:ref:`safety warnings` which are obtained by querying an -SMT solver. -The component does not yet support all features of the Solidity language and -likely outputs many warnings. In case it reports unsupported features, the -analysis may not be fully sound. +这个组件必须在构建 Solidity 编译器时被å¯ç”¨ï¼Œ +因此它ä¸æ˜¯åœ¨æ‰€æœ‰ Solidity 二进制文件中都å¯ç”¨ã€‚ +:ref:`构建说明` 解释了如何激活这个选项。 +它在大多数版本中为 Ubuntu PPA 版本激活, +但ä¸ç”¨äºŽ Docker é•œåƒã€Windows 二进制文件或é™æ€æž„建的 Linux 二进制文件。 +如果您在本地安装了SMT检查器并通过节点(而ä¸æ˜¯é€šè¿‡æµè§ˆå™¨ï¼‰è¿è¡Œ solc-js, +å¯ä»¥é€šè¿‡ `smtCallback `_ +为 solc-js 激活它。 + +如果您使用 ``pragma experimental SMTChecker;``, +那么您会得到é¢å¤–çš„ :ref:`安全警告`。 +这些警告是通过查询SMT求解器获得的。 +该组件还ä¸æ”¯æŒ Solidity 语言的所有功能,å¯èƒ½ä¼šè¾“出许多警告。 +如果它报告ä¸æ”¯æŒçš„功能,那么分æžå¯èƒ½ä¸å®Œå…¨æ­£ç¡®ã€‚ .. index:: source file, ! import, module, source unit .. _import: -Importing other Source Files -============================ +导入其他æºæ–‡ä»¶ +============== -Syntax and Semantics --------------------- +语法与语义 +---------- -Solidity supports import statements to help modularise your code that -are similar to those available in JavaScript -(from ES6 on). However, Solidity does not support the concept of -a `default export `_. +Solidity 支æŒå¯¼å…¥è¯­å¥ï¼Œä»¥å¸®åŠ©æ¨¡å—化您的代ç ï¼Œ +这些语å¥ä¸Ž JavaScript 中å¯ç”¨çš„语å¥ç›¸ä¼¼(从ES6开始)。 +然而,Solidity 并ä¸æ”¯æŒ `默认导出 `_ +的概念。 -At a global level, you can use import statements of the following form: +在全局层é¢ï¼Œæ‚¨å¯ä»¥ä½¿ç”¨ä»¥ä¸‹å½¢å¼çš„导入语å¥ï¼š .. code-block:: solidity import "filename"; -The ``filename`` part is called an *import path*. -This statement imports all global symbols from "filename" (and symbols imported there) into the -current global scope (different than in ES6 but backwards-compatible for Solidity). -This form is not recommended for use, because it unpredictably pollutes the namespace. -If you add new top-level items inside "filename", they automatically -appear in all files that import like this from "filename". It is better to import specific -symbols explicitly. +``filename`` 部分被称为 *导入路径*。 +该语å¥å°†æ‰€æœ‰æ¥è‡ª “filename†的全局符å·ï¼ˆä»¥åŠåœ¨é‚£é‡Œå¯¼å…¥çš„符å·ï¼‰ +导入到当å‰çš„全局范围(与ES6中ä¸åŒï¼Œä½†å¯¹Solidityæ¥è¯´æ˜¯å‘åŽå…¼å®¹çš„)。 +è¿™ç§å½¢å¼ä¸å»ºè®®ä½¿ç”¨ï¼Œå› ä¸ºå®ƒä¸å¯é¢„测地污染了命å空间。 +如果您在 “filename†里é¢æ·»åŠ æ–°çš„顶层项目, +它们会自动出现在所有åƒè¿™æ ·ä»Ž “filename†导入的文件中。 +最好是明确地导入特定的符å·ã€‚ -The following example creates a new global symbol ``symbolName`` whose members are all -the global symbols from ``"filename"``: +下é¢çš„例å­åˆ›å»ºäº†ä¸€ä¸ªæ–°çš„å…¨å±€ç¬¦å· ``symbolName``,其æˆå‘˜å‡æ¥è‡ª ``"filename"`` 中全局符å·ï¼› .. code-block:: solidity import * as symbolName from "filename"; -which results in all global symbols being available in the format ``symbolName.symbol``. +è¿™æ„味ç€æ‰€æœ‰å…¨å±€ç¬¦å·ä»¥ ``symbolName.symbol`` çš„æ ¼å¼æ供。 -A variant of this syntax that is not part of ES6, but possibly useful is: +å¦ä¸€ç§è¯­æ³•ä¸å±žäºŽ ES6,但å¯èƒ½æ˜¯æœ‰ç”¨çš„: .. code-block:: solidity import "filename" as symbolName; -which is equivalent to ``import * as symbolName from "filename";``. +è¿™æ¡è¯­å¥ç­‰åŒäºŽ ``import * as symbolName from "filename";``。 -If there is a naming collision, you can rename symbols while importing. For example, -the code below creates new global symbols ``alias`` and ``symbol2`` which reference -``symbol1`` and ``symbol2`` from inside ``"filename"``, respectively. +如果有命å冲çªï¼Œæ‚¨å¯ä»¥åœ¨å¯¼å…¥çš„åŒæ—¶é‡å‘½å符å·ã€‚ +例如,下é¢çš„代ç åˆ›å»ºäº†æ–°çš„å…¨å±€ç¬¦å· ``alias`` å’Œ ``symbol2``, +它们分别从 ``"filename"`` 里é¢å¼•ç”¨ ``symbol1`` å’Œ ``symbol2``。 .. code-block:: solidity @@ -225,56 +217,50 @@ the code below creates new global symbols ``alias`` and ``symbol2`` which refere .. index:: virtual filesystem, source unit name, import; path, filesystem path, import callback, Remix IDE -Import Paths ------------- - -In order to be able to support reproducible builds on all platforms, the Solidity compiler has to -abstract away the details of the filesystem where source files are stored. -For this reason import paths do not refer directly to files in the host filesystem. -Instead the compiler maintains an internal database (*virtual filesystem* or *VFS* for short) where -each source unit is assigned a unique *source unit name* which is an opaque and unstructured identifier. -The import path specified in an import statement is translated into a source unit name and used to -find the corresponding source unit in this database. - -Using the :ref:`Standard JSON ` API it is possible to directly provide the names and -content of all the source files as a part of the compiler input. -In this case source unit names are truly arbitrary. -If, however, you want the compiler to automatically find and load source code into the VFS, your -source unit names need to be structured in a way that makes it possible for an :ref:`import callback -` to locate them. -When using the command-line compiler the default import callback supports only loading source code -from the host filesystem, which means that your source unit names must be paths. -Some environments provide custom callbacks that are more versatile. -For example the `Remix IDE `_ provides one that -lets you `import files from HTTP, IPFS and Swarm URLs or refer directly to packages in NPM registry -`_. - -For a complete description of the virtual filesystem and the path resolution logic used by the -compiler see :ref:`Path Resolution `. +导入路径 +--------- + +为了能够在所有平å°ä¸Šæ”¯æŒå¯é‡å¤çš„构建, +Solidity 编译器必须抽象出存储æºæ–‡ä»¶çš„文件系统的细节。 +由于这个原因,导入路径并ä¸ç›´æŽ¥æŒ‡å‘主机文件系统中的文件。 +相å,编译器维护一个内部数æ®åº“( *虚拟文件系统* 或简称 *VFS* ), +æ¯ä¸ªæºå•å…ƒè¢«åˆ†é…一个唯一的 *æºå•å…ƒå称*, +这是一个ä¸é€æ˜Žçš„ã€éžç»“构化的标识。 +在导入语å¥ä¸­æŒ‡å®šçš„导入路径被转译æˆæºå•å…ƒå称,并用于在这个数æ®åº“中找到相应的æºå•å…ƒã€‚ + +使用 :ref:`标准 JSON ` API, +å¯ä»¥ç›´æŽ¥æ供所有æºæ–‡ä»¶çš„å称和内容作为编译器输入的一部分。 +在这ç§æƒ…况下,æºå•å…ƒçš„å称确实是任æ„的。 +然而,如果您想让编译器自动查找并将æºä»£ç åŠ è½½åˆ°VFS中, +您的æºå•å…ƒå称需è¦ä»¥ä¸€ç§ç»“构化的方å¼ï¼Œä½¿ :ref:`回调引用 ` 能够定ä½å®ƒä»¬ã€‚ +当使用命令行编译器时,默认的回调引用åªæ”¯æŒä»Žä¸»æœºæ–‡ä»¶ç³»ç»ŸåŠ è½½æºä»£ç ï¼Œ +è¿™æ„味ç€æ‚¨çš„æºå•å…ƒå称必须是路径。一些环境æ供了自定义的回调,其用途更广。 +例如, `Remix IDE `_ æ供了一个å¯ä»¥è®©æ‚¨ +`从HTTPã€IPFSå’ŒSwarm URL导入文件,或者直接引用NPM注册表中的包 `_。 + +关于虚拟文件系统和编译器使用的路径解æžé€»è¾‘的完整æ述,请å‚è§ :ref:`è·¯å¾„è§£æž `。 .. index:: ! comment, natspec -Comments +注释 ======== -Single-line comments (``//``) and multi-line comments (``/*...*/``) are possible. +å¯ä»¥ä½¿ç”¨å•è¡Œæ³¨é‡Šï¼ˆ ``//`` )和多行注释( ``/*...*/`` ) .. code-block:: solidity - // This is a single-line comment. + // 这是一个å•è¡Œæ³¨é‡Šã€‚ /* - This is a - multi-line comment. + 这是一个 + 多行注释。 */ .. note:: - A single-line comment is terminated by any unicode line terminator - (LF, VF, FF, CR, NEL, LS or PS) in UTF-8 encoding. The terminator is still part of - the source code after the comment, so if it is not an ASCII symbol - (these are NEL, LS and PS), it will lead to a parser error. - -Additionally, there is another type of comment called a NatSpec comment, -which is detailed in the :ref:`style guide`. They are written with a -triple slash (``///``) or a double asterisk block (``/** ... */``) and -they should be used directly above function declarations or statements. + å•è¡Œæ³¨é‡Šç”± UTF-8 ç¼–ç ä¸­çš„任何å•ç è¡Œç»“æŸç¬¦ï¼ˆLFã€VFã€FFã€CRã€NELã€LS 或 PS)结æŸã€‚ + 终结符在注释之åŽä»ç„¶æ˜¯æºä»£ç çš„一部分, + 所以如果它ä¸æ˜¯ä¸€ä¸ª ASCII 符å·ï¼ˆè¿™äº›æ˜¯ NELã€LS å’Œ PS),将导致解æžå™¨é”™è¯¯ã€‚ + +此外,还有一ç§æ³¨é‡Šå«åš NatSpec 注释,在 :ref:`æ ¼å¼æŒ‡å—` 中详细说明。 +它们用三斜线( ``///`` )或åŒæ˜Ÿå·å—( ``/** ... */`` )æ¥å†™ï¼Œ +它们应该直接用在函数声明或语å¥çš„上方。 diff --git a/docs/metadata.rst b/docs/metadata.rst index ede16a73fd8e..f4a5474d8fcc 100644 --- a/docs/metadata.rst +++ b/docs/metadata.rst @@ -1,63 +1,59 @@ .. _metadata: ################# -Contract Metadata +åˆçº¦çš„å…ƒæ•°æ® ################# .. index:: metadata, contract verification -The Solidity compiler automatically generates a JSON file. -The file contains two kinds of information about the compiled contract: +Solidity 编译器自动生æˆä¸€ä¸ª JSON 文件。 +该文件包å«ä¸¤ç§æœ‰å…³å·²ç¼–译åˆçº¦çš„ä¿¡æ¯ï¼š -- How to interact with the contract: ABI, and NatSpec documentation. -- How to reproduce the compilation and verify a deployed contract: - compiler version, compiler settings, and source files used. +- 如何与åˆçº¦äº¤äº’:ABI å’Œ NatSpec 文档。 +- 如何é‡çŽ°ç¼–译并验è¯å·²éƒ¨ç½²çš„åˆçº¦ï¼š + 编译器版本ã€ç¼–译器设置和使用的æºæ–‡ä»¶ã€‚ -The compiler appends by default the IPFS hash of the metadata file to the end -of the runtime bytecode (not necessarily the creation bytecode) of each contract, -so that, if published, you can retrieve the file in an authenticated way without -having to resort to a centralized data provider. The other available options are -the Swarm hash and not appending the metadata hash to the bytecode. These can be -configured via the :ref:`Standard JSON Interface`. +默认情况下,编译器会将元数æ®æ–‡ä»¶çš„ IPFS 哈希值附加到 +æ¯ä¸ªåˆçº¦çš„è¿è¡Œæ—¶å­—节ç ï¼ˆä¸ä¸€å®šæ˜¯åˆ›å»ºå­—节ç ï¼‰æœ«å°¾ï¼Œ +这样,如果å‘布了该文件,就å¯ä»¥é€šè¿‡éªŒè¯çš„æ–¹å¼æ£€ç´¢è¯¥æ–‡ä»¶ï¼Œè€Œæ— éœ€æ±‚助于集中å¼æ•°æ®æ供者。 +其他å¯ç”¨é€‰é¡¹åŒ…括 Swarm 哈希值和ä¸åœ¨å­—节ç ä¸­é™„加元数æ®å“ˆå¸Œå€¼ã€‚ +这些选项å¯é€šè¿‡ :ref:`标准 JSON æŽ¥å£ ` 进行é…置。 -You have to publish the metadata file to IPFS, Swarm, or another service so -that others can access it. You create the file by using the ``solc --metadata`` -command together with the ``--output-dir`` parameter. Without the parameter, -the metadata will be written to standard output. -The metadata contains IPFS and Swarm references to the source code, so you have to -upload all source files in addition to the metadata file. For IPFS, the hash contained -in the CID returned by ``ipfs add`` (not the direct sha2-256 hash of the file) -shall match with the one contained in the bytecode. +您必须将元数æ®æ–‡ä»¶å‘布到IPFS,Swarm或其他æœåŠ¡ï¼Œ +以便其他人å¯ä»¥è®¿é—®å®ƒã€‚您å¯ä»¥é€šè¿‡ä½¿ç”¨ ``solc --metadata`` 命令 +å’Œ ``--output-dir`` å‚æ•°æ¥åˆ›å»ºè¯¥æ–‡ä»¶ã€‚如果没有这个å‚数, +元数æ®å°†è¢«å†™åˆ°æ ‡å‡†è¾“出。 +元数æ®åŒ…å« IPFS å’Œ Swarm 对æºä»£ç çš„引用, +所以除了元数æ®æ–‡ä»¶å¤–,您还必须上传所有的æºæ–‡ä»¶ã€‚ +对于IPFS, ``ipfs add`` 返回的 CID 中包å«çš„哈希值(ä¸æ˜¯æ–‡ä»¶çš„直接sha2-256哈希值) +应与字节ç ä¸­åŒ…å«çš„哈希值相匹é…。 -The metadata file has the following format. The example below is presented in a -human-readable way. Properly formatted metadata should use quotes correctly, -reduce whitespace to a minimum, and sort the keys of all objects in alphabetical order -to arrive at a canonical formatting. Comments are not permitted and are used here only for -explanatory purposes. +元数æ®æ–‡ä»¶çš„æ ¼å¼å¦‚下。下é¢çš„示例是以人类å¯è¯»çš„æ–¹å¼å‘ˆçŽ°çš„。 +正确格å¼åŒ–的元数æ®åº”正确使用引å·ï¼Œ +å°½é‡å‡å°‘空白,并按字æ¯é¡ºåºå¯¹æ‰€æœ‰å¯¹è±¡çš„键值进行排åºï¼Œä»¥å½¢æˆè§„范格å¼ã€‚ +ä¸å…许使用注释,此处注释仅用于解释目的。 .. code-block:: javascript { - // Required: Details about the compiler, contents are specific - // to the language. + // 必选:编译器的详情,内容视语言而定。 "compiler": { - // Optional: Hash of the compiler binary which produced this output + // å¯é€‰ï¼šç”Ÿæˆæ­¤è¾“出的编译器二进制文件的哈希值 "keccak256": "0x123...", - // Required for Solidity: Version of the compiler + // 对 Solidity æ¥è¯´æ˜¯å¿…选的:编译器的版本 "version": "0.8.2+commit.661d1103" }, - // Required: Source code language, basically selects a "sub-version" - // of the specification + // 必选:æºä»£ç çš„编程语言,一般会选择规范的“å­ç‰ˆæœ¬â€ "language": "Solidity", - // Required: Generated information about the contract. + // 必选:åˆçº¦çš„生æˆä¿¡æ¯ "output": { - // Required: ABI definition of the contract. See "Contract ABI Specification" + // 必选:åˆçº¦çš„ ABI å®šä¹‰ï¼Œè§ â€œåˆçº¦ ABI 规范†"abi": [/* ... */], - // Required: NatSpec developer documentation of the contract. See https://docs.soliditylang.org/en/latest/natspec-format.html for details. + // 必选:åˆçº¦çš„å¼€å‘者 NatSpec æ–‡æ¡£ï¼Œè¯¦è§ https://docs.soliditylang.org/en/latest/natspec-format.html "devdoc": { - // Contents of the @author NatSpec field of the contract + // åˆçº¦ @author NatSpec字段的内容 "author": "John Doe", - // Contents of the @dev NatSpec field of the contract + // åˆçº¦ä¸­ @dev NatSpec 字段的内容 "details": "Interface of the ERC20 standard as defined in the EIP. See https://eips.ethereum.org/EIPS/eip-20 for details", "errors": { "MintToZeroAddress()" : { @@ -77,31 +73,31 @@ explanatory purposes. "kind": "dev", "methods": { "transfer(address,uint256)": { - // Contents of the @dev NatSpec field of the method + // 方法的 @dev NatSpec 字段的内容 "details": "Returns a boolean value indicating whether the operation succeeded. Must be called by the token holder address", - // Contents of the @param NatSpec fields of the method + // 方法的 @param NatSpec 字段的内容 "params": { "_value": "The amount tokens to be transferred", "_to": "The receiver address" }, - // Contents of the @return NatSpec field. + // @return NatSpec 字段的内容。 "returns": { - // Return var name (here "success") if exists. "_0" as key if return var is unnamed + // 如果存在,返回varå称(这里是 “successâ€ï¼‰ã€‚如果返回的var是未命å的,“_0†作为键。 "success": "a boolean value indicating whether the operation succeeded" } } }, "stateVariables": { "owner": { - // Contents of the @dev NatSpec field of the state variable + // 状æ€å˜é‡çš„ @dev NatSpec 字段的内容 "details": "Must be set during contract creation. Can then only be changed by the owner" } }, - // Contents of the @title NatSpec field of the contract + // åˆçº¦ä¸­ @title NatSpec 字段的内容 "title": "MyERC20: an example ERC20", - "version": 1 // NatSpec version + "version": 1 // NatSpec 版本 }, - // Required: NatSpec user documentation of the contract. See "NatSpec Format" + // 必选:åˆçº¦çš„用户 NatSpec 文档。请å‚阅“NatSpec æ ¼å¼â€ "userdoc": { "errors": { "ApprovalCallerNotOwnerNorApproved()": [ @@ -121,47 +117,56 @@ explanatory purposes. "notice": "Transfers `_value` tokens to address `_to`" } }, - "version": 1 // NatSpec version + "version": 1 // NatSpec 版本 } }, - // Required: Compiler settings. Reflects the settings in the JSON input during compilation. - // Check the documentation of standard JSON input's "settings" field + // 必选: 编译器设置。å映编译时 JSON 输入的设置。 + // 查看标准 JSON 输入的 “setting†字段文档 "settings": { - // Required for Solidity: File path and the name of the contract or library this - // metadata is created for. + // 对 Solidity æ¥è¯´æ˜¯å¿…选的: 文件路径以åŠä¸ºå…¶åˆ›å»ºçš„åˆçº¦æˆ–库的å称。 "compilationTarget": { "myDirectory/myFile.sol": "MyContract" }, - // Required for Solidity. + // 对 Solidity æ¥è¯´æ˜¯å¿…选的。 "evmVersion": "london", - // Required for Solidity: Addresses for libraries used. + // 对 Solidity æ¥è¯´æ˜¯å¿…选的: 使用的库åˆçº¦åœ°å€ã€‚ "libraries": { "MyLib": "0x123123..." }, "metadata": { - // Reflects the setting used in the input json, defaults to "true" + // å映输入 json 中使用的设置,默认为“true†"appendCBOR": true, - // Reflects the setting used in the input json, defaults to "ipfs" + // å映输入 json 中使用的设置,默认为“ipfs†"bytecodeHash": "ipfs", - // Reflects the setting used in the input json, defaults to "false" + // å映输入 json 中使用的设置,默认为“false†"useLiteralContent": true }, +<<<<<<< HEAD + // å¯é€‰ï¼šä¼˜åŒ–设置。“enabled†和 “runs†字段已弃用,仅用于å‘åŽå…¼å®¹ã€‚ +======= // Optional: Optimizer settings. The fields "enabled" and "runs" are deprecated // and are only given for backward-compatibility. +>>>>>>> english/develop "optimizer": { "details": { "constantOptimizer": false, "cse": false, "deduplicate": false, +<<<<<<< HEAD + // inliner 默认为“true†+ "inliner": true, + // jumpdestRemover 默认为“true†+======= // inliner defaults to "false" "inliner": false, // jumpdestRemover defaults to "true" +>>>>>>> english/develop "jumpdestRemover": true, "orderLiterals": false, - // peephole defaults to "true" + // peephole 默认为“true†"peephole": true, "yul": true, - // Optional: Only present if "yul" is "true" + // å¯é€‰ï¼šä»…当 “yul†为 “true†时æ‰å‡ºçŽ° "yulDetails": { "optimizerSteps": "dhfoDgvulfnTUtnIf...", "stackAllocation": false @@ -170,123 +175,126 @@ explanatory purposes. "enabled": true, "runs": 500 }, - // Required for Solidity: Sorted list of import remappings. + // 对 Solidity æ¥è¯´æ˜¯å¿…选的:导入é‡æ–°æ˜ å°„的排åºåˆ—表。 "remappings": [ ":g=/dir" ] }, - // Required: Compilation source files/source units, keys are file paths + // 必选:编译æºæ–‡ä»¶/æºå•å…ƒï¼Œé”®ä¸ºæ–‡ä»¶è·¯å¾„ "sources": { +<<<<<<< HEAD "destructible": { - // Required (unless "url" is used): literal contents of the source file + // 必选(除éžä½¿ç”¨äº† “urlâ€ï¼‰ï¼šæºæ–‡ä»¶çš„å­—é¢å†…容 "content": "contract destructible is owned { function destroy() { if (msg.sender == owner) selfdestruct(owner); } }", + // 必选:æºæ–‡ä»¶çš„ keccak256 哈希值 +======= + "settable": { + // Required (unless "url" is used): literal contents of the source file + "content": "contract settable is owned { uint256 private x = 0; function set(uint256 _x) public { if (msg.sender == owner) x = _x; } }", // Required: keccak256 hash of the source file +>>>>>>> english/develop "keccak256": "0x234..." }, "myDirectory/myFile.sol": { - // Required: keccak256 hash of the source file + // 必选:æºæ–‡ä»¶çš„ keccak256 哈希值 "keccak256": "0x123...", - // Optional: SPDX license identifier as given in the source file + // å¯é€‰ï¼šæºæ–‡ä»¶ä¸­ç»™å‡ºçš„ SPDX 许å¯è¯æ ‡è¯†ç¬¦ "license": "MIT", - // Required (unless "content" is used, see above): Sorted URL(s) - // to the source file, protocol is more or less arbitrary, but an - // IPFS URL is recommended + // 必选(除éžä½¿ç”¨äº† “contentâ€ï¼Œè§ä¸Šæ–‡ï¼‰ï¼šæŒ‡å‘æºæ–‡ä»¶çš„æŽ’åº URL, + // åè®®å¯ä»»æ„选择,但建议使用 IPFS URL "urls": [ "bzz-raw://7d7a...", "dweb:/ipfs/QmN..." ] } }, - // Required: The version of the metadata format + // 必选:元数æ®æ ¼å¼çš„版本 "version": 1 } .. warning:: - Since the bytecode of the resulting contract contains the metadata hash by default, any - change to the metadata might result in a change of the bytecode. This includes - changes to a filename or path, and since the metadata includes a hash of all the - sources used, a single whitespace change results in different metadata, and - different bytecode. + 由于产生的åˆçº¦çš„字节ç é»˜è®¤åŒ…å«å…ƒæ•°æ®å“ˆå¸Œå€¼ï¼Œ + 对元数æ®çš„任何改å˜éƒ½å¯èƒ½å¯¼è‡´å­—节ç çš„改å˜ã€‚ + 这包括对文件å或路径的改å˜ï¼Œè€Œä¸”由于元数æ®åŒ…括所有使用的æºçš„哈希值, + 一个空白的改å˜å°±ä¼šå¯¼è‡´ä¸åŒçš„元数æ®å’Œä¸åŒçš„字节ç ã€‚ .. note:: - The ABI definition above has no fixed order. It can change with compiler versions. - Starting from Solidity version 0.5.12, though, the array maintains a certain - order. + 上é¢çš„ABI定义没有固定的顺åºã€‚它å¯ä»¥éšç€ç¼–译器的版本而改å˜ã€‚ + ä¸è¿‡ï¼Œä»ŽSolidity 0.5.12版本开始,该数组ä¿æŒä¸€å®šçš„顺åºã€‚ .. _encoding-of-the-metadata-hash-in-the-bytecode: -Encoding of the Metadata Hash in the Bytecode +在字节ç ä¸­å¯¹å…ƒæ•°æ®å“ˆå¸Œå€¼è¿›è¡Œç¼–ç  ============================================= -The compiler currently by default appends the -`IPFS hash (in CID v0) `_ -of the canonical metadata file and the compiler version to the end of the bytecode. -Optionally, a Swarm hash instead of the IPFS, or an experimental flag is used. -Below are all the possible fields: +编译器目å‰é»˜è®¤å°†è§„范元数æ®æ–‡ä»¶çš„ +`IPFS 哈希(in CID v0) `_ +和编译器版本附加到字节ç æœ«å°¾ã€‚ +也å¯é€‰æ‹©ä½¿ç”¨ Swarm 哈希值代替 IPFS,或使用实验标志。 +以下是所有å¯èƒ½çš„字段: .. code-block:: javascript { "ipfs": "", - // If "bytecodeHash" was "bzzr1" in compiler settings not "ipfs" but "bzzr1" + // 如果编译器设置中的“bytecodeHashâ€ä¸ºâ€œbzzr1â€ï¼Œæ­¤å¤„ä¸æ˜¯â€œipfsâ€è€Œæ˜¯â€œbzzr1†"bzzr1": "", - // Previous versions were using "bzzr0" instead of "bzzr1" + // 以å‰çš„版本使用“bzzr0â€è€Œä¸æ˜¯â€œbzzr1†"bzzr0": "", - // If any experimental features that affect code generation are used + // 如果使用任何影å“代ç ç”Ÿæˆçš„实验性功能 "experimental": true, "solc": "" } -Because we might support other ways to retrieve the -metadata file in the future, this information is stored -`CBOR `_-encoded. The last two bytes in the bytecode -indicate the length of the CBOR encoded information. By looking at this length, the -relevant part of the bytecode can be decoded with a CBOR decoder. +因为我们将æ¥å¯èƒ½ä¼šæ”¯æŒä»¥å…¶ä»–æ–¹å¼æ£€ç´¢å…ƒæ•°æ®æ–‡ä»¶ï¼Œ +因此这些信æ¯è¢«å­˜å‚¨ä¸º `CBOR `__ - ç¼–ç ã€‚ +字节ç ä¸­çš„最åŽä¸¤ä¸ªå­—节表示 CBOR ç¼–ç ä¿¡æ¯çš„长度。通过查看这个长度, +å¯ä»¥ç”¨ CBOR 解ç å™¨å¯¹å­—节ç çš„相关部分进行解ç ã€‚ -Check the `Metadata Playground `_ to see it in action. +请访问 `Metadata Playground `_ 查看实际æ“作。 +<<<<<<< HEAD +SOLCçš„å‘布版本使用如上所示的3ä¸ªå­—èŠ‚çš„ç‰ˆæœ¬ç¼–ç  +(主è¦ã€æ¬¡è¦å’Œè¡¥ä¸ç‰ˆæœ¬å·å„一个字节), +而预å‘布版本将使用一个完整的版本字符串,包括æ交哈希和构建日期。 +======= Whereas release builds of solc use a 3 byte encoding of the version as shown above (one byte each for major, minor and patch version number), pre-release builds will instead use a complete version string including commit hash and build date. +>>>>>>> english/develop -The commandline flag ``--no-cbor-metadata`` can be used to skip metadata -from getting appended at the end of the deployed bytecode. Equivalently, the -boolean field ``settings.metadata.appendCBOR`` in Standard JSON input can be set to false. +命令行标志 ``--no-cbor-metadata`` å¯ä»¥ç”¨æ¥è·³è¿‡å…ƒæ•°æ®åœ¨éƒ¨ç½²çš„字节ç æœ«ç«¯çš„附加。 +åŒæ ·åœ°ï¼Œæ ‡å‡†JSON输入中的布尔字段 ``settings.metadata.appendCBOR`` å¯ä»¥è®¾ç½®ä¸ºfalse。 .. note:: - The CBOR mapping can also contain other keys, so it is better to fully - decode the data by looking at the end of the bytecode for the CBOR length, - and to use a proper CBOR parser. Do not rely on it starting with ``0xa264`` - or ``0xa2 0x64 'i' 'p' 'f' 's'``. + CBOR 映射也å¯èƒ½åŒ…å«å…¶ä»–键, + 因此最好通过查看字节ç æœ«å°¾çš„ CBOR 长度æ¥å®Œå…¨è§£ç æ•°æ®ï¼Œ + 并使用适当的 CBOR 分æžå™¨ã€‚ä¸è¦ä¾èµ–以 ``0xa264`` + 或 ``0xa2 0x64 'i' 'p' 'f' 's'`` 开头的数æ®ã€‚ -Usage for Automatic Interface Generation and NatSpec +自动化接å£ç”Ÿæˆå’ŒNatSpec 的使用方法 ==================================================== -The metadata is used in the following way: A component that wants to interact -with a contract (e.g. a wallet) retrieves the code of the contract. -It decodes the CBOR encoded section containing the IPFS/Swarm hash of the -metadata file. With that hash, the metadata file is retrieved. That file -is JSON-decoded into a structure like above. +元数æ®çš„使用方å¼å¦‚下:一个想è¦ä¸Žåˆçº¦äº¤äº’的组件 +(例如钱包)会检索åˆçº¦çš„代ç ã€‚ +它对包å«å…ƒæ•°æ®æ–‡ä»¶çš„ IPFS/Swarm 哈希的 CBOR ç¼–ç éƒ¨åˆ†è¿›è¡Œè§£ç ã€‚ +通过该哈希值,元数æ®æ–‡ä»¶è¢«æ£€ç´¢å‡ºæ¥ã€‚该文件被 JSON 解ç æˆä¸€ä¸ªç±»ä¼¼äºŽä¸Šè¿°çš„结构。 -The component can then use the ABI to automatically generate a rudimentary -user interface for the contract. +然åŽï¼Œè¯¥ç»„件å¯ä»¥ä½¿ç”¨ABI为åˆçº¦è‡ªåŠ¨ç”Ÿæˆä¸€ä¸ªåŸºæœ¬çš„用户界é¢ã€‚ -Furthermore, the wallet can use the NatSpec user documentation to display a -human-readable confirmation message to the user whenever they interact with -the contract, together with requesting authorization for the transaction signature. +此外,钱包还å¯ä»¥ä½¿ç”¨ NatSpec 用户文档,在用户与åˆçº¦è¿›è¡Œäº¤äº’时, +å‘用户显示一æ¡å¯è¯»çš„确认信æ¯ï¼ŒåŒæ—¶è¯·æ±‚交易签å进行授æƒã€‚ -For additional information, read :doc:`Ethereum Natural Language Specification (NatSpec) format `. +有关其他信æ¯ï¼Œè¯·é˜…读 :doc:`以太åŠè‡ªç„¶è¯­è¨€è§„范(NatSpecï¼‰æ ¼å¼ `。 -Usage for Source Code Verification +æºä»£ç éªŒè¯çš„用法 ================================== -If pinned/published, it is possible to retrieve the metadata of the contract from IPFS/Swarm. -The metadata file also contains the URLs or the IPFS hashes of the source files, as well as -the compilation settings, i.e. everything needed to reproduce a compilation. +如果已固定/å‘布,则å¯ä»¥ä»Ž IPFS/Swarm 获å–åˆçº¦çš„元数æ®ã€‚ +元数æ®æ–‡ä»¶è¿˜åŒ…å«æºæ–‡ä»¶çš„ URL 或 IPFS 哈希值,以åŠç¼–译设置, +å³é‡çŽ°ç¼–译所需的一切信æ¯ã€‚ -With this information it is then possible to verify the source code of a contract by -reproducing the compilation, and comparing the bytecode from the compilation with -the bytecode of the deployed contract. +有了这些信æ¯ï¼Œå°±å¯ä»¥é€šè¿‡é‡çŽ°ç¼–译æ¥éªŒè¯åˆçº¦çš„æºä»£ç ï¼Œ +并将编译的字节ç ä¸Žå·²éƒ¨ç½²åˆçº¦çš„字节ç è¿›è¡Œæ¯”较。 -This automatically verifies the metadata since its hash is part of the bytecode, as well -as the source codes, because their hashes are part of the metadata. Any change in the files -or settings would result in a different metadata hash. The metadata here serves -as a fingerprint of the whole compilation. +由于元数æ®å’Œæºä»£ç çš„哈希值都是字节ç çš„一部分,因此å¯ä»¥è‡ªåŠ¨éªŒè¯å…ƒæ•°æ®å’Œæºä»£ç ã€‚ +文件或设置的任何更改都会导致ä¸åŒçš„元数æ®å“ˆå¸Œå€¼ã€‚ +这里的元数æ®æ˜¯æ•´ä¸ªç¼–译过程的指纹。 -`Sourcify `_ makes use of this feature for "full/perfect verification", -as well as pinning the files publicly on IPFS to be accessed with the metadata hash. +`Sourcify `_ 利用这一特性进行 “完全/完美验è¯â€ï¼Œ +并将文件公开固定在 IPFS 上,以便使用元数æ®å“ˆå¸Œå€¼è¿›è¡Œè®¿é—®ã€‚ diff --git a/docs/natspec-format.rst b/docs/natspec-format.rst index 0265fef3e689..4fea39019c37 100644 --- a/docs/natspec-format.rst +++ b/docs/natspec-format.rst @@ -1,84 +1,76 @@ .. _natspec: ############## -NatSpec Format +é£Žæ ¼æŒ‡å— ############## -Solidity contracts can use a special form of comments to provide rich -documentation for functions, return variables and more. This special form is -named the Ethereum Natural Language Specification Format (NatSpec). +Solidityåˆçº¦å¯ä»¥ä½¿ç”¨ä¸€ç§ç‰¹æ®Šå½¢å¼çš„注释æ¥ä¸ºå‡½æ•°ï¼Œè¿”回å˜é‡ç­‰æ供丰富的文档。 +è¿™ç§ç‰¹æ®Šå½¢å¼è¢«å‘½å为Ethereum自然语言规范格å¼ï¼ˆNatSpec)。 .. note:: - NatSpec was inspired by `Doxygen `_. - While it uses Doxygen-style comments and tags, there is no intention to keep - strict compatibility with Doxygen. Please carefully examine the supported tags - listed below. + NatSpecæ˜¯å— `Doxygen `_ çš„å¯å‘。 + 虽然它使用Doxygen风格的注释和标签,但并ä¸æ‰“算与Doxygenä¿æŒä¸¥æ ¼çš„兼容性。 + 请仔细检查下é¢åˆ—出的支æŒçš„标签。 -This documentation is segmented into developer-focused messages and end-user-facing -messages. These messages may be shown to the end user (the human) at the -time that they will interact with the contract (i.e. sign a transaction). +该文件被划分为以开å‘人员为中心的信æ¯å’Œé¢å‘最终用户的信æ¯ã€‚ +这些信æ¯å¯ä»¥åœ¨ç»ˆç«¯ç”¨æˆ·ï¼ˆäººç±»ï¼‰ä¸Žåˆçº¦äº¤äº’(å³ç­¾ç½²äº¤æ˜“)时显示给他们。 -It is recommended that Solidity contracts are fully annotated using NatSpec for -all public interfaces (everything in the ABI). +建议 Solidity åˆçº¦ä½¿ç”¨ NatSpec 对所有公共接å£ï¼ˆABI中的一切)进行完全地注释。 -NatSpec includes the formatting for comments that the smart contract author will -use, and which are understood by the Solidity compiler. Also detailed below is -output of the Solidity compiler, which extracts these comments into a machine-readable -format. +NatSpec 包括智能åˆçº¦ä½œè€…将使用的注释的格å¼ï¼Œ +这些注释å¯è¢« Solidity 编译器ç†è§£ã€‚ +下é¢è¿˜è¯¦ç»†ä»‹ç»äº† Solidity 编译器的输出, +它将这些注释æå–为机器å¯è¯»çš„æ ¼å¼ã€‚ -NatSpec may also include annotations used by third-party tools. These are most likely -accomplished via the ``@custom:`` tag, and a good use case is analysis and verification -tools. +NatSpec 也å¯ä»¥åŒ…括第三方工具使用的注释。 +这些最å¯èƒ½æ˜¯é€šè¿‡ ``@custom:`` 标签完æˆçš„, +一个好的用例是分æžå’ŒéªŒè¯å·¥å…·å°±æ˜¯å¦‚此。 .. _header-doc-example: -Documentation Example +文档示例 ===================== -Documentation is inserted above each ``contract``, ``interface``, ``library``, -``function``, and ``event`` using the Doxygen notation format. -A ``public`` state variable is equivalent to a ``function`` -for the purposes of NatSpec. +文档å¯ä»¥é€šè¿‡ä½¿ç”¨ Doxygen 符å·æ ¼å¼æ¥åµŒå…¥åˆ°æ¯ä¸ª ``contract``, ``interface``, ``library``, +``function`` å’Œ ``event`` 之上。在 NatSpec 中, ``public`` 状æ€å˜é‡ç­‰åŒäºŽ ``function``。 -- For Solidity you may choose ``///`` for single or multi-line - comments, or ``/**`` and ending with ``*/``. +- 对于Solidity,您å¯ä»¥é€‰æ‹© ``///`` 用于å•è¡Œæ³¨é‡Š + 或以 ``/**`` 开始,并以 ``*/`` 结æŸçš„符å·ç”¨äºŽå¤šè¡Œæ³¨é‡Š -- For Vyper, use ``"""`` indented to the inner contents with bare - comments. See the `Vyper - documentation `__. +- 对于Vyperæ¥è¯´ï¼Œä½¿ç”¨ ``""""`` 缩进到内部内容æ¥è£¸æ³¨é‡Šï¼ˆè¯‘者注:无标记符å·æ³¨é‡Šï¼‰ã€‚ + å‚è§ `Vyper 文档 `__。 -The following example shows a contract and a function using all available tags. +下é¢çš„例å­æ˜¾ç¤ºäº†ä¸€ä¸ªåˆçº¦å’Œä¸€ä¸ªä½¿ç”¨æ‰€æœ‰å¯ç”¨æ ‡è®°çš„函数。 .. note:: - The Solidity compiler only interprets tags if they are external or - public. You are welcome to use similar comments for your internal and - private functions, but those will not be parsed. + Solidity 编译器åªåœ¨æ ‡ç­¾æ˜¯å¤–部或公共的情况下æ‰è¿›è¡Œè§£æžã€‚ + 但也欢迎您为您的内部和ç§æœ‰å‡½æ•°ä½¿ç”¨ç±»ä¼¼çš„注释,ä¸è¿‡è¿™äº›ä¸ä¼šè¢«è§£æžã€‚ - This may change in the future. + 这在未æ¥å¯èƒ½ä¼šå‘生å˜åŒ–。 .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.2 < 0.9.0; - /// @title A simulator for trees + /// @title 树的模拟器 /// @author Larry A. Gardner - /// @notice You can use this contract for only the most basic simulation - /// @dev All function calls are currently implemented without side effects - /// @custom:experimental This is an experimental contract. + /// @notice 您åªèƒ½å°†æ­¤åˆçº¦ç”¨äºŽæœ€åŸºæœ¬çš„模拟。 + /// @dev ç›®å‰æ‰€æœ‰çš„函数调用都是在没有副作用的情况下实现的 + /// @custom:experimental 这是一个实验性的åˆçº¦ã€‚ contract Tree { - /// @notice Calculate tree age in years, rounded up, for live trees - /// @dev The Alexandr N. Tetearing algorithm could increase precision - /// @param rings The number of rings from dendrochronological sample - /// @return Age in years, rounded up for partial years + /// @notice 计算活体树木的树龄,按四èˆäº”入计算 + /// @dev Alexandr N. Tetearing 算法å¯ä»¥æ高精确度 + /// @param rings 树龄学样本的环数 + /// @return 树龄(å²ï¼‰ï¼Œéƒ¨åˆ†å¹´ä»½å››èˆäº”å…¥ function age(uint256 rings) external virtual pure returns (uint256) { return rings + 1; } - /// @notice Returns the amount of leaves the tree has. - /// @dev Returns only a fixed number. + /// @notice 返回该树的å¶å­æ•°é‡ã€‚ + /// @dev 在此åªæ˜¯è¿”回了一个固定的数字。 function leaves() external virtual pure returns(uint256) { return 2; } @@ -95,8 +87,8 @@ The following example shows a contract and a function using all available tags. return rings + 2; } - /// Return the amount of leaves that this specific kind of tree has - /// @inheritdoc Tree + /// 返回这ç§ç‰¹å®šç±»åž‹çš„æ ‘çš„å¶å­æ•°é‡ã€‚ + /// @inheritdoc Tree åˆçº¦ function leaves() external override(Tree, Plant) pure returns(uint256) { return 3; } @@ -104,99 +96,103 @@ The following example shows a contract and a function using all available tags. .. _header-tags: -Tags +标签 ==== -All tags are optional. The following table explains the purpose of each -NatSpec tag and where it may be used. As a special case, if no tags are -used then the Solidity compiler will interpret a ``///`` or ``/**`` comment -in the same way as if it were tagged with ``@notice``. +所有标签都是å¯é€‰çš„。下表解释了æ¯ä¸ª NatSpec 标签的目的和它å¯èƒ½è¢«ä½¿ç”¨çš„地方。 +有一ç§ç‰¹æ®Šæƒ…况,如果没有使用标签,那么 Solidity 编译器将以åŒæ ·çš„æ–¹å¼è¿›è¡Œ ``///`` 或 ``/**`` 注释, +如åŒå®ƒè¢«æ ‡è®°ä¸º ``@notice``。 =============== ====================================================================================== ============================= -Tag Context +标签 应用于 =============== ====================================================================================== ============================= -``@title`` A title that should describe the contract/interface contract, library, interface -``@author`` The name of the author contract, library, interface -``@notice`` Explain to an end user what this does contract, library, interface, function, public state variable, event -``@dev`` Explain to a developer any extra details contract, library, interface, function, state variable, event +<<<<<<< HEAD +``@title`` 一个应该æè¿°åˆçº¦/接å£çš„标题 contract, library, interface +``@author`` 作者的åå­— contract, library, interface +``@notice`` å‘终端用户解释这个东西的作用 contract, library, interface, function, public state variable, event +``@dev`` å‘å¼€å‘人员解释任何é¢å¤–的细节 contract, library, interface, function, state variable, event +``@param`` å°±åƒåœ¨Doxygen中一样记录一个å‚数(必须在å‚æ•°å之åŽï¼‰ function, event +``@return`` 记录一个åˆçº¦çš„函数的返回å˜é‡ function, public state variable +``@inheritdoc`` 从基本函数中å¤åˆ¶æ‰€æœ‰ç¼ºå¤±çš„标签(必须在åˆçº¦å称之åŽï¼‰ function, public state variable +``@custom:...`` 自定义标签,语义由应用程åºå®šä¹‰ everywhere +======= +``@title`` A title that should describe the contract/interface contract, library, interface, struct, enum +``@author`` The name of the author contract, library, interface, struct, enum +``@notice`` Explain to an end user what this does contract, library, interface, function, public state variable, event, struct, enum +``@dev`` Explain to a developer any extra details contract, library, interface, function, state variable, event, struct, enum ``@param`` Documents a parameter just like in Doxygen (must be followed by parameter name) function, event ``@return`` Documents the return variables of a contract's function function, public state variable ``@inheritdoc`` Copies all missing tags from the base function (must be followed by the contract name) function, public state variable ``@custom:...`` Custom tag, semantics is application-defined everywhere +>>>>>>> english/develop =============== ====================================================================================== ============================= -If your function returns multiple values, like ``(int quotient, int remainder)`` -then use multiple ``@return`` statements in the same format as the ``@param`` statements. +如果您的函数返回多个值,如 ``(int quotient, int remainder)`` +那么使用多个 ``@return`` 语å¥ï¼Œæ ¼å¼ä¸Ž ``@param`` 语å¥ç›¸åŒã€‚ -Custom tags start with ``@custom:`` and must be followed by one or more lowercase letters or hyphens. -It cannot start with a hyphen however. They can be used everywhere and are part of the developer documentation. +自定义标签以 ``@custom:`` 开头,åŽé¢å¿…须有一个或多个å°å†™å­—æ¯æˆ–连字符。 +然而,它ä¸èƒ½ä»¥è¿žå­—符开始。它们å¯ä»¥åœ¨ä»»ä½•åœ°æ–¹ä½¿ç”¨ï¼Œæ˜¯å¼€å‘者文档的一部分。 .. _header-dynamic: -Dynamic expressions +动æ€è¡¨è¾¾æ–¹å¼ ------------------- -The Solidity compiler will pass through NatSpec documentation from your Solidity -source code to the JSON output as described in this guide. The consumer of this -JSON output, for example the end-user client software, may present this to the end-user directly or it may apply some pre-processing. +Solidity 编译器将通过 NatSpec 文档从您的 Solidity æºä»£ç ä¼ é€’到本指å—所述的 JSON 输出。 +æ­¤ JSON 输出的使用者,例如最终用户的客户端软件,å¯ä»¥ç›´æŽ¥å°†å…¶å‘ˆçŽ°ç»™æœ€ç»ˆç”¨æˆ·ï¼Œæˆ–者它å¯ä»¥åº”用一些预处ç†ã€‚ -For example, some client software will render: +例如,一些客户端软件会呈现为: .. code:: Solidity - /// @notice This function will multiply `a` by 7 + /// @notice 这个函数将使 `a` 乘以7 -to the end-user as: +对终端用户æ¥è¯´ï¼Œæ˜¯ï¼š .. code:: text - This function will multiply 10 by 7 + 这个函数将10乘以7 -if a function is being called and the input ``a`` is assigned a value of 10. +如果一个函数被调用,并且输入的 ``a`` 被赋值为10。 .. _header-inheritance: -Inheritance Notes +继承说明 ----------------- -Functions without NatSpec will automatically inherit the documentation of their -base function. Exceptions to this are: +没有NatSpec的函数将自动继承其基函数的文档。这方é¢çš„例外情况是: -* When the parameter names are different. -* When there is more than one base function. -* When there is an explicit ``@inheritdoc`` tag which specifies which contract should be used to inherit. +* 当å‚æ•°å称ä¸åŒæ—¶ã€‚ +* 当有ä¸æ­¢ä¸€ä¸ªçš„基础函数时。 +* 当有一个明确的 ``@inheritdoc`` 标签,指定了应该使用哪个åˆçº¦æ¥ç»§æ‰¿ã€‚ .. _header-output: -Documentation Output +文件输出 ==================== -When parsed by the compiler, documentation such as the one from the -above example will produce two different JSON files. One is meant to be -consumed by the end user as a notice when a function is executed and the -other to be used by the developer. +当被编译器解æžæ—¶ï¼Œåƒä¸Šé¢ä¾‹å­ä¸­çš„文档将产生两个ä¸åŒçš„JSON文件。 +一个是为了让终端用户在执行函数时作为通知使用,å¦ä¸€ä¸ªæ˜¯ä¸ºäº†è®©å¼€å‘人员使用。 -If the above contract is saved as ``ex1.sol`` then you can generate the -documentation using: +如果上述åˆçº¦è¢«ä¿å­˜ä¸º ``ex1.sol``,那么您å¯ä»¥ç”¨ä»¥ä¸‹æ–¹æ³•ç”Ÿæˆæ–‡æ¡£ï¼š .. code-block:: shell solc --userdoc --devdoc ex1.sol -And the output is below. +输出如下。 .. note:: - Starting Solidity version 0.6.11 the NatSpec output also contains a ``version`` and a ``kind`` field. - Currently the ``version`` is set to ``1`` and ``kind`` must be one of ``user`` or ``dev``. - In the future it is possible that new versions will be introduced, deprecating older ones. + 从Solidity 0.6.11版开始,NatSpec输出也包å«ä¸€ä¸ª ``version(版本å·ï¼‰`` 和一个 ``kind(ç§ç±»ï¼‰`` 字段。 + ç›®å‰ï¼Œ ``version`` 被设置为 ``1``, ``kind`` 必须是 ``user(用户)`` 或 ``dev(开å‘者)`` 之一。 + 在未æ¥ï¼Œæœ‰å¯èƒ½ä¼šå¼•å…¥æ–°çš„版本,淘汰旧的版本。 .. _header-user-doc: -User Documentation +用户文档 ------------------ -The above documentation will produce the following user documentation -JSON file as output: +上述文档将产生以下用户文档 JSON 文件作为输出: .. code-block:: json @@ -207,24 +203,21 @@ JSON file as output: { "age(uint256)" : { - "notice" : "Calculate tree age in years, rounded up, for live trees" + "notice" : "计算活体树木的树龄,按四èˆäº”入计算" } }, - "notice" : "You can use this contract for only the most basic simulation" + "notice" : "您åªèƒ½å°†æ­¤åˆçº¦ç”¨äºŽæœ€åŸºæœ¬çš„模拟。" } -Note that the key by which to find the methods is the function's -canonical signature as defined in the :ref:`Contract -ABI ` and not simply the function's -name. +请注æ„,找到方法的关键是 :ref:`åˆçº¦ ABI ` 中定义的函数的标准签å, +而ä¸æ˜¯ç®€å•çš„函数å称。 .. _header-developer-doc: -Developer Documentation +å¼€å‘者文档 ----------------------- -Apart from the user documentation file, a developer documentation JSON -file should also be produced and should look like this: +除了用户文档文件,还应该产生一个开å‘者文档的JSON文件,看起æ¥åº”该是这样的: .. code-block:: json @@ -232,19 +225,19 @@ file should also be produced and should look like this: "version" : 1, "kind" : "dev", "author" : "Larry A. Gardner", - "details" : "All function calls are currently implemented without side effects", - "custom:experimental" : "This is an experimental contract.", + "details" : "ç›®å‰æ‰€æœ‰çš„函数调用都是在没有副作用的情况下实现的", + "custom:experimental" : "这是一个实验性的åˆçº¦ã€‚", "methods" : { "age(uint256)" : { - "details" : "The Alexandr N. Tetearing algorithm could increase precision", + "details" : "Alexandr N. Tetearing 算法å¯ä»¥æ高精确度", "params" : { - "rings" : "The number of rings from dendrochronological sample" + "rings" : "树龄学样本的环数" }, - "return" : "age in years, rounded up for partial years" + "return" : "树龄(å²ï¼‰ï¼Œéƒ¨åˆ†å¹´ä»½å››èˆäº”å…¥" } }, - "title" : "A simulator for trees" + "title" : "树的模拟器" } diff --git a/docs/path-resolution.rst b/docs/path-resolution.rst index 666d9b8dc9ca..700d170988b5 100644 --- a/docs/path-resolution.rst +++ b/docs/path-resolution.rst @@ -1,91 +1,95 @@ .. _path-resolution: ********************** -Import Path Resolution +å¯¼å…¥è·¯å¾„è§£æž ********************** -In order to be able to support reproducible builds on all platforms, the Solidity compiler has to -abstract away the details of the filesystem where source files are stored. -Paths used in imports must work the same way everywhere while the command-line interface must be -able to work with platform-specific paths to provide good user experience. -This section aims to explain in detail how Solidity reconciles these requirements. +为了能够在所有平å°ä¸Šæ”¯æŒå¯é‡å¤çš„构建,Solidity 编译器必须抽象出存储æºæ–‡ä»¶çš„文件系统的细节。 +在导入中使用的路径必须在任何地方以åŒæ ·çš„æ–¹å¼å·¥ä½œï¼Œè€Œå‘½ä»¤è¡Œç•Œé¢å¿…须能够与平å°ç‰¹å®šçš„路径一起工作, +以æ供良好的用户体验。 +本节旨在详细解释 Solidity 是如何å调这些è¦æ±‚的。 .. index:: ! virtual filesystem, ! VFS, ! source unit name .. _virtual-filesystem: -Virtual Filesystem +虚拟文件系统 ================== -The compiler maintains an internal database (*virtual filesystem* or *VFS* for short) where each -source unit is assigned a unique *source unit name* which is an opaque and unstructured identifier. -When you use the :ref:`import statement `, you specify an *import path* that references a -source unit name. +编译器维护一个内部数æ®åº“( *虚拟文件系统* 或简称 *VFS* ), +æ¯ä¸ªæºå•å…ƒè¢«åˆ†é…一个唯一的 *æºå•å…ƒå称*,这是一个ä¸é€æ˜Žçš„éžç»“构化的标识符。 +当您使用 :ref:`import è¯­å¥ ` 时, +您指定了引用æºå•å…ƒå称的 *导入路径*。 .. index:: ! import callback, ! Host Filesystem Loader, ! --no-import-callback .. _import-callback: -Import Callback +导入回调 --------------- -The VFS is initially populated only with files the compiler has received as input. -Additional files can be loaded during compilation using an *import callback*, which is different -depending on the type of compiler you use (see below). -If the compiler does not find any source unit name matching the import path in the VFS, it invokes -the callback, which is responsible for obtaining the source code to be placed under that name. -An import callback is free to interpret source unit names in an arbitrary way, not just as paths. -If there is no callback available when one is needed or if it fails to locate the source code, -compilation fails. - +VFS最åˆåªå¡«å……了编译器收到的输入文件。 +在编译过程中å¯ä»¥ä½¿ç”¨ *import 回调* 加载其他文件, +但这å–决于您使用的编译器的类型(è§ä¸‹æ–‡ï¼‰ã€‚ +如果编译器在VFS中没有找到任何与导入路径相匹é…çš„æºå•å…ƒå称, +它就会调用回调,负责获å–è¦æ”¾åœ¨è¯¥å称下的æºä»£ç ã€‚ +一个导入回调å¯ä»¥è‡ªç”±åœ°ä»¥ä»»æ„æ–¹å¼è§£é‡Šæºå•å…ƒå称,而ä¸ä»…仅是作为路径。 +如果在需è¦å›žè°ƒæ—¶æ²¡æœ‰å¯ç”¨çš„回调,或者无法找到æºä»£ç ï¼Œç¼–译就会失败。 + +<<<<<<< HEAD +命令行编译器æ供了 *主机文件系统加载器* -- 一个基本的回调, +它将æºå•å…ƒå称解释为本地文件系统中的一个路径。 +`JavaScriptæŽ¥å£ `_ 默认ä¸æ供任何接å£ï¼Œ +但å¯ä»¥ç”±ç”¨æˆ·æ供一个。 +这个机制å¯ä»¥ç”¨æ¥ä»Žæœ¬åœ°æ–‡ä»¶ç³»ç»Ÿä»¥å¤–的地方获得æºä»£ç  +(本地文件系统甚至å¯èƒ½æ— æ³•è®¿é—®ï¼Œä¾‹å¦‚当编译器在æµè§ˆå™¨ä¸­è¿è¡Œæ—¶ï¼‰ã€‚ +例如, `Remix IDE `_ æ供了一个多功能的回调, +让您 `从HTTPã€IPFSå’ŒSwarm URL导入文件,或直接引用NPM注册表中的包 `_。 +======= By default, the command-line compiler provides the *Host Filesystem Loader* - a rudimentary callback that interprets a source unit name as a path in the local filesystem. This callback can be disabled using the ``--no-import-callback`` command-line option. The `JavaScript interface `_ does not provide any by default, but one can be provided by the user. -This mechanism can be used to obtain source code from locations other then the local filesystem +This mechanism can be used to obtain source code from locations other than the local filesystem (which may not even be accessible, e.g. when the compiler is running in a browser). For example the `Remix IDE `_ provides a versatile callback that lets you `import files from HTTP, IPFS and Swarm URLs or refer directly to packages in NPM registry `_. +>>>>>>> english/develop .. note:: - Host Filesystem Loader's file lookup is platform-dependent. - For example backslashes in a source unit name can be interpreted as directory separators or not - and the lookup can be case-sensitive or not, depending on the underlying platform. + 主机文件系统加载器的文件查找是ä¾èµ–于平å°çš„。 + 例如,æºå•å…ƒå称中的å斜线å¯ä»¥è¢«è§£é‡Šä¸ºç›®å½•åˆ†éš”符,也å¯ä»¥ä¸è¢«è§£é‡Šä¸ºç›®å½•åˆ†éš”符, + 查找时å¯ä»¥åŒºåˆ†å¤§å°å†™ï¼Œè¿™å–决于底层平å°ã€‚ - For portability it is recommended to avoid using import paths that will work correctly only - with a specific import callback or only on one platform. - For example you should always use forward slashes since they work as path separators also on - platforms that support backslashes. + 为了实现å¯ç§»æ¤æ€§ï¼Œæˆ‘们建议é¿å…使用åªæœ‰åœ¨ç‰¹å®šçš„导入回调中æ‰èƒ½æ­£å¸¸å·¥ä½œçš„导入路径, + 或者åªåœ¨ä¸€ä¸ªå¹³å°ä¸Šä½¿ç”¨ã€‚ + 例如,您应该总是使用正斜线,因为它们在支æŒå斜线的平å°ä¸Šä¹Ÿèƒ½ä½œä¸ºè·¯å¾„分隔符使用。 -Initial Content of the Virtual Filesystem +虚拟文件系统的åˆå§‹å†…容 ----------------------------------------- -The initial content of the VFS depends on how you invoke the compiler: +VFSçš„åˆå§‹å†…容å–决于您如何调用编译器: -#. **solc / command-line interface** +#. **solc / 命令行界é¢** - When you compile a file using the command-line interface of the compiler, you provide one or - more paths to files containing Solidity code: + 当您使用编译器的命令行界é¢ç¼–译一个文件时,您æ供一个或多个包å«Solidity代ç çš„文件的路径: .. code-block:: bash solc contract.sol /usr/local/dapp-bin/token.sol - The source unit name of a file loaded this way is constructed by converting its path to a - canonical form and, if possible, making it relative to either the base path or one of the - include paths. - See :ref:`CLI Path Normalization and Stripping ` for - a detailed description of this process. + 以这ç§æ–¹å¼åŠ è½½çš„文件的æºå•å…ƒå称是通过将其路径转æ¢ä¸ºè§„范的形å¼æ¥æž„建的, + 如果å¯èƒ½çš„è¯ï¼Œä½¿å…¶ä¸ŽåŸºæœ¬è·¯å¾„或其中一个包å«è·¯å¾„相对。 + å‚è§ :ref:`CLI路径规范化和剥离 ` 以了解这一过程的详细æ述。 .. index:: standard JSON -#. **Standard JSON** +#. **标准JSON** - When using the :ref:`Standard JSON ` API (via either the `JavaScript interface - `_ or the ``--standard-json`` command-line option) - you provide input in JSON format, containing, among other things, the content of all your source - files: + 当使用 :ref:`标准JSON ` APIæ—¶ + 通过 `JavaScriptæŽ¥å£ `_ 或 + `--standard-json` 命令行选项),您需æä¾›JSONæ ¼å¼çš„输入,其中包å«æ‚¨æ‰€æœ‰æºæ–‡ä»¶çš„内容。 .. code-block:: json @@ -105,15 +109,13 @@ The initial content of the VFS depends on how you invoke the compiler: "settings": {"outputSelection": {"*": { "*": ["metadata", "evm.bytecode"]}}} } - The ``sources`` dictionary becomes the initial content of the virtual filesystem and its keys - are used as source unit names. + 上é¢çš„ ``sources`` 字典结构æˆä¸ºè™šæ‹Ÿæ–‡ä»¶ç³»ç»Ÿçš„åˆå§‹å†…容,它的键被用作æºå•å…ƒå称。 .. _initial-vfs-content-standard-json-with-import-callback: -#. **Standard JSON (via import callback)** +#. **标准JSON(通过导入回调)** - With Standard JSON it is also possible to tell the compiler to use the import callback to obtain - the source code: + 通过标准JSON,也å¯ä»¥å‘Šè¯‰ç¼–译器使用导入回调æ¥èŽ·å¾—æºä»£ç ï¼š .. code-block:: json @@ -130,40 +132,41 @@ The initial content of the VFS depends on how you invoke the compiler: "settings": {"outputSelection": {"*": { "*": ["metadata", "evm.bytecode"]}}} } - If an import callback is available, the compiler will give it the strings specified in - ``urls`` one by one, until one is loaded successfully or the end of the list is reached. + 如果导入回调是å¯ç”¨çš„,编译器将一个一个地给它 ``urls`` 中指定的字符串,直到有一个被æˆåŠŸåŠ è½½æˆ–到达列表的末尾。 - The source unit names are determined the same way as when using ``content`` - they are keys of - the ``sources`` dictionary and the content of ``urls`` does not affect them in any way. + æºå•å…ƒå称的确定方å¼ä¸Žä½¿ç”¨ ``content`` æ—¶ç›¸åŒ - 它们是 ``sources`` 字典结构的键, + ``urls`` 的内容ä¸ä¼šä»¥ä»»ä½•æ–¹å¼å½±å“它们。 .. index:: standard input, stdin, -#. **Standard input** +#. **标准输入** +<<<<<<< HEAD + 在命令行中,也å¯ä»¥é€šè¿‡å°†æºä»£ç å‘é€åˆ°ç¼–译器的标准输入æ¥æä¾›æºä»£ç : +======= On the command-line it is also possible to provide the source by sending it to compiler's standard input: +>>>>>>> english/develop .. code-block:: bash echo 'import "./util.sol"; contract C {}' | solc - - ``-`` used as one of the arguments instructs the compiler to place the content of the standard - input in the virtual filesystem under a special source unit name: ````. + ``-`` 作为å‚数之一,指示编译器将标准输入的内容放在虚拟文件系统中的一个特殊的æºå•å…ƒå下: ````。 -Once the VFS is initialized, additional files can still be added to it only through the import -callback. +åˆå§‹åŒ–VFS之åŽï¼Œä»ç„¶å¯ä»¥å‘它添加其他文件,但åªèƒ½é€šè¿‡å¯¼å…¥å›žè°ƒçš„æ–¹å¼ã€‚ .. index:: ! import; path -Imports +导入 ======= -The import statement specifies an *import path*. -Based on how the import path is specified, we can divide imports into two categories: +导入语å¥æŒ‡å®šäº†ä¸€ä¸ª *导入路径*。 +æ ¹æ®å¯¼å…¥è·¯å¾„的指定方å¼ï¼Œæˆ‘们å¯ä»¥å°†å¯¼å…¥åˆ†ä¸ºä¸¤ç±»ï¼š -- :ref:`Direct imports `, where you specify the full source unit name directly. -- :ref:`Relative imports `, where you specify a path starting with ``./`` or ``../`` - to be combined with the source unit name of the importing file. +- :ref:`直接导入 `,直接指定完整的æºå•å…ƒå称。 +- :ref:`相对导入 `,指定一个以 ``./`` 或 ``../`` 开头的路径, + 与导入文件的æºå•å…ƒå称相结åˆã€‚ .. code-block:: solidity @@ -172,143 +175,129 @@ Based on how the import path is specified, we can divide imports into two catego import "./math/math.sol"; import "contracts/tokens/token.sol"; -In the above ``./math/math.sol`` and ``contracts/tokens/token.sol`` are import paths while the -source unit names they translate to are ``contracts/math/math.sol`` and ``contracts/tokens/token.sol`` -respectively. +在上é¢çš„ ``./math/math.sol`` å’Œ ``contracts/tokens/token.sol`` 都是导入路径, +然而它们转译æˆçš„æºå•å…ƒå分别是 ``contracts/math/math.sol`` å’Œ ``contracts/tokens/token.sol``。 .. index:: ! direct import, import; direct .. _direct-imports: -Direct Imports +直接导入 -------------- -An import that does not start with ``./`` or ``../`` is a *direct import*. +ä¸ä»¥ ``./`` 或 ``../`` 开头的导入是 *直接导入*。 .. code-block:: solidity - import "/project/lib/util.sol"; // source unit name: /project/lib/util.sol - import "lib/util.sol"; // source unit name: lib/util.sol - import "@openzeppelin/address.sol"; // source unit name: @openzeppelin/address.sol - import "https://example.com/token.sol"; // source unit name: https://example.com/token.sol + import "/project/lib/util.sol"; // æºå•å…ƒå称: /project/lib/util.sol + import "lib/util.sol"; // æºå•å…ƒå称: lib/util.sol + import "@openzeppelin/address.sol"; // æºå•å…ƒå称: @openzeppelin/address.sol + import "https://example.com/token.sol"; // æºå•å…ƒå称: https://example.com/token.sol -After applying any :ref:`import remappings ` the import path simply becomes the -source unit name. +在应用任何 :ref:`导入é‡æ˜ å°„ ` 之åŽï¼Œå¯¼å…¥è·¯å¾„简å•åœ°æˆä¸ºæºå•å…ƒå称。 .. note:: - A source unit name is just an identifier and even if its value happens to look like a path, it - is not subject to the normalization rules you would typically expect in a shell. - Any ``/./`` or ``/../`` segments or sequences of multiple slashes remain a part of it. - When the source is provided via Standard JSON interface it is entirely possible to associate - different content with source unit names that would refer to the same file on disk. + 一个æºå•å…ƒçš„åå­—åªæ˜¯ä¸€ä¸ªæ ‡è¯†ç¬¦ï¼Œå³ä½¿å®ƒçš„值碰巧看起æ¥åƒä¸€ä¸ªè·¯å¾„, + 它也ä¸å—您在shell中通常期望的规范化规则的约æŸã€‚ + 任何 ``/./`` 或 ``/../`` 的注释段或多个斜线的åºåˆ—都是它的一部分。 + 当æºæ˜¯é€šè¿‡æ ‡å‡†JSON接å£æ供的时候,完全有å¯èƒ½å°†ä¸åŒçš„内容与æºå•å…ƒçš„å称è”系起æ¥ï¼Œ + 这些å称将指代ç£ç›˜ä¸Šçš„åŒä¸€ä¸ªæ–‡ä»¶ã€‚ -When the source is not available in the virtual filesystem, the compiler passes the source unit name -to the import callback. -The Host Filesystem Loader will attempt to use it as a path and look up the file on disk. -At this point the platform-specific normalization rules kick in and names that were considered -different in the VFS may actually result in the same file being loaded. -For example ``/project/lib/math.sol`` and ``/project/lib/../lib///math.sol`` are considered -completely different in the VFS even though they refer to the same file on disk. +当æºæ–‡ä»¶åœ¨è™šæ‹Ÿæ–‡ä»¶ç³»ç»Ÿä¸­ä¸å¯ç”¨æ—¶ï¼Œç¼–译器会将æºå•å…ƒå称传递给导入回调。 +主机文件系统加载器将å°è¯•ä½¿ç”¨å®ƒä½œä¸ºè·¯å¾„并在ç£ç›˜ä¸ŠæŸ¥æ‰¾æ–‡ä»¶ã€‚ +在这一点上,平å°ç‰¹å®šçš„规范化规则开始å‘挥作用,在VFS中被认为是ä¸åŒçš„å字实际上å¯èƒ½å¯¼è‡´åŒä¸€ä¸ªæ–‡ä»¶è¢«åŠ è½½ã€‚ +例如, ``/project/lib/math.sol`` å’Œ ``/project/lib/../lib///math.sol`` +在VFS中被认为是完全ä¸åŒçš„,但它们在ç£ç›˜ä¸ŠæŒ‡å‘的是åŒä¸€ä¸ªæ–‡ä»¶ã€‚ .. note:: - Even if an import callback ends up loading source code for two different source unit names from - the same file on disk, the compiler will still see them as separate source units. - It is the source unit name that matters, not the physical location of the code. + å³ä½¿ä¸€ä¸ªå¯¼å…¥å›žè°ƒæœ€ç»ˆä»Žç£ç›˜ä¸Šçš„åŒä¸€ä¸ªæ–‡ä»¶ä¸­åŠ è½½äº†ä¸¤ä¸ªä¸åŒçš„æºå•å…ƒå称的æºä»£ç ï¼Œ + 编译器ä»ç„¶ä¼šå°†å®ƒä»¬è§†ä¸ºç‹¬ç«‹çš„æºå•å…ƒã€‚ + é‡è¦çš„是æºå•å…ƒå称,而ä¸æ˜¯ä»£ç çš„物ç†ä½ç½®ã€‚ .. index:: ! relative import, ! import; relative .. _relative-imports: -Relative Imports +相对导入 ---------------- -An import starting with ``./`` or ``../`` is a *relative import*. -Such imports specify a path relative to the source unit name of the importing source unit: +以 ``./`` 或 ``./`` 开头的导入是一个 *相对导入*。 +è¿™ç§å¯¼å…¥æŒ‡å®šäº†ä¸€ä¸ªç›¸å¯¹äºŽå¯¼å…¥æºå•å…ƒçš„æºå•å…ƒå称的路径。 .. code-block:: solidity :caption: /project/lib/math.sol - import "./util.sol" as util; // source unit name: /project/lib/util.sol - import "../token.sol" as token; // source unit name: /project/token.sol + import "./util.sol" as util; // æºå•å…ƒå称: /project/lib/util.sol + import "../token.sol" as token; // æºå•å…ƒå称: /project/token.sol .. code-block:: solidity :caption: lib/math.sol - import "./util.sol" as util; // source unit name: lib/util.sol - import "../token.sol" as token; // source unit name: token.sol + import "./util.sol" as util; // æºå•å…ƒå称: lib/util.sol + import "../token.sol" as token; // æºå•å…ƒå称: token.sol .. note:: - Relative imports **always** start with ``./`` or ``../`` so ``import "util.sol"``, unlike - ``import "./util.sol"``, is a direct import. - While both paths would be considered relative in the host filesystem, ``util.sol`` is actually - absolute in the VFS. + 相对导入 **总是** 以 ``./`` 或 ``./`` 开始, + 所以与 ``import "./util.sol"`` ä¸åŒï¼Œ ``import "util.sol"`` 是一个直接导入。 + 虽然这两个路径在主机文件系统中被认为是相对的,但 ``util.sol`` 在VFS中实际上是ç»å¯¹çš„。 -Let us define a *path segment* as any non-empty part of the path that does not contain a separator -and is bounded by two path separators. -A separator is a forward slash or the beginning/end of the string. -For example in ``./abc/..//`` there are three path segments: ``.``, ``abc`` and ``..``. +让我们把 *路径段* 定义为路径中ä¸åŒ…å«åˆ†éš”符的任何éžç©ºéƒ¨åˆ†ï¼Œå¹¶ä»¥ä¸¤ä¸ªè·¯å¾„分隔符为界。 +分隔符是一个正斜æ æˆ–字符串的开头/结尾。 +例如,在 ``./abc/...//`` 中,有三个路径段。 ``.``, ``abc`` å’Œ ``..``。 -The compiler resolves the import into a source unit name based on the import path, in the following way: +编译器根æ®å¯¼å…¥è·¯å¾„将导入解æžä¸ºä¸€ä¸ªæºå•å…ƒå称,方法如下: -#. We start with the source unit name of the importing source unit. -#. The last path segment with preceding slashes is removed from the resolved name. -#. Then, for every segment in the import path, starting from the leftmost one: +#. 我们从导入æºå•å…ƒçš„æºå•å…ƒå称开始。 +#. 最åŽä¸€ä¸ªå¸¦æœ‰æ–œçº¿çš„路径段将从解æžçš„å称中删除。 +#. 然åŽï¼Œå¯¹äºŽå¯¼å…¥è·¯å¾„中的æ¯ä¸€æ®µï¼Œä»Žæœ€å·¦è¾¹çš„一段开始: - - If the segment is ``.``, it is skipped. - - If the segment is ``..``, the last path segment with preceding slashes is removed from the resolved name. - - Otherwise, the segment (preceded by a single slash if the resolved name is not empty), is appended to the resolved name. + - 如果该段是 ``.``,则跳过。 + - 如果该段是 ``..``,最åŽä¸€ä¸ªå¸¦æœ‰æ–œçº¿çš„路径段将从解æžçš„å称中删除。 + - å¦åˆ™ï¼Œè¯¥æ®µï¼ˆå¦‚果解æžçš„å称ä¸æ˜¯ç©ºçš„,å‰é¢æœ‰ä¸€ä¸ªå•æ–œçº¿ï¼‰è¢«é™„加到解æžçš„å称上。 -The removal of the last path segment with preceding slashes is understood to -work as follows: +删除å‰é¢æœ‰æ–œçº¿çš„最åŽä¸€ä¸ªè·¯å¾„段,å¯ä»¥ç†è§£ä¸ºå·¥ä½œåŽŸç†å¦‚下: -1. Everything past the last slash is removed (i.e. ``a/b//c.sol`` becomes ``a/b//``). -2. All trailing slashes are removed (i.e. ``a/b//`` becomes ``a/b``). +1. 超过最åŽä¸€ä¸ªæ–œçº¿çš„æ‰€æœ‰å†…å®¹éƒ½è¢«åˆ é™¤ï¼ˆå³ ``a/b//c.sol`` å˜æˆ ``a/b//``)。 +2. æ‰€æœ‰çš„å°¾éƒ¨æ–œçº¿è¢«åˆ é™¤ï¼ˆå³ ``a/b//`` å˜æˆ ``a/b``)。 -Note that the process normalizes the part of the resolved source unit name that comes from the import path according -to the usual rules for UNIX paths, i.e. all ``.`` and ``..`` are removed and multiple slashes are -squashed into a single one. -On the other hand, the part that comes from the source unit name of the importing module remains unnormalized. -This ensures that the ``protocol://`` part does not turn into ``protocol:/`` if the importing file -is identified with a URL. +请注æ„ï¼Œè¯¥è¿‡ç¨‹æ ¹æ® UNIX 路径的通常规则对解æžçš„æºå•å…ƒå称中æ¥è‡ªå¯¼å…¥è·¯å¾„的部分进行了规范化处ç†ï¼Œ +å³æ‰€æœ‰çš„ ``.`` å’Œ ``..`` 被删除,多个斜线被压æˆä¸€ä¸ªã€‚ +å¦ä¸€æ–¹é¢ï¼Œæ¥è‡ªå¯¼å…¥æ¨¡å—çš„æºå•å…ƒå称的部分ä»æœªè¢«è§„范化。 +这确ä¿äº†åœ¨å¯¼å…¥æ–‡ä»¶è¢«è¯†åˆ«ä¸ºURL时, ``protocol://`` 部分ä¸ä¼šå˜æˆ ``protocol:/``。 -If your import paths are already normalized, you can expect the above algorithm to produce very -intuitive results. -Here are some examples of what you can expect if they are not: +如果导入路径已ç»è§„范化,则å¯ä»¥æœŸæœ›ä¸Šè¿°ç®—法产生éžå¸¸ç›´è§‚的结果。 +下é¢æ˜¯ä¸€äº›ä¾‹å­ï¼Œå‘Šè¯‰æ‚¨å¦‚æžœä¸æ˜¯çš„è¯ä¼šå‘生什么: .. code-block:: solidity :caption: lib/src/../contract.sol - import "./util/./util.sol"; // source unit name: lib/src/../util/util.sol - import "./util//util.sol"; // source unit name: lib/src/../util/util.sol - import "../util/../array/util.sol"; // source unit name: lib/src/array/util.sol - import "../.././../util.sol"; // source unit name: util.sol - import "../../.././../util.sol"; // source unit name: util.sol + import "./util/./util.sol"; // æºå•å…ƒå称: lib/src/../util/util.sol + import "./util//util.sol"; // æºå•å…ƒå称: lib/src/../util/util.sol + import "../util/../array/util.sol"; // æºå•å…ƒå称: lib/src/array/util.sol + import "../.././../util.sol"; // æºå•å…ƒå称: util.sol + import "../../.././../util.sol"; // æºå•å…ƒå称: util.sol .. note:: - The use of relative imports containing leading ``..`` segments is not recommended. - The same effect can be achieved in a more reliable way by using direct imports with - :ref:`base path and include paths `. + ä¸å»ºè®®ä½¿ç”¨ä½¿ç”¨åŒ…å«å‰ç¼€ ``..`` 的路径段。 + 通过使用带有 :ref:`基本路径和包å«è·¯å¾„ ` 的直接导入, + å¯ä»¥ä»¥æ›´å¯é çš„æ–¹å¼å®žçŽ°åŒæ ·çš„效果。 .. index:: ! base path, ! --base-path, ! include paths, ! --include-path .. _base-and-include-paths: -Base Path and Include Paths +基本路径和包å«è·¯å¾„ =========================== -The base path and include paths represent directories that the Host Filesystem Loader will load files from. -When a source unit name is passed to the loader, it prepends the base path to it and performs a -filesystem lookup. -If the lookup does not succeed, the same is done with all directories on the include path list. +基本路径和包å«è·¯å¾„表示主机文件系统加载器将加载文件的目录。 +当一个æºå•å…ƒçš„å字被传递给加载器时,它把基本路径加到它的å‰é¢ï¼Œå¹¶æ‰§è¡Œä¸€ä¸ªæ–‡ä»¶ç³»ç»ŸæŸ¥æ‰¾ã€‚ +如果查找ä¸æˆåŠŸï¼Œä¹Ÿä¼šå¯¹åŒ…å«è·¯å¾„列表中的所有目录进行åŒæ ·çš„处ç†ã€‚ -It is recommended to set the base path to the root directory of your project and use include paths to -specify additional locations that may contain libraries your project depends on. -This lets you import from these libraries in a uniform way, no matter where they are located in the -filesystem relative to your project. -For example, if you use npm to install packages and your contract imports -``@openzeppelin/contracts/utils/Strings.sol``, you can use these options to tell the compiler that -the library can be found in one of the npm package directories: +建议将基本路径设置为您项目的根目录,并使用包å«è·¯å¾„æ¥æŒ‡å®šå¯èƒ½åŒ…å«æ‚¨é¡¹ç›®æ‰€ä¾èµ–的库的其他ä½ç½®ã€‚ +è¿™å¯ä»¥è®©æ‚¨ä»¥ç»Ÿä¸€çš„æ–¹å¼ä»Žè¿™äº›åº“中导入,无论它们在文件系统中相对于您的项目ä½äºŽä½•å¤„。 +例如,如果您使用npm安装包,而您的åˆçº¦å¯¼å…¥äº† ``@openzeppelin/contracts/utils/Strings.sol``, +您å¯ä»¥ä½¿ç”¨è¿™äº›é€‰é¡¹æ¥å‘Šè¯‰ç¼–译器,该库å¯ä»¥åœ¨npm包目录中找到。 .. code-block:: bash @@ -317,35 +306,38 @@ the library can be found in one of the npm package directories: --include-path node_modules/ \ --include-path /usr/local/lib/node_modules/ -Your contract will compile (with the same exact metadata) no matter whether you install the library -in the local or global package directory or even directly under your project root. +无论您是把库安装在本地还是全局包目录下,甚至直接安装在您的项目根目录下, +您的åˆçº¦éƒ½ä¼šè¢«ç¼–译(具有完全相åŒçš„元数æ®ï¼‰ã€‚ -By default the base path is empty, which leaves the source unit name unchanged. -When the source unit name is a relative path, this results in the file being looked up in the -directory the compiler has been invoked from. -It is also the only value that results in absolute paths in source unit names being actually -interpreted as absolute paths on disk. -If the base path itself is relative, it is interpreted as relative to the current working directory -of the compiler. +默认情况下,基本路径是空的,这使得æºå•å…ƒçš„å称没有å˜åŒ–。 +当æºå•å…ƒå称是一个相对路径时,这将导致文件在编译器被调用的目录中被查找。 +这也是唯一能使æºå•å…ƒå称中的ç»å¯¹è·¯å¾„被实际解释为ç£ç›˜ä¸Šçš„ç»å¯¹è·¯å¾„的值。 +如果基本路径本身是相对的,则它被解释为相对于编译器的当å‰å·¥ä½œç›®å½•ã€‚ .. note:: - Include paths cannot have empty values and must be used together with a non-empty base path. + 包å«è·¯å¾„ä¸èƒ½æœ‰ç©ºå€¼ï¼Œå¿…须与éžç©ºçš„基本路径一起使用。 .. note:: - Include paths and base path can overlap as long as it does not make import resolution ambiguous. - For example, you can specify a directory inside base path as an include directory or have an - include directory that is a subdirectory of another include directory. - The compiler will only issue an error if the source unit name passed to the Host Filesystem - Loader represents an existing path when combined with multiple include paths or an include path - and base path. + åªè¦ä¸ä½¿å¯¼å…¥è§£æžäº§ç”Ÿæ­§ä¹‰ï¼ŒåŒ…å«è·¯å¾„和基本路径å¯ä»¥é‡åˆã€‚ + 例如,您å¯ä»¥åœ¨åŸºæœ¬è·¯å¾„内指定一个目录作为包å«ç›®å½•ï¼Œæˆ–者有一个包å«ç›®å½•æ˜¯å¦ä¸€ä¸ªåŒ…å«ç›®å½•çš„å­ç›®å½•ã€‚ + åªæœ‰ä¼ é€’给主机文件系统加载器的æºå•å…ƒå称在与多个包å«è·¯å¾„或包å«è·¯å¾„和基本路径结åˆä»£è¡¨ä¸€ä¸ªçŽ°æœ‰è·¯å¾„时, + 编译器æ‰ä¼šå‘出错误。 .. _cli-path-normalization-and-stripping: -CLI Path Normalization and Stripping +CLI路径规范化和剥离 ------------------------------------ +<<<<<<< HEAD +在命令行中,编译器的行为就åƒæ‚¨å¯¹å…¶ä»–程åºçš„期望一样: +它接å—å¹³å°çš„本地格å¼çš„路径,相对路径是相对于当å‰å·¥ä½œç›®å½•çš„。 +然而,分é…给在命令行上指定了路径的文件的æºå•å…ƒå称,ä¸åº”该因为项目在ä¸åŒçš„å¹³å°ä¸Šè¢«ç¼–译, +或者因为编译器碰巧从ä¸åŒçš„目录被调用而改å˜ã€‚ +为了达到这个目的,æ¥è‡ªå‘½ä»¤è¡Œçš„æºæ–‡ä»¶çš„路径必须被转æ¢ä¸ºè§„范的形å¼ï¼Œ +如果å¯èƒ½çš„è¯ï¼Œåº”使其与基本路径或包å«è·¯å¾„之一相对。 +======= On the command-line the compiler behaves just as you would expect from any other program: it accepts paths in a format native to the platform and relative paths are relative to the current working directory. @@ -354,51 +346,47 @@ should not change just because the project is being compiled on a different plat compiler happens to have been invoked from a different directory. To achieve this, paths to source files coming from the command-line must be converted to a canonical form, and, if possible, made relative to the base path or one of the include paths. +>>>>>>> english/develop -The normalization rules are as follows: +规范化规则如下: -- If a path is relative, it is made absolute by prepending the current working directory to it. -- Internal ``.`` and ``..`` segments are collapsed. -- Platform-specific path separators are replaced with forward slashes. -- Sequences of multiple consecutive path separators are squashed into a single separator (unless - they are the leading slashes of an `UNC path `_). -- If the path includes a root name (e.g. a drive letter on Windows) and the root is the same as the - root of the current working directory, the root is replaced with ``/``. -- Symbolic links in the path are **not** resolved. +- 如果一个路径是相对路径,则通过在其å‰é¢åŠ ä¸Šå½“å‰å·¥ä½œç›®å½•ä½¿å…¶æˆä¸ºç»å¯¹è·¯å¾„。 +- 内部的 ``.`` å’Œ ``..`` 段被折å èµ·æ¥ã€‚ +- å¹³å°ç‰¹å®šçš„路径分隔符被替æ¢ä¸ºæ­£æ–œæ ã€‚ +- 多个连续路径分隔符的åºåˆ—被压缩æˆä¸€ä¸ªåˆ†éš”符 + (除éžå®ƒä»¬æ˜¯ `UNC路径 `_ çš„å‰å¯¼æ–œæ ï¼‰ã€‚ +- 如果路径中包å«ä¸€ä¸ªæ ¹å(例如Windows系统中的一个盘符),并且该根å与当å‰å·¥ä½œç›®å½•çš„æ ¹å相åŒï¼Œ + 则根å将被替æ¢ä¸º ``/``。 +- 路径中的符å·é“¾æŽ¥ **没有** 解æžã€‚ - - The only exception is the path to the current working directory prepended to relative paths in - the process of making them absolute. - On some platforms the working directory is reported always with symbolic links resolved so for - consistency the compiler resolves them everywhere. + - 唯一的例外是在使相对路径æˆä¸ºç»å¯¹è·¯å¾„的过程中,对当å‰å·¥ä½œç›®å½•çš„路径进行了预处ç†ã€‚ + 在一些平å°ä¸Šï¼Œå·¥ä½œç›®å½•æ€»æ˜¯ç”¨å¸¦æœ‰ç¬¦å·é“¾æŽ¥çš„解æžæ¥å£°æ˜Žï¼Œ + 所以为了ä¿æŒä¸€è‡´æ€§ï¼Œç¼–译器在任何地方都会解æžå®ƒä»¬ã€‚ -- The original case of the path is preserved even if the filesystem is case-insensitive but - `case-preserving `_ and the actual case on - disk is different. +- å³ä½¿æ–‡ä»¶ç³»ç»Ÿå¯¹å¤§å°å†™ä¸æ•æ„Ÿï¼Œ + 但 `ä¿ç•™å¤§å°å†™ `_ + å’Œç£ç›˜ä¸Šçš„实际大å°å†™ä¸åŒï¼Œæ˜¯ä¼šä¿ç•™è·¯å¾„的原始大å°å†™ã€‚ .. note:: - There are situations where paths cannot be made platform-independent. - For example on Windows the compiler can avoid using drive letters by referring to the root - directory of the current drive as ``/`` but drive letters are still necessary for paths leading - to other drives. - You can avoid such situations by ensuring that all the files are available within a single - directory tree on the same drive. - -After normalization the compiler attempts to make the source file path relative. -It tries the base path first and then the include paths in the order they were given. -If the base path is empty or not specified, it is treated as if it was equal to the path to the -current working directory (with all symbolic links resolved). -The result is accepted only if the normalized directory path is the exact prefix of the normalized -file path. -Otherwise the file path remains absolute. -This makes the conversion unambiguous and ensures that the relative path does not start with ``../``. -The resulting file path becomes the source unit name. + 有些情况下,路径ä¸èƒ½ç‹¬ç«‹äºŽå¹³å°ã€‚ + 例如,在Windows下,编译器å¯ä»¥é€šè¿‡å°†å½“å‰é©±åŠ¨å™¨çš„根目录称为 ``/`` æ¥é¿å…使用驱动器字æ¯ï¼Œ + 但对于通往其他驱动器的路径æ¥è¯´ï¼Œé©±åŠ¨å™¨å­—æ¯ä»ç„¶æ˜¯å¿…è¦çš„。 + 您å¯ä»¥é€šè¿‡ç¡®ä¿æ‰€æœ‰çš„文件都在åŒä¸€é©±åŠ¨å™¨ä¸Šçš„å•ä¸€ç›®å½•æ ‘内,æ¥é¿å…è¿™ç§æƒ…况。 + +在规范化之åŽï¼Œç¼–译器试图使æºæ–‡ä»¶çš„路径å˜æˆç›¸å¯¹çš„。 +它首先å°è¯•åŸºæœ¬è·¯å¾„,然åŽæŒ‰ç…§ç»™å‡ºçš„顺åºå°è¯•åŒ…å«è·¯å¾„。 +如果基本路径是空的或者没有指定,它将被视为等åŒäºŽå½“å‰å·¥ä½œç›®å½•çš„路径(解决了所有符å·é“¾æŽ¥ï¼‰ã€‚ +åªæœ‰å½“规范化的目录路径是规范化的文件路径的确切å‰ç¼€æ—¶ï¼Œæ‰ä¼šæŽ¥å—这个结果。 +å¦åˆ™ï¼Œæ–‡ä»¶è·¯å¾„ä»ç„¶æ˜¯ç»å¯¹çš„。 +这使得转æ¢æ¯«ä¸å«ç³Šï¼Œå¹¶ç¡®ä¿ç›¸å¯¹è·¯å¾„ä¸ä»¥ ``.../`` 开头。 +产生的文件路径æˆä¸ºæºå•å…ƒå称。 .. note:: - The relative path produced by stripping must remain unique within the base path and include paths. - For example the compiler will issue an error for the following command if both - ``/project/contract.sol`` and ``/lib/contract.sol`` exist: + 剥离åŽäº§ç”Ÿçš„相对路径必须在基本路径和包å«è·¯å¾„中ä¿æŒå”¯ä¸€ã€‚ + 例如,如果 ``/project/contract.sol`` å’Œ ``/lib/contract.sol`` åŒæ—¶å­˜åœ¨ï¼Œ + 编译器将对以下命令å‘出错误: .. code-block:: bash @@ -406,34 +394,45 @@ The resulting file path becomes the source unit name. .. note:: +<<<<<<< HEAD + 在0.8.8版本之å‰ï¼ŒCLI路径剥离ä¸è¢«æ‰§è¡Œï¼Œå”¯ä¸€åº”用的规范化是路径分隔符的转æ¢ã€‚ + 当使用旧版本的编译器时,建议从基本路径调用编译器,在命令行上åªä½¿ç”¨ç›¸å¯¹è·¯å¾„。 +======= Prior to version 0.8.8, CLI path stripping was not performed and the only normalization applied was the conversion of path separators. When working with older versions of the compiler it is recommended to invoke the compiler from the base path and to only use relative paths on the command-line. +>>>>>>> english/develop .. index:: ! allowed paths, ! --allow-paths, remapping; target .. _allowed-paths: -Allowed Paths +å…许的路径 ============= -As a security measure, the Host Filesystem Loader will refuse to load files from outside of a few -locations that are considered safe by default: +作为一项安全措施,主机文件系统加载器将拒ç»ä»Žé»˜è®¤è®¤ä¸ºå®‰å…¨çš„几个ä½ç½®ä¹‹å¤–的地方加载文件: -- Outside of Standard JSON mode: +- 标准JSON模å¼ä¹‹å¤–: +<<<<<<< HEAD + - å«æœ‰å‘½ä»¤è¡Œä¸Šæ‰€åˆ—输入文件的目录。 + - 作为 :ref:`é‡æ˜ å°„ ` 目标使用的目录。 + 如果目标ä¸æ˜¯ä¸€ä¸ªç›®å½•ï¼ˆå³ä¸ä»¥ ``/``, ``/.`` 或 ``/.`` 结尾),则使用包å«è¯¥ç›®æ ‡çš„目录。 + - 基本路径和包å«è·¯å¾„。 +======= - The directories containing input files listed on the command-line. - The directories used as :ref:`remapping ` targets. If the target is not a directory (i.e does not end with ``/``, ``/.`` or ``/..``) the directory containing the target is used instead. - Base path and include paths. +>>>>>>> english/develop -- In Standard JSON mode: +- 在标准JSON模å¼ä¸‹ï¼š - - Base path and include paths. + - 基本路径和包å«è·¯å¾„。 -Additional directories can be whitelisted using the ``--allow-paths`` option. -The option accepts a comma-separated list of paths: +å¯ä»¥ä½¿ç”¨ ``--allow-paths`` 选项将其他目录列入白åå•ã€‚ +该选项接å—一个用逗å·åˆ†éš”的路径列表: .. code-block:: bash @@ -444,103 +443,98 @@ The option accepts a comma-separated list of paths: --include-path=/lib/ \ --allow-paths=../utils/,/tmp/libraries -When the compiler is invoked with the command shown above, the Host Filesystem Loader will allow -importing files from the following directories: +当用上é¢çš„命令调用编译器时,主机文件系统加载器将å…许从以下目录导入文件: -- ``/home/user/project/token/`` (because ``token/`` contains the input file and also because it is - the base path), -- ``/lib/`` (because ``/lib/`` is one of the include paths), -- ``/home/user/project/libs/`` (because ``libs/`` is a directory containing a remapping target), -- ``/home/user/utils/`` (because of ``../utils/`` passed to ``--allow-paths``), -- ``/tmp/libraries/`` (because of ``/tmp/libraries`` passed to ``--allow-paths``), +- ``/home/user/project/token/`` (因为 ``token/`` 包å«è¾“入文件,也因为它是基本路径), +- ``/lib/`` (因为 ``/lib/`` 是包å«è·¯å¾„之一), +- ``/home/user/project/libs/`` (因为 ``libs/`` 是一个包å«é‡æ˜ å°„目标的目录), +- ``/home/user/utils/`` (因为 ``.../utils/`` 传给了 ``-allow-paths`` ), +- ``/tmp/libraries/`` (因为 ``/tmp/libraries`` 被传递到 ``/tmp/libraries``), .. note:: - The working directory of the compiler is one of the paths allowed by default only if it - happens to be the base path (or the base path is not specified or has an empty value). + 编译器的工作目录是默认å…许的路径之一,å‰æ是它æ°å¥½æ˜¯åŸºæœ¬è·¯å¾„时(或者基本路径没有被指定或有一个空值)。 .. note:: - The compiler does not check if allowed paths actually exist and whether they are directories. - Non-existent or empty paths are simply ignored. - If an allowed path matches a file rather than a directory, the file is considered whitelisted, too. + 编译器ä¸æ£€æŸ¥å…许的路径是å¦çœŸå®žå­˜åœ¨ä»¥åŠå®ƒä»¬æ˜¯å¦æ˜¯ç›®å½•ã€‚ + ä¸å­˜åœ¨çš„或空的路径会被简å•åœ°å¿½ç•¥æŽ‰ã€‚ + 如果一个被å…许的路径与一个文件而ä¸æ˜¯ä¸€ä¸ªç›®å½•ç›¸åŒ¹é…,该文件也被视为白åå•ã€‚ .. note:: - Allowed paths are case-sensitive even if the filesystem is not. - The case must exactly match the one used in your imports. - For example ``--allow-paths tokens`` will not match ``import "Tokens/IERC20.sol"``. + å…许的路径是区分大å°å†™çš„,å³ä½¿æ–‡ä»¶ç³»ç»Ÿä¸æ˜¯è¿™æ ·çš„。 + 大å°å†™å¿…须与您的导入中使用的大å°å†™å®Œå…¨ä¸€è‡´ã€‚ + 例如 ``--allow-paths tokens`` ä¸ä¼šåŒ¹é… ``import "Tokens/IERC20.sol"``。 .. warning:: - Files and directories only reachable through symbolic links from allowed directories are not - automatically whitelisted. - For example if ``token/contract.sol`` in the example above was actually a symlink pointing at - ``/etc/passwd`` the compiler would refuse to load it unless ``/etc/`` was one of the allowed - paths too. + åªæœ‰é€šè¿‡å…许的目录的符å·é“¾æŽ¥æ‰èƒ½åˆ°è¾¾çš„文件和目录ä¸ä¼šè¢«è‡ªåŠ¨åˆ—入白åå•ã€‚ + 例如,如果上é¢çš„例å­ä¸­çš„ ``token/contract.sol`` å®žé™…ä¸Šæ˜¯ä¸€ä¸ªæŒ‡å‘ + ``/etc/passwd`` 的符å·é“¾æŽ¥ï¼Œç¼–译器将拒ç»åŠ è½½å®ƒï¼Œé™¤éž ``/etc/`` 也是å…许的路径之一。 .. index:: ! remapping; import, ! import; remapping, ! remapping; context, ! remapping; prefix, ! remapping; target .. _import-remapping: -Import Remapping +导入é‡æ˜ å°„ ================ -Import remapping allows you to redirect imports to a different location in the virtual filesystem. -The mechanism works by changing the translation between import paths and source unit names. -For example you can set up a remapping so that any import from the virtual directory -``github.com/ethereum/dapp-bin/library/`` would be seen as an import from ``dapp-bin/library/`` instead. +导入é‡æ˜ å°„å…许您将导入é‡å®šå‘到虚拟文件系统的ä¸åŒä½ç½®ã€‚ +该机制通过改å˜å¯¼å…¥è·¯å¾„å’Œæºå•å…ƒå称之间的转æ¢æ¥å·¥ä½œã€‚ +例如,您å¯ä»¥è®¾ç½®ä¸€ä¸ªé‡æ˜ å°„,使任何从虚拟目录 ``github.com/ethereum/dapp-bin/library/`` +的导入被视为从 ``dapp-bin/library/`` 导入。 -You can limit the scope of a remapping by specifying a *context*. -This allows creating remappings that apply only to imports located in a specific library or a specific file. -Without a context a remapping is applied to every matching import in all the files in the virtual -filesystem. +您å¯ä»¥é€šè¿‡æŒ‡å®š *context* æ¥é™åˆ¶é‡æ˜ å°„的范围。 +è¿™å…许创建仅适用于特定库或特定文件中的导入的é‡æ˜ å°„。 +如果没有context关键字指定,é‡æ˜ å°„将应用于虚拟文件系统中所有文件中的æ¯ä¸ªåŒ¹é…的导入。 -Import remappings have the form of ``context:prefix=target``: +导入é‡æ˜ å°„çš„å½¢å¼ä¸º ``context:prefix=target``: -- ``context`` must match the beginning of the source unit name of the file containing the import. -- ``prefix`` must match the beginning of the source unit name resulting from the import. -- ``target`` is the value the prefix is replaced with. +- ``context`` 必须与包å«å¯¼å…¥æ–‡ä»¶çš„æºå•å…ƒå称的开头相匹é…。 +- ``prefix`` 必须与导入的æºå•å…ƒå称的开头相匹é…。 +- ``target`` 是å‰ç¼€è¢«æ›¿æ¢çš„值。 -For example, if you clone https://github.com/ethereum/dapp-bin/ locally to ``/project/dapp-bin`` -and run the compiler with: +例如,如果您在本地克隆 https://github.com/ethereum/dapp-bin/ 到 ``/project/dapp-bin``, +并用以下命令è¿è¡Œç¼–译器: .. code-block:: bash solc github.com/ethereum/dapp-bin/=dapp-bin/ --base-path /project source.sol -you can use the following in your source file: +您å¯ä»¥åœ¨æ‚¨çš„æºæ–‡ä»¶ä¸­ä½¿ç”¨ä»¥ä¸‹å†…容: .. code-block:: solidity - import "github.com/ethereum/dapp-bin/library/math.sol"; // source unit name: dapp-bin/library/math.sol + import "github.com/ethereum/dapp-bin/library/math.sol"; // æºå•å…ƒå称: dapp-bin/library/math.sol +<<<<<<< HEAD +编译器将在VFSçš„ ``dapp bin/library/math.sol`` 下寻找该文件。 +如果那里没有该文件,æºå•å…ƒå称将被传递给主机文件系统加载器, +然åŽå®ƒå°†åœ¨ ``/project/dapp-bin/library/iterable_mapping.sol`` 中寻找。 +======= The compiler will look for the file in the VFS under ``dapp-bin/library/math.sol``. If the file is not available there, the source unit name will be passed to the Host Filesystem Loader, which will then look in ``/project/dapp-bin/library/math.sol``. +>>>>>>> english/develop .. warning:: - Information about remappings is stored in contract metadata. - Since the binary produced by the compiler has a hash of the metadata embedded in it, any - modification to the remappings will result in different bytecode. + 关于é‡æ˜ å°„çš„ä¿¡æ¯è¢«å­˜å‚¨åœ¨åˆçº¦å…ƒæ•°æ®ä¸­ã€‚ + 由于编译器产生的二进制文件中嵌入了元数æ®çš„哈希值,对é‡æ˜ å°„的任何修改都会导致ä¸åŒçš„字节ç ã€‚ - For this reason you should be careful not to include any local information in remapping targets. - For example if your library is located in ``/home/user/packages/mymath/math.sol``, a remapping - like ``@math/=/home/user/packages/mymath/`` would result in your home directory being included in - the metadata. - To be able to reproduce the same bytecode with such a remapping on a different machine, you - would need to recreate parts of your local directory structure in the VFS and (if you rely on - Host Filesystem Loader) also in the host filesystem. + 由于这个原因,您应该注æ„ä¸è¦åœ¨é‡æ˜ å°„目标中包å«ä»»ä½•æœ¬åœ°ä¿¡æ¯ã€‚ + 例如,如果您的库ä½äºŽ ``/home/user/packages/mymath/math.sol``, + åƒ ``@math/=/home/user/packages/mymath/`` 这样的é‡æ˜ å°„会导致您的主目录被包å«åœ¨å…ƒæ•°æ®ä¸­ã€‚ + 为了能够在ä¸åŒçš„机器上用这样的é‡æ˜ å°„é‡çŽ°ç›¸åŒçš„字节ç ï¼Œ + 您需è¦åœ¨VFS和(如果您ä¾èµ–主机文件系统加载器)主机文件系统中é‡æ–°åˆ›å»ºæ‚¨çš„本地目录结构。 - To avoid having your local directory structure embedded in the metadata, it is recommended to - designate the directories containing libraries as *include paths* instead. - For example, in the example above ``--include-path /home/user/packages/`` would let you use - imports starting with ``mymath/``. - Unlike remapping, the option on its own will not make ``mymath`` appear as ``@math`` but this - can be achieved by creating a symbolic link or renaming the package subdirectory. + 为了é¿å…元数æ®ä¸­åµŒå…¥æ‚¨çš„本地目录结构,建议将包å«åº“的目录指定为 *include paths*。 + 例如,在上é¢çš„例å­ä¸­ï¼Œ ``--include-path /home/user/packages/`` 会让您使用以 ``mymath/`` 开始的导入。 + 与é‡æ˜ å°„ä¸åŒï¼Œè¯¥é€‰é¡¹æœ¬èº«ä¸ä¼šä½¿ ``mymath`` 显示为 ``@math``, + 但这å¯ä»¥é€šè¿‡åˆ›å»ºç¬¦å·é“¾æŽ¥æˆ–é‡å‘½å软件包å­ç›®å½•æ¥å®žçŽ°ã€‚ -As a more complex example, suppose you rely on a module that uses an old version of dapp-bin that -you checked out to ``/project/dapp-bin_old``, then you can run: +作为一个更å¤æ‚的例å­ï¼Œå‡è®¾æ‚¨ä¾èµ–一个使用旧版dapp-bin的模å—, +您把它签出到 ``/project/dapp-bin_old``,那么您å¯ä»¥è¿è¡Œï¼š .. code-block:: bash @@ -549,112 +543,107 @@ you checked out to ``/project/dapp-bin_old``, then you can run: --base-path /project \ source.sol -This means that all imports in ``module2`` point to the old version but imports in ``module1`` -point to the new version. +è¿™æ„å‘³ç€ ``module2`` 的所有导入都指å‘旧版本,但 ``module1`` 的导入则指å‘新版本。 +<<<<<<< HEAD +以下是关于é‡æ˜ å°„行为的详细规则: +======= Here are the detailed rules governing the behavior of remappings: +>>>>>>> english/develop -#. **Remappings only affect the translation between import paths and source unit names.** +#. **é‡æ–°æ˜ å°„åªå½±å“导入路径和æºå•å…ƒå称之间的转æ¢ã€‚** - Source unit names added to the VFS in any other way cannot be remapped. - For example the paths you specify on the command-line and the ones in ``sources.urls`` in - Standard JSON are not affected. + 以任何其他方å¼æ·»åŠ åˆ°VFSçš„æºå•å…ƒå称ä¸èƒ½è¢«é‡æ–°æ˜ å°„。 + 例如,您在命令行上指定的路径和标准JSON中 ``sources.urls`` 中的路径ä¸å—å½±å“。 .. code-block:: bash - solc /project/=/contracts/ /project/contract.sol # source unit name: /project/contract.sol + solc /project/=/contracts/ /project/contract.sol # æºå•å…ƒå称: /project/contract.sol - In the example above the compiler will load the source code from ``/project/contract.sol`` and - place it under that exact source unit name in the VFS, not under ``/contract/contract.sol``. + 在上é¢çš„例å­ä¸­ï¼Œç¼–译器将从 ``/project/contract.sol`` 中加载æºä»£ç ï¼Œ + 并将其放在VFS中那个确切的æºä»£ç å•å…ƒå下,而ä¸æ˜¯æ”¾åœ¨ ``/contract/contract.sol`` 中。 -#. **Context and prefix must match source unit names, not import paths.** +#. **上下文和å‰ç¼€å¿…须与æºå•å…ƒå称相匹é…,而ä¸æ˜¯å¯¼å…¥è·¯å¾„。** - - This means that you cannot remap ``./`` or ``../`` directly since they are replaced during - the translation to source unit name but you can remap the part of the name they are replaced - with: + - è¿™æ„味ç€æ‚¨ä¸èƒ½ç›´æŽ¥é‡æ–°æ˜ å°„ ``./`` 或 ``./``,因为它们在转译æˆæºå•å…ƒå称时被替æ¢äº†ï¼Œ + 但您å¯ä»¥é‡æ–°æ˜ å°„它们被替æ¢çš„那部分å称: .. code-block:: bash - solc ./=a/ /project/=b/ /project/contract.sol # source unit name: /project/contract.sol + solc ./=a/ /project/=b/ /project/contract.sol # æºå•å…ƒå称: /project/contract.sol .. code-block:: solidity :caption: /project/contract.sol - import "./util.sol" as util; // source unit name: b/util.sol + import "./util.sol" as util; // æºå•å…ƒå称: b/util.sol - - You cannot remap base path or any other part of the path that is only added internally by an - import callback: + - 您ä¸èƒ½é‡æ–°æ˜ å°„基本路径或仅由导入回调内部添加的任何其他部分的路径。 .. code-block:: bash - solc /project/=/contracts/ /project/contract.sol --base-path /project # source unit name: contract.sol + solc /project/=/contracts/ /project/contract.sol --base-path /project # æºå•å…ƒå称: contract.sol .. code-block:: solidity :caption: /project/contract.sol - import "util.sol" as util; // source unit name: util.sol + import "util.sol" as util; // æºå•å…ƒå称: util.sol -#. **Target is inserted directly into the source unit name and does not necessarily have to be a valid path.** +#. **目标直接æ’å…¥æºå•å…ƒå称中,ä¸ä¸€å®šæ˜¯æœ‰æ•ˆçš„路径。** - - It can be anything as long as the import callback can handle it. - In case of the Host Filesystem Loader this includes also relative paths. - When using the JavaScript interface you can even use URLs and abstract identifiers if - your callback can handle them. + - åªè¦å¯¼å…¥å›žè°ƒèƒ½å¤Ÿå¤„ç†å®ƒï¼Œå®ƒå¯ä»¥æ˜¯ä»»ä½•ä¸œè¥¿ã€‚ + 在主机文件系统加载器的情况下,这也包括相对路径。 + 当使用JavaScript接å£æ—¶ï¼Œæ‚¨ç”šè‡³å¯ä»¥ä½¿ç”¨URL和抽象标识符, + 如果您的回调能够处ç†å®ƒä»¬ã€‚ - - Remapping happens after relative imports have already been resolved into source unit names. - This means that targets starting with ``./`` and ``../`` have no special meaning and are - relative to the base path rather than to the location of the source file. + - é‡æ˜ å°„å‘生在相对导入已ç»è¢«è§£æžä¸ºæºå•å…ƒå称之åŽã€‚ + è¿™æ„味ç€ä»¥ ``./`` å’Œ ``./`` 开头的目标没有特殊å«ä¹‰ï¼Œæ˜¯ç›¸å¯¹äºŽåŸºæœ¬è·¯å¾„而ä¸æ˜¯æºæ–‡ä»¶çš„ä½ç½®ã€‚ - - Remapping targets are not normalized so ``@root/=./a/b//`` will remap ``@root/contract.sol`` - to ``./a/b//contract.sol`` and not ``a/b/contract.sol``. + - é‡æ˜ å°„目标没有被规范化,所以 ``@root/=./a/b//`` å°†é‡æ˜ å°„ + ``@root/contract.sol`` 到 ``./a/b/contract.sol`` 而ä¸æ˜¯ ``a/b/contract.sol``。 - - If the target does not end with a slash, the compiler will not add one automatically: + - 如果目标ä¸ä»¥æ–œçº¿ç»“尾,编译器将ä¸ä¼šè‡ªåŠ¨æ·»åŠ ä¸€ä¸ªæ–œçº¿: .. code-block:: bash - solc /project/=/contracts /project/contract.sol # source unit name: /project/contract.sol + solc /project/=/contracts /project/contract.sol # æºå•å…ƒå称: /project/contract.sol .. code-block:: solidity :caption: /project/contract.sol - import "/project/util.sol" as util; // source unit name: /contractsutil.sol + import "/project/util.sol" as util; // æºå•å…ƒå称: /contractsutil.sol -#. **Context and prefix are patterns and matches must be exact.** +#. **上下文和å‰ç¼€æ˜¯åŒ¹é…模å¼ï¼ŒåŒ¹é…必须是精确的。** - - ``a//b=c`` will not match ``a/b``. - - source unit names are not normalized so ``a/b=c`` will not match ``a//b`` either. - - Parts of file and directory names can match as well. - ``/newProject/con:/new=old`` will match ``/newProject/contract.sol`` and remap it to - ``oldProject/contract.sol``. + - ``a//b=c`` ä¸ä¼šåŒ¹é… ``a/b``。 + - æºå•å…ƒå称没有被规范化,所以 ``a/b=c`` 也ä¸ä¼šåŒ¹é… ``a//b``。 + - 文件和目录的部分å称是å¯ä»¥åŒ¹é…。 + ``/newProject/con:/new=old`` å°†åŒ¹é… ``/newProject/contract.sol`` + 并将其é‡æ–°æ˜ å°„到 ``oldProject/contract.sol``。 -#. **At most one remapping is applied to a single import.** +#. **最多åªæœ‰ä¸€ä¸ªé‡æ˜ å°„被应用于å•ä¸ªå¯¼å…¥ã€‚** - - If multiple remappings match the same source unit name, the one with the longest matching - prefix is chosen. - - If prefixes are identical, the one specified last wins. - - Remappings do not work on other remappings. For example ``a=b b=c c=d`` will not result in ``a`` - being remapped to ``d``. + - 如果多个é‡æ˜ å°„与åŒä¸€ä¸ªæºå•å…ƒå称相匹é…,则选择具有最长匹é…å‰ç¼€çš„那个。 + - 如果å‰ç¼€ç›¸åŒï¼Œåˆ™é€‰æ‹©æœ€åŽæŒ‡å®šçš„那个。 + - é‡æ˜ å°„对其他é‡æ˜ å°„ä¸èµ·ä½œç”¨ã€‚例如 ``a=b b=c c=d`` ä¸ä¼šå¯¼è‡´ ``a`` 被é‡æ˜ å°„到 ``d``。 -#. **Prefix cannot be empty but context and target are optional.** +#. **prefixä¸èƒ½ä¸ºç©ºï¼Œä½†contextå’Œtarget是å¯é€‰çš„。** - - If ``target`` is the empty string, ``prefix`` is simply removed from import paths. - - Empty ``context`` means that the remapping applies to all imports in all source units. + - 如果 ``target`` 是空字符串, ``prefix`` 将从导入路径中删除。 + - 空的 ``context`` æ„味ç€é‡æ–°æ˜ å°„适用于所有æºå•å…ƒä¸­çš„所有导入。 .. index:: Remix IDE, file:// -Using URLs in imports +在导入中使用url ===================== -Most URL prefixes such as ``https://`` or ``data://`` have no special meaning in import paths. -The only exception is ``file://`` which is stripped from source unit names by the Host Filesystem -Loader. +大多数URLå‰ç¼€ï¼Œå¦‚ ``https://`` 或 ``data://`` 在导入路径中没有特殊å«ä¹‰ã€‚ +唯一的例外是 ``file://``,它被主机文件系统加载器从æºå•å…ƒå称中剥离出æ¥ã€‚ -When compiling locally you can use import remapping to replace the protocol and domain part with a -local path: +在本地编译时,您å¯ä»¥ä½¿ç”¨å¯¼å…¥é‡æ˜ å°„,用本地路径替æ¢å议和域å部分: .. code-block:: bash solc :https://github.com/ethereum/dapp-bin=/usr/local/dapp-bin contract.sol -Note the leading ``:``, which is necessary when the remapping context is empty. -Otherwise the ``https:`` part would be interpreted by the compiler as the context. +注æ„å‰é¢çš„ ``:``,当é‡æ˜ å°„上下文为空时,这是必è¦çš„。 +å¦åˆ™ï¼Œ ``https:`` 部分将被编译器解释为上下文。 diff --git a/docs/resources.rst b/docs/resources.rst index 84df74fb73cb..82f043585c1e 100644 --- a/docs/resources.rst +++ b/docs/resources.rst @@ -1,150 +1,165 @@ ######### -Resources +èµ„æº ######### -General Resources +ä¸€èˆ¬èµ„æº ================= -* `Ethereum.org Developer Portal `_ +* `Ethereum.orgå¼€å‘者门户网站 `_ * `Ethereum StackExchange `_ -* `Solidity Portal `_ -* `Solidity Changelog `_ -* `Solidity Source Code on GitHub `_ -* `Solidity Language Users Chat `_ -* `Solidity Compiler Developers Chat `_ -* `Awesome Solidity `_ -* `Solidity by Example `_ -* `Solidity Documentation Community Translations `_ - -Integrated (Ethereum) Development Environments +* `Solidity门户网站 `_ +* `Solidityå˜æ›´æ—¥å¿— `_ +* `GitHub上的Solidityæºä»£ç  `_ +* `Solidity语言用户èŠå¤©å®¤ `_ +* `Solidity编译器开å‘人员èŠå¤©å®¤ `_ +* `很棒的Solidity `_ +* `通过实例学Solidity `_ +* `Solidity文档社区翻译 `_ + +集æˆï¼ˆä»¥å¤ªåŠï¼‰å¼€å‘环境 ============================================== * `Brownie `_ - Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine. + é¢å‘以太åŠè™šæ‹Ÿæœºçš„基于Python的智能åˆçº¦å¼€å‘和测试框架。 * `Dapp `_ - Tool for building, testing and deploying smart contracts from the command-line. +<<<<<<< HEAD + 用于从命令行构建,测试和部署智能åˆçº¦çš„工具。 * `Embark `_ - Developer platform for building and deploying decentralized applications. + 构建和部署去中心化应用程åºçš„å¼€å‘者平å°ã€‚ +======= + Tool for building, testing and deploying smart contracts from the command-line. +>>>>>>> english/develop * `Foundry `_ - Fast, portable and modular toolkit for Ethereum application development written in Rust. + 用Rust编写的用于Ethereum应用开å‘的快速,å¯ç§»æ¤å’Œæ¨¡å—化的工具包。 * `Hardhat `_ - Ethereum development environment with local Ethereum network, debugging features and plugin ecosystem. + 以太åŠå¼€å‘环境具有本地以太åŠç½‘络,调试功能和æ’件生æ€ç³»ç»Ÿã€‚ * `Remix `_ - Browser-based IDE with integrated compiler and Solidity runtime environment without server-side components. + 基于æµè§ˆå™¨çš„IDE,具有集æˆçš„编译器和Solidityè¿è¡ŒçŽ¯å¢ƒï¼Œæ²¡æœ‰æœåŠ¡å™¨ç«¯ç»„件。 * `Truffle `_ - Ethereum development framework. + 以太åŠå¼€å‘框架。 -Editor Integrations +ç¼–è¾‘å™¨é›†æˆ =================== * Emacs * `Emacs Solidity `_ - Plugin for the Emacs editor providing syntax highlighting and compilation error reporting. + Emacs编辑器的æ’件,æ供语法高亮和编译错误报告。 * IntelliJ - * `IntelliJ IDEA plugin `_ - Solidity plugin for IntelliJ IDEA (and all other JetBrains IDEs). + * `IntelliJ IDEA æ’件 `_ + IntelliJ IDEA(和所有其他JetBrains IDEs)的Solidityæ’件 * Sublime Text - * `Package for SublimeText - Solidity language syntax `_ - Solidity syntax highlighting for SublimeText editor. + * `SublimeText的软件包 - Solidity语言语法 `_ + 用于 SublimeText 编辑器的 Solidity 语法高亮。 * Vim - * `Vim Solidity by Thesis `_ - Syntax highlighting for Solidity in Vim. + * `Thesis çš„ Vim Solidity `_ + Vim 中 Solidity 的语法高亮。 - * `Vim Solidity by TovarishFin `_ - Vim syntax file for Solidity. + * `TovarishFin çš„ Vim Solidity `_ + Solidity çš„ Vim 语法文件。 * `Vim Syntastic `_ - Plugin for the Vim editor providing compile checking. + 为Vim编辑器æ供编译检查的æ’件。 * Visual Studio Code (VS Code) +<<<<<<< HEAD + * `ä»¥å¤ªåŠ Remix çš„ Visual Studio 代ç æ‰©å±•åŒ… `_ + VS Code çš„ä»¥å¤ªåŠ Remix 扩展包 +======= * `Ethereum Remix Visual Studio Code extension `_ Ethereum Remix extension pack for VS Code +>>>>>>> english/develop - * `Solidity Visual Studio Code extension, by Juan Blanco `_ - Solidity plugin for Microsoft Visual Studio Code that includes syntax highlighting and the Solidity compiler. + * `Juan Blanco çš„ Solidity Visual Studio 代ç æ‰©å±•åŒ… `_ + Microsoft Visual Studio Code çš„ Solidity æ’件,包括语法高亮和 Solidity 编译器。 - * `Solidity Visual Studio Code extension, by Nomic Foundation `_ - Solidity and Hardhat support by the Hardhat team, including: syntax highlighting, jump to definition, renames, quick fixes and inline solc warnings and errors. + * `Nomic Foundation çš„ Solidity Visual Studio 代ç æ‰©å±•åŒ… `_ + ç”±Hardhat团队æ供的Solidityå’ŒHardhat支æŒï¼ŒåŒ…括:语法高亮,跳转到定义,é‡å‘½å,快速修å¤å’Œå†…è”solc警告和错误。 - * `Solidity Visual Auditor extension `_ - Adds security centric syntax and semantic highlighting to Visual Studio Code. + * `Solidity å¯è§†åŒ–审计扩展 `_ + 在Visual Studio Code中增加了以安全为中心的语法和语义çªå‡ºæ˜¾ç¤ºã€‚ - * `Truffle for VS Code `_ - Build, debug and deploy smart contracts on Ethereum and EVM-compatible blockchains. + * `用于 VS Code çš„ Truffle `_ + 在Ethereumå’ŒEVM兼容的区å—链上构建,调试和部署智能åˆçº¦ã€‚ -Solidity Tools +Solidity 工具 ============== -* `ABI to Solidity interface converter `_ - A script for generating contract interfaces from the ABI of a smart contract. +* `ABI到Solidity接å£è½¬æ¢å™¨ `_ + 一个用于从智能åˆçº¦çš„ABI生æˆåˆçº¦æŽ¥å£çš„脚本。 * `abi-to-sol `_ - Tool to generate Solidity interface source from a given ABI JSON. + 从一个给定的ABI JSON生æˆSolidity接å£æºçš„工具。 * `Doxity `_ - Documentation Generator for Solidity. + Solidity的文档生æˆå™¨ã€‚ * `Ethlint `_ - Linter to identify and fix style and security issues in Solidity. + 识别和修å¤Solidity中的风格和安全问题的语法检查器。 * `evmdis `_ - EVM Disassembler that performs static analysis on the bytecode to provide a higher level of abstraction than raw EVM operations. + EVMå汇编程åºï¼Œå¯¹å­—节ç è¿›è¡Œé™æ€åˆ†æžï¼Œæ供比原始EVMæ“作更高的抽象水平。 * `EVM Lab `_ - Rich tool package to interact with the EVM. Includes a VM, Etherchain API, and a trace-viewer with gas cost display. + 丰富的工具包,与EVM互动。包括一个虚拟机ã€ä»¥å¤ªé“¾API,以åŠä¸€ä¸ªå¸¦æœ‰gasæˆæœ¬æ˜¾ç¤ºçš„跟踪查看器。 * `hevm `_ - EVM debugger and symbolic execution engine. + EVM调试器和符å·æ‰§è¡Œå¼•æ“Žã€‚ * `leafleth `_ - A documentation generator for Solidity smart-contracts. + Solidity智能åˆçº¦çš„文档生æˆå™¨ã€‚ + +<<<<<<< HEAD +* `PIET `_ + 一个通过简å•å›¾å½¢ç•Œé¢å¼€å‘,审计和使用Solidity智能åˆçº¦çš„工具。 +======= +>>>>>>> english/develop * `Scaffold-ETH `_ - Forkable Ethereum development stack focused on fast product iterations. + 专注于产å“快速迭代的å¯åˆ†å‰çš„以太åŠå¼€å‘堆栈。 * `sol2uml `_ - Unified Modeling Language (UML) class diagram generator for Solidity contracts. + Solidityåˆçº¦çš„统一建模语言(UML)类图生æˆå™¨ã€‚ * `solc-select `_ - A script to quickly switch between Solidity compiler versions. + 一个在 Solidity 编译器版本之间快速切æ¢çš„脚本。 -* `Solidity prettier plugin `_ - A Prettier Plugin for Solidity. +* `优化Solidity语言格å¼æ’件 `_ + Solidityæ ¼å¼ç¾ŽåŒ–æ’件。 * `Solidity REPL `_ - Try Solidity instantly with a command-line Solidity console. + 使用命令行solidity控制å°ç«‹å³å°è¯•solidity。 * `solgraph `_ - Visualize Solidity control flow and highlight potential security vulnerabilities. + å¯è§†åŒ–Solidity控制æµå¹¶çªå‡ºæ½œåœ¨çš„安全æ¼æ´žã€‚ * `Solhint `_ - Solidity linter that provides security, style guide and best practice rules for smart contract validation. + Solidity语法检查器,为智能åˆçº¦çš„验è¯æ供安全,风格指å—和最佳实践规则。 * `Sourcify `_ - Decentralized automated contract verification service and public repository of contract metadata. + 去中心化的自动åˆçº¦éªŒè¯æœåŠ¡å’Œåˆçº¦å…ƒæ•°æ®çš„公共存储库。 * `SÅ«rya `_ - Utility tool for smart contract systems, offering a number of visual outputs and information about the contracts' structure. Also supports querying the function call graph. + 智能åˆçº¦ç³»ç»Ÿçš„实用工具,æ供一些å¯è§†åŒ–输出和关于åˆçº¦ç»“æž„çš„ä¿¡æ¯ã€‚还支æŒæŸ¥è¯¢å‡½æ•°è°ƒç”¨å›¾ã€‚ * `Universal Mutator `_ - A tool for mutation generation, with configurable rules and support for Solidity and Vyper. + 一个用于çªå˜ç”Ÿæˆçš„工具,具有å¯é…置的规则并支æŒSolidityå’ŒVyper。 -Third-Party Solidity Parsers and Grammars +第三方Solidity解æžå™¨å’Œè¯­æ³• ========================================= -* `Solidity Parser for JavaScript `_ - A Solidity parser for JS built on top of a robust ANTLR4 grammar. +* `用于JavaScriptçš„Solidity解æžå™¨ `_ + 一个建立在强大的ANTLR4语法之上的JS Solidity解æžå™¨ã€‚ diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst index 92d601043dd7..838ed376f405 100644 --- a/docs/security-considerations.rst +++ b/docs/security-considerations.rst @@ -1,93 +1,93 @@ .. _security_considerations: ####################### -Security Considerations +安全考虑 ####################### -While it is usually quite easy to build software that works as expected, -it is much harder to check that nobody can use it in a way that was **not** anticipated. +虽然通常很容易建立起按预期工作的软件,但è¦æ£€æŸ¥æ²¡æœ‰äººèƒ½å¤Ÿä»¥ **éž** 预期的方å¼ä½¿ç”¨å®ƒï¼Œå°±éš¾å¾—多了。 -In Solidity, this is even more important because you can use smart contracts to handle tokens or, -possibly, even more valuable things. -Furthermore, every execution of a smart contract happens in public and, -in addition to that, the source code is often available. +在 Solidity 中,这一点更加é‡è¦ï¼Œå› ä¸ºæ‚¨å¯ä»¥ä½¿ç”¨æ™ºèƒ½åˆçº¦æ¥å¤„ç†ä»£å¸ï¼Œ +甚至å¯èƒ½æ˜¯æ›´æœ‰ä»·å€¼çš„东西。 +此外,智能åˆçº¦çš„æ¯ä¸€æ¬¡æ‰§è¡Œéƒ½æ˜¯å…¬å¼€çš„, +除此之外,æºä»£ç ä¹Ÿé€šå¸¸æ˜¯å®¹æ˜“获得的。 -Of course, you always have to consider how much is at stake: -You can compare a smart contract with a web service that is open to the public -(and thus, also to malicious actors) and perhaps even open-source. -If you only store your grocery list on that web service, you might not have to take too much care, -but if you manage your bank account using that web service, you should be more careful. +当然,您总是è¦è€ƒè™‘有多大的风险: +您å¯ä»¥å°†æ™ºèƒ½åˆçº¦ä¸Žä¸€ä¸ªå¯¹å…¬ä¼—开放 +(因此也对æ¶æ„行为者开放),甚至å¯èƒ½æ˜¯å¼€æºçš„网络æœåŠ¡è¿›è¡Œæ¯”较。 +如果您åªåœ¨è¯¥ç½‘络æœåŠ¡ä¸Šå­˜å‚¨æ‚¨çš„æ‚货清å•ï¼Œæ‚¨å¯èƒ½ä¸å¿…太过å°å¿ƒï¼Œ +但如果您使用该网络æœåŠ¡ç®¡ç†æ‚¨çš„银行账户,您就应该更加å°å¿ƒã€‚ -This section will list some pitfalls and general security recommendations -but can, of course, never be complete. -Also, keep in mind that even if your smart contract code is bug-free, -the compiler or the platform itself might have a bug. -A list of some publicly known security-relevant bugs of the compiler can be found -in the :ref:`list of known bugs`, which is also machine-readable. -Note that there is a `Bug Bounty Program `_ -that covers the code generator of the Solidity compiler. +本节将列出一些陷阱和一般安全建议, +但当然,这ä¸å¯èƒ½æ˜¯å®Œæ•´çš„。 +此外,请记ä½ï¼Œå³ä½¿æ‚¨çš„智能åˆçº¦ä»£ç æ²¡æœ‰é”™è¯¯ï¼Œ +编译器或平å°æœ¬èº«ä¹Ÿå¯èƒ½æœ‰ä¸€ä¸ªé”™è¯¯ã€‚ +编译器的一些公开的,与安全有关的错误列表å¯ä»¥ +在 :ref:`已知错误列表 ` 中找到,它也是机器å¯è¯»çš„。 +请注æ„,有一个涵盖 Solidity 编译器的代ç ç”Ÿæˆå™¨çš„ +`错误èµé‡‘计划 `_。 -As always, with open-source documentation, -please help us extend this section (especially, some examples would not hurt)! +åƒå¾€å¸¸ä¸€æ ·ï¼Œå¯¹äºŽå¼€æºæ–‡æ¡£ï¼Œ +请帮助我们扩展这部分内容(尤其是,一些例å­ä¸ä¼šæœ‰ä»€ä¹ˆå½±å“ï¼‰ï¼ -NOTE: In addition to the list below, you can find more security recommendations and best practices -`in Guy Lando's knowledge list `_ and -`the Consensys GitHub repo `_. +注æ„:除了下é¢çš„列表,您也å¯ä»¥åœ¨ +`Guy Lando 的知识列表 `_ +å’Œ `Consensys GitHub 代ç ä»“库 `_ +中找到更多的安全建议和最佳实践。 ******** -Pitfalls +陷阱 ******** -Private Information and Randomness +éšç§ä¿¡æ¯å’Œéšæœºæ€§ ================================== -Everything you use in a smart contract is publicly visible, -even local variables and state variables marked ``private``. +您在智能åˆçº¦ä¸­ä½¿ç”¨çš„所有东西都是公开å¯è§çš„, +å³ä½¿æ˜¯æ ‡è®°ä¸º ``private`` 的局部å˜é‡å’ŒçŠ¶æ€å˜é‡ã€‚ -Using random numbers in smart contracts is quite tricky if you do not want block builders to be able to cheat. +如果你ä¸å¸Œæœ›åŒºå—构造者能够作弊,在智能åˆçº¦ä¸­ä½¿ç”¨éšæœºæ•°æ˜¯ç›¸å½“棘手的。 -Reentrancy -========== +é‡å…¥ +=========== -Any interaction from a contract (A) with another contract (B) -and any transfer of Ether hands over control to that contract (B). -This makes it possible for B to call back into A before this interaction is completed. -To give an example, the following code contains a bug (it is just a snippet and not a complete contract): +一个åˆçº¦ï¼ˆA)与å¦ä¸€ä¸ªåˆçº¦ï¼ˆB)的任何交互 +和任何以太å¸çš„转移都会将控制æƒäº¤ç»™è¯¥åˆçº¦ï¼ˆB)。 +这使得 B 有å¯èƒ½åœ¨è¿™ä¸ªäº¤äº’完æˆä¹‹å‰å›žè°ƒå›ž A。 +举个例å­ï¼Œä¸‹é¢çš„代ç åŒ…å«äº†ä¸€ä¸ªé”™è¯¯ï¼ˆè¿™åªæ˜¯ä¸€ä¸ªç‰‡æ®µï¼Œè€Œä¸æ˜¯ä¸€ä¸ªå®Œæ•´çš„åˆçº¦ï¼‰ï¼š .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.6.0 <0.9.0; - // THIS CONTRACT CONTAINS A BUG - DO NOT USE + // æ­¤åˆçº¦åŒ…å«ä¸€ä¸ªé”™è¯¯ - 请勿使用 contract Fund { - /// @dev Mapping of ether shares of the contract. + /// @dev åˆçº¦çš„以太å¸ä»½é¢çš„映射。 mapping(address => uint) shares; - /// Withdraw your share. + /// æå–您的份é¢ã€‚ function withdraw() public { if (payable(msg.sender).send(shares[msg.sender])) shares[msg.sender] = 0; } } -The problem is not too serious here because of the limited gas as part of ``send``, -but it still exposes a weakness: -Ether transfer can always include code execution, -so the recipient could be a contract that calls back into ``withdraw``. -This would let it get multiple refunds and, basically, retrieve all the Ether in the contract. -In particular, the following contract will allow an attacker to refund multiple times -as it uses ``call`` which forwards all remaining gas by default: +这里的问题ä¸æ˜¯å¤ªä¸¥é‡ï¼Œå› ä¸ºä½œä¸º ``send`` 的一部分,gas 有é™ï¼Œ +但它ä»ç„¶æš´éœ²äº†ä¸€ä¸ªå¼±ç‚¹: +以太å¸çš„转移总是å¯ä»¥åŒ…括代ç çš„执行, +所以接收者å¯ä»¥æ˜¯ä¸€ä¸ªå›žè°ƒåˆ° ``withdraw`` çš„åˆçº¦ã€‚ +这将让它获得多次退款,并基本上å–回åˆçº¦ä¸­çš„所有以太。 +特别的是,下é¢çš„åˆçº¦å°†å…许攻击者多次退款, +因为它使用了 ``call``,它会默认转å‘所有剩余 gas。 .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.6.2 <0.9.0; - // THIS CONTRACT CONTAINS A BUG - DO NOT USE + //æ­¤åˆçº¦åŒ…å«ä¸€ä¸ªé”™è¯¯ - 请勿使用 contract Fund { - /// @dev Mapping of ether shares of the contract. + /// @dev åˆçº¦çš„以太å¸ä»½é¢çš„映射。 mapping(address => uint) shares; - /// Withdraw your share. + /// æå–您的份é¢ã€‚ function withdraw() public { (bool success,) = msg.sender.call{value: shares[msg.sender]}(""); if (success) @@ -95,7 +95,7 @@ as it uses ``call`` which forwards all remaining gas by default: } } -To avoid reentrancy, you can use the Checks-Effects-Interactions pattern as demonstrated below: +为了é¿å…é‡å…¥ï¼Œæ‚¨å¯ä»¥ä½¿ç”¨å¦‚下所示的 检查-生效-交互(Checks-Effects-Interactions)模å¼ï¼š .. code-block:: solidity @@ -103,9 +103,9 @@ To avoid reentrancy, you can use the Checks-Effects-Interactions pattern as demo pragma solidity >=0.6.0 <0.9.0; contract Fund { - /// @dev Mapping of ether shares of the contract. + /// @dev åˆçº¦çš„以太å¸ä»½é¢çš„映射。 mapping(address => uint) shares; - /// Withdraw your share. + /// æå–您的份é¢ã€‚ function withdraw() public { uint share = shares[msg.sender]; shares[msg.sender] = 0; @@ -113,103 +113,96 @@ To avoid reentrancy, you can use the Checks-Effects-Interactions pattern as demo } } -The Checks-Effects-Interactions pattern ensures that all code paths through a contract -complete all required checks of the supplied parameters before modifying the contract's state (Checks); -only then it makes any changes to the state (Effects); -it may make calls to functions in other contracts -*after* all planned state changes have been written to storage (Interactions). -This is a common foolproof way to prevent *reentrancy attacks*, -where an externally called malicious contract can double-spend an allowance, -double-withdraw a balance, among other things, -by using logic that calls back into the original contract before it has finalized its transaction. - -Note that reentrancy is not only an effect of Ether transfer -but of any function call on another contract. -Furthermore, you also have to take multi-contract situations into account. -A called contract could modify the state of another contract you depend on. - -Gas Limit and Loops +检查-生效-交互模å¼ç¡®ä¿æ‰€æœ‰é€šè¿‡åˆçº¦çš„代ç è·¯å¾„ +在修改åˆçº¦çš„状æ€ï¼ˆæ£€æŸ¥ï¼‰ä¹‹å‰å®Œæˆå¯¹æ‰€æ供的å‚数的所有必è¦æ£€æŸ¥ï¼› +åªæœ‰è¿™æ ·å®ƒæ‰ä¼šå¯¹çŠ¶æ€è¿›è¡Œä»»ä½•æ”¹å˜ï¼ˆç”Ÿæ•ˆï¼‰ï¼› +*之åŽ* 所有计划的状æ€æ”¹å˜è¢«å†™å…¥å­˜å‚¨ï¼ˆäº¤äº’)。 +这是一ç§å¸¸è§çš„防止 *é‡å…¥æ€§æ”»å‡»* 的万无一失的方法, +在这ç§æƒ…况下,外部调用的æ¶æ„åˆçº¦èƒ½å¤Ÿ +通过使用在原始åˆçº¦æœ€ç»ˆå®Œæˆäº¤æ˜“之å‰å›žè°ƒåŽŸå§‹åˆçº¦çš„逻辑 +æ¥é‡å¤èŠ±è´¹æŽˆæƒé¢åº¦ï¼Œé‡å¤æå–ä½™é¢ï¼Œä»¥åŠå…¶ä»–事情。 + +请注æ„,é‡å…¥ä¸ä»…是对以太å¸è½¬ç§»çš„å½±å“, +也是对å¦ä¸€ä¸ªåˆçº¦çš„任何函数调用的影å“。 +此外,您还必须考虑到多åˆçº¦çš„情况。 +一个被调用的åˆçº¦å¯ä»¥ä¿®æ”¹æ‚¨æ‰€ä¾èµ–çš„å¦ä¸€ä¸ªåˆçº¦çš„状æ€ã€‚ + +gas é™åˆ¶å’Œå¾ªçŽ¯ =================== -Loops that do not have a fixed number of iterations, for example, -loops that depend on storage values, have to be used carefully: -Due to the block gas limit, transactions can only consume a certain amount of gas. -Either explicitly or just due to normal operation, -the number of iterations in a loop can grow beyond the block gas limit -which can cause the complete contract to be stalled at a certain point. -This may not apply to ``view`` functions that are only executed to read data from the blockchain. -Still, such functions may be called by other contracts as part of on-chain operations and stall those. -Please be explicit about such cases in the documentation of your contracts. - -Sending and Receiving Ether +对于没有固定迭代次数的循环,例如, +ä¾èµ–于存储值的循环,必须谨慎使用: +ç”±äºŽå— gas çš„é™åˆ¶ï¼Œäº‹åŠ¡åªèƒ½æ¶ˆè€—一定é‡çš„ gas。 +无论是明确的还是仅仅由于正常的æ“作, +循环中的迭代次数å¯ä»¥å¢žé•¿åˆ°è¶…è¿‡å— gas é™åˆ¶ï¼Œ +è¿™å¯èƒ½å¯¼è‡´å®Œæ•´çš„åˆçº¦åœ¨æŸä¸€ç‚¹ä¸Šåœæ»žã€‚ +è¿™å¯èƒ½ä¸é€‚用于åªä¸ºä»ŽåŒºå—链上读å–æ•°æ®è€Œæ‰§è¡Œçš„ ``view`` 函数。 +但是,这样的函数å¯èƒ½ä¼šè¢«å…¶ä»–åˆçº¦è°ƒç”¨ï¼Œä½œä¸ºé“¾ä¸Šæ“作的一部分,并使其åœæ»žã€‚ +请在您的åˆçº¦æ–‡æ¡£ä¸­æ˜Žç¡®è¯´æ˜Žè¿™ç§æƒ…况。 + +å‘é€å’ŒæŽ¥æ”¶ä»¥å¤ªå¸ =========================== -- Neither contracts nor "external accounts" are currently able to prevent someone from sending them Ether. - Contracts can react on and reject a regular transfer, but there are ways to move Ether without creating a message call. - One way is to simply "mine to" the contract address and the second way is using ``selfdestruct(x)``. - -- If a contract receives Ether (without a function being called), either the :ref:`receive Ether ` - or the :ref:`fallback ` function is executed. - If it does not have a ``receive`` nor a ``fallback`` function, the Ether will be rejected (by throwing an exception). - During the execution of one of these functions, the contract can only rely on the "gas stipend" it is passed (2300 gas) - being available to it at that time. - This stipend is not enough to modify storage (do not take this for granted though, the stipend might change with future hard forks). - To be sure that your contract can receive Ether in that way, check the gas requirements of the receive and fallback functions - (for example in the "details" section in Remix). - -- There is a way to forward more gas to the receiving contract using ``addr.call{value: x}("")``. - This is essentially the same as ``addr.transfer(x)``, only that it forwards all remaining gas - and opens up the ability for the recipient to perform more expensive actions - (and it returns a failure code instead of automatically propagating the error). - This might include calling back into the sending contract or other state changes you might not have thought of. - So it allows for great flexibility for honest users but also for malicious actors. - -- Use the most precise units to represent the Wei amount as possible, as you lose any that is rounded due to a lack of precision. - -- If you want to send Ether using ``address.transfer``, there are certain details to be aware of: - - 1. If the recipient is a contract, it causes its receive or fallback function - to be executed which can, in turn, call back the sending contract. - 2. Sending Ether can fail due to the call depth going above 1024. Since the - caller is in total control of the call depth, they can force the - transfer to fail; take this possibility into account or use ``send`` and - make sure to always check its return value. Better yet, write your - contract using a pattern where the recipient can withdraw Ether instead. - 3. Sending Ether can also fail because the execution of the recipient - contract requires more than the allotted amount of gas (explicitly by - using :ref:`require `, :ref:`assert `, - :ref:`revert ` or because the - operation is too expensive) - it "runs out of gas" (OOG). If you - use ``transfer`` or ``send`` with a return value check, this might - provide a means for the recipient to block progress in the sending - contract. Again, the best practice here is to use a :ref:`"withdraw" - pattern instead of a "send" pattern `. - -Call Stack Depth +- 无论是åˆçº¦è¿˜æ˜¯ “外部账户â€ï¼Œç›®å‰éƒ½æ— æ³•é˜»æ­¢æœ‰äººå‘他们å‘é€ä»¥å¤ªå¸ã€‚ + åˆçº¦å¯ä»¥å¯¹æ™®é€šçš„转账åšå‡ºå应并拒ç»ï¼Œä½†æœ‰ä¸€äº›æ–¹æ³•å¯ä»¥åœ¨ä¸åˆ›å»ºæ¶ˆæ¯è°ƒç”¨çš„情况下转移以太å¸ã€‚ + 一ç§æ–¹æ³•æ˜¯ç®€å•åœ°å‘åˆçº¦åœ°å€â€œæŒ–矿â€ï¼Œç¬¬äºŒç§æ–¹æ³•æ˜¯ä½¿ç”¨ ``selfdestruct(x)``。 + +- 如果一个åˆçº¦æ”¶åˆ°äº†ä»¥å¤ªï¼ˆæ²¡æœ‰å‡½æ•°è¢«è°ƒç”¨ï¼‰ï¼Œè¦ä¹ˆæ˜¯æ‰§è¡Œ :ref:`receive 方法 `, + è¦ä¹ˆæ‰§è¡Œ :ref:`fallback ` 函数。 + 如果它没有 ``receive`` 也没有 ``fallback`` 函数, + 那么该以太将被拒ç»ï¼ˆæŠ›å‡ºä¸€ä¸ªå¼‚常)。 + 在这些函数的执行过程中,åˆçº¦åªèƒ½ä¾é æ­¤æ—¶å®ƒæ‰€ä¼ é€’çš„ “gas津贴â€ï¼ˆ2300 gas)å¯ç”¨ã€‚ + 但这个津贴ä¸è¶³ä»¥ä¿®æ”¹å­˜å‚¨ï¼ˆä½†ä¸è¦è®¤ä¸ºè¿™æ˜¯ç†æ‰€å½“然的,这个津贴å¯èƒ½ä¼šéšç€æœªæ¥çš„硬分å‰è€Œæ”¹å˜ï¼‰ã€‚ + 为了确ä¿æ‚¨çš„åˆçº¦èƒ½å¤Ÿä»¥è¿™ç§æ–¹å¼æŽ¥æ”¶ä»¥å¤ªï¼Œè¯·æ£€æŸ¥ receive å’Œ fallback 函数的 gas è¦æ±‚ + (在 Remix 的“详细â€ç« èŠ‚会举例说明)。 + +- 有一ç§æ–¹æ³•å¯ä»¥ä½¿ç”¨ ``addr.call{value: x}("")`` 将更多的 gas 转å‘给接收åˆçº¦ã€‚ + 这与 ``addr.transfer(x)`` 本质上是一样的,åªæ˜¯å®ƒè½¬å‘了所有剩余的 gas, + 并为接收方æ供了执行更昂贵的æ“作的能力 + (而且它返回一个失败代ç ï¼Œè€Œä¸æ˜¯è‡ªåŠ¨ä¼ æ’­é”™è¯¯ï¼‰ã€‚ + è¿™å¯èƒ½åŒ…括回调到å‘é€åˆçº¦æˆ–其他您å¯èƒ½æ²¡æœ‰æƒ³åˆ°çš„状æ€å˜åŒ–。 + 因此,这ç§æ–¹æ³•æ— è®ºæ˜¯ç»™è¯šå®žç”¨æˆ·è¿˜æ˜¯æ¶æ„行为者都æ供了æžå¤§çš„çµæ´»æ€§ã€‚ + +- å°½å¯èƒ½ä½¿ç”¨æœ€ç²¾ç¡®çš„å•ä½æ¥è¡¨ç¤º wei çš„æ•°é‡ï¼Œå› ä¸ºæ‚¨ä¼šå› ä¸ºç¼ºä¹ç²¾ç¡®æ€§è€Œå¤±åŽ»ä»»ä½•å››èˆäº”入的结果。 + +- 如果您想用 ``address.transfer`` æ¥å‘é€ä»¥å¤ªï¼Œæœ‰ä¸€äº›ç»†èŠ‚需è¦æ³¨æ„: + + 1. 如果接收者是一个åˆçº¦ï¼Œå®ƒä¼šå¯¼è‡´å…¶ receive 或 fallback 函数被执行, + 而该函数åˆå¯ä»¥å›žè°ƒå‘é€ä»¥å¤ªçš„åˆçº¦ã€‚ + 2. å‘é€ä»¥å¤ªå¯èƒ½ç”±äºŽè°ƒç”¨æ·±åº¦è¶…过1024而失败。由于调用者完全控制ç€è°ƒç”¨æ·±åº¦ï¼Œä»–们å¯ä»¥è¿«ä½¿ä¼ è¾“失败; + 考虑到这ç§å¯èƒ½æ€§ï¼Œæˆ–者使用 ``send``,并确ä¿æ€»æ˜¯æ£€æŸ¥å…¶è¿”回值。 + 更好的办法是,使用接收者å¯ä»¥æå–以太å¸çš„模å¼æ¥ç¼–写您的åˆçº¦ã€‚ + 3. å‘é€ä»¥å¤ªä¹Ÿå¯èƒ½å¤±è´¥ï¼Œå› ä¸ºæŽ¥æ”¶åˆçº¦çš„执行需è¦è¶…过分é…çš„ gas 值 + (确切地说,是使用了 :ref:`require `, :ref:`assert `, + :ref:`revert ` 或者因为æ“作太昂贵)- 它 “耗尽了 gasâ€ï¼ˆOOG)。 + 如果您使用 ``transfer`` 或 ``send``,并带有返回值检查,这å¯èƒ½ä¸ºæŽ¥æ”¶è€…æ供一ç§æ‰‹æ®µæ¥é˜»æ­¢å‘é€åˆçº¦çš„进展。 + åŒæ ·ï¼Œè¿™é‡Œçš„最佳åšæ³•æ˜¯ä½¿ç”¨ :ref:`"æ款" 模å¼è€Œä¸æ˜¯ "å‘é€"æ¨¡å¼ `。 + +调用栈深度 ================ -External function calls can fail at any time -because they exceed the maximum call stack size limit of 1024. -In such situations, Solidity throws an exception. -Malicious actors might be able to force the call stack to a high value -before they interact with your contract. -Note that, since `Tangerine Whistle `_ hardfork, -the `63/64 rule `_ makes call stack depth attack impractical. -Also note that the call stack and the expression stack are unrelated, -even though both have a size limit of 1024 stack slots. - -Note that ``.send()`` does **not** throw an exception if the call stack is depleted -but rather returns ``false`` in that case. -The low-level functions ``.call()``, ``.delegatecall()`` and ``.staticcall()`` behave in the same way. - -Authorized Proxies +外部函数调用éšæ—¶éƒ½å¯èƒ½å¤±è´¥ï¼Œ +因为它们超过了最大调用堆栈大å°1024çš„é™åˆ¶ã€‚ +在这ç§æƒ…况下,Solidity 会抛出一个异常。 +æ¶æ„的行为者å¯èƒ½ä¼šåœ¨ä¸Žæ‚¨çš„åˆçº¦äº¤äº’之å‰ï¼Œ +将调用堆栈逼到一个高值。 +请注æ„,由于 `æ¡”å­å“¨å­ï¼ˆTangerine Whistle) `_ 硬分å‰ï¼Œ +`63/64规则 `_ 使得调用栈深度攻击ä¸åˆ‡å®žé™…。 +还è¦æ³¨æ„的是,调用栈和表达å¼æ ˆæ˜¯ä¸ç›¸å…³çš„, +尽管两者都有1024个栈槽的大å°é™åˆ¶ã€‚ + +æ³¨æ„ ``.send()`` 在调用栈被耗尽的情况下 **ä¸ä¼š** 抛出异常, +而是会返回 ``false``。 +低级函数 ``.call()``, ``.delegatecall()`` å’Œ ``.staticcall()`` 也都是这样的。 + +授æƒçš„ä»£ç† ================== -If your contract can act as a proxy, i.e. if it can call arbitrary contracts with user-supplied data, -then the user can essentially assume the identity of the proxy contract. -Even if you have other protective measures in place, it is best to build your contract system such -that the proxy does not have any permissions (not even for itself). -If needed, you can accomplish that using a second proxy: +如果您的åˆçº¦å¯ä»¥ä½œä¸ºä¸€ä¸ªä»£ç†ï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œå¦‚果它å¯ä»¥ç”¨ç”¨æˆ·æ供的数æ®è°ƒç”¨ä»»æ„çš„åˆçº¦ï¼Œ +那么用户基本上å¯ä»¥æ‰¿æ‹…代ç†åˆçº¦çš„身份。 +å³ä½¿æ‚¨æœ‰å…¶ä»–çš„ä¿æŠ¤æŽªæ–½ï¼Œæœ€å¥½æ˜¯å»ºç«‹æ‚¨çš„åˆçº¦ç³»ç»Ÿï¼Œ +使代ç†æ²¡æœ‰ä»»ä½•æƒé™ï¼ˆç”šè‡³å¯¹è‡ªå·±ä¹Ÿæ²¡æœ‰ï¼‰ã€‚ +如果需è¦ï¼Œæ‚¨å¯ä»¥ä½¿ç”¨ç¬¬äºŒä¸ªä»£ç†æ¥å®Œæˆï¼š .. code-block:: solidity @@ -222,11 +215,10 @@ If needed, you can accomplish that using a second proxy: returns (bool, bytes memory) { return proxy.callOther(addr, payload); } - // Other functions and other functionality + // 其他函数和其他功能 } - // This is the full contract, it has no other functionality and - // requires no privileges to work. + // 这是完整的åˆçº¦ï¼Œå®ƒæ²¡æœ‰å…¶ä»–功能,ä¸éœ€è¦ä»»ä½•æƒé™å°±å¯ä»¥å·¥ä½œã€‚ contract PermissionlessProxy { function callOther(address addr, bytes memory payload) public returns (bool, bytes memory) { @@ -237,14 +229,14 @@ If needed, you can accomplish that using a second proxy: tx.origin ========= -Never use ``tx.origin`` for authorization. -Let's say you have a wallet contract like this: +永远ä¸è¦ä½¿ç”¨ ``tx.origin`` åšèº«ä»½è®¤è¯ã€‚ +å‡è®¾æ‚¨æœ‰ä¸€ä¸ªè¿™æ ·çš„钱包åˆçº¦ï¼š .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; - // THIS CONTRACT CONTAINS A BUG - DO NOT USE + // 本åˆçº¦åŒ…å«ä¸€ä¸ªé”™è¯¯ - 请勿使用 contract TxUserWallet { address owner; @@ -253,13 +245,13 @@ Let's say you have a wallet contract like this: } function transferTo(address payable dest, uint amount) public { - // THE BUG IS RIGHT HERE, you must use msg.sender instead of tx.origin + // 错误就在这里,您必须使用 msg.sender 而ä¸æ˜¯ tx.origin。 require(tx.origin == owner); dest.transfer(amount); } } -Now someone tricks you into sending Ether to the address of this attack wallet: +现在有人欺骗您,让您å‘这个攻击钱包的地å€å‘é€ä»¥å¤ªå¸ï¼š .. code-block:: solidity @@ -281,22 +273,21 @@ Now someone tricks you into sending Ether to the address of this attack wallet: } } -If your wallet had checked ``msg.sender`` for authorization, it would get the address of the attack wallet, -instead of the owner's address. -But by checking ``tx.origin``, it gets the original address that kicked off the transaction, -which is still the owner's address. -The attack wallet instantly drains all your funds. +如果您的钱包检查了 ``msg.sender`` 的授æƒï¼Œå®ƒå°†å¾—到攻击钱包的地å€ï¼Œ +而ä¸æ˜¯æ‰€æœ‰è€…地å€ã€‚ +但是通过检查 ``tx.origin``,它得到的是å¯åŠ¨äº¤æ˜“的原始地å€ï¼Œ +è¿™ä»ç„¶æ˜¯æ‰€æœ‰è€…地å€ã€‚ +攻击钱包会立å³è€—尽您的所有资金。 .. _underflow-overflow: -Two's Complement / Underflows / Overflows +äºŒè¿›åˆ¶è¡¥ç  / 下溢 / 上溢 ========================================= -As in many programming languages, Solidity's integer types are not actually integers. -They resemble integers when the values are small, but cannot represent arbitrarily large numbers. +正如在许多编程语言中,Solidity 的整数类型实际上ä¸æ˜¯æ•´æ•°ã€‚ +当数值较å°æ—¶ï¼Œå®ƒä»¬ç±»ä¼¼äºŽæ•´æ•°ï¼Œä½†ä¹Ÿä¸èƒ½è¡¨ç¤ºä»»æ„大的数字。 -The following code causes an overflow because the result of the addition is too large -to be stored in the type ``uint8``: +下é¢çš„代ç ä¼šå¯¼è‡´æº¢å‡ºï¼Œå› ä¸ºåŠ æ³•çš„结果太大,ä¸èƒ½å­˜å‚¨åœ¨ ``uint8`` 类型中: .. code-block:: solidity @@ -304,35 +295,34 @@ to be stored in the type ``uint8``: uint8 y = 1; return x + y; -Solidity has two modes in which it deals with these overflows: Checked and Unchecked or "wrapping" mode. +Solidity 有两ç§æ¨¡å¼æ¥å¤„ç†è¿™äº›æº¢å‡ºã€‚检查和ä¸æ£€æŸ¥æˆ– “包装†模å¼ã€‚ -The default checked mode will detect overflows and cause a failing assertion. You can disable this check -using ``unchecked { ... }``, causing the overflow to be silently ignored. The above code would return -``0`` if wrapped in ``unchecked { ... }``. +默认的检查模å¼å°†æ£€æµ‹åˆ°æº¢å‡ºå¹¶å¯¼è‡´ä¸€ä¸ªå¤±è´¥çš„断言。 +您å¯ä»¥ä½¿ç”¨ ``unchecked { ... }``,使溢出被无声地忽略。 +上é¢çš„代ç å¦‚果用 ``unchecked { ... }`` 包装,将返回 ``0``。 -Even in checked mode, do not assume you are protected from overflow bugs. -In this mode, overflows will always revert. If it is not possible to avoid the -overflow, this can lead to a smart contract being stuck in a certain state. +å³ä½¿åœ¨æ£€æŸ¥æ¨¡å¼ä¸‹ï¼Œä¹Ÿä¸è¦è®¤ä¸ºæ‚¨å—到了ä¿æŠ¤ï¼Œä¸ä¼šå‡ºçŽ°æº¢å‡ºé”™è¯¯ã€‚ +在这ç§æ¨¡å¼ä¸‹ï¼Œæº¢å‡ºæ€»æ˜¯ä¼šè¢«è¿˜åŽŸã€‚如果无法é¿å…溢出,这å¯èƒ½å¯¼è‡´æ™ºèƒ½åˆçº¦è¢«å¡åœ¨æŸä¸ªçŠ¶æ€ã€‚ -In general, read about the limits of two's complement representation, which even has some -more special edge cases for signed numbers. +一般æ¥è¯´ï¼Œè¯·é˜…读关于二进制补ç è¡¨ç¤ºæ³•çš„é™åˆ¶ï¼Œå®ƒç”šè‡³å¯¹æœ‰ç¬¦å·çš„数字有一些更特殊的边缘情况。 -Try to use ``require`` to limit the size of inputs to a reasonable range and use the -:ref:`SMT checker` to find potential overflows. +å°è¯•ä½¿ç”¨ ``require`` 将输入的大å°é™åˆ¶åœ¨ä¸€ä¸ªåˆç†çš„范围内, +并使用 :ref:`SMT 检查器 ` æ¥å‘现潜在的溢出。 .. _clearing-mappings: -Clearing Mappings +清除映射 ================= -The Solidity type ``mapping`` (see :ref:`mapping-types`) is a storage-only key-value data structure -that does not keep track of the keys that were assigned a non-zero value. -Because of that, cleaning a mapping without extra information about the written keys is not possible. -If a ``mapping`` is used as the base type of a dynamic storage array, -deleting or popping the array will have no effect over the ``mapping`` elements. -The same happens, for example, if a ``mapping`` is used as the type of a member field of a ``struct`` -that is the base type of a dynamic storage array. -The ``mapping`` is also ignored in assignments of structs or arrays containing a ``mapping``. +Solidity ``mapping`` 类型(å‚è§ :ref:`mapping-types`)是一个仅有存储空间的键值数æ®ç»“构, +它ä¸è·Ÿè¸ªè¢«åˆ†é…éžé›¶å€¼çš„键。 +正因为如此,清ç†æ˜ å°„æ—¶ä¸å¯èƒ½æœ‰å…³äºŽå†™å…¥é”®çš„é¢å¤–ä¿¡æ¯ã€‚ +如果 ``mapping`` 被用作动æ€å­˜å‚¨æ•°ç»„的基本类型, +删除或弹出数组将ä¸ä¼šå¯¹ ``mapping`` 元素产生影å“。 +例如,如果一个 ``mapping`` 被用作一个 ``struct`` çš„æˆå‘˜å­—段的类型, +而该结构是一个动æ€å­˜å‚¨é˜µåˆ—的基本类型,åŒæ ·çš„情况也会å‘生。 +``mapping`` åœ¨åŒ…å« ``mapping`` 的结构或数组的分é…中也会被忽略。 + .. code-block:: solidity @@ -360,99 +350,106 @@ The ``mapping`` is also ignored in assignments of structs or arrays containing a } } -Consider the example above and the following sequence of calls: ``allocate(10)``, ``writeMap(4, 128, 256)``. -At this point, calling ``readMap(4, 128)`` returns 256. -If we call ``eraseMaps``, the length of the state variable ``array`` is zeroed, -but since its ``mapping`` elements cannot be zeroed, their information stays alive in the contract's storage. -After deleting ``array``, calling ``allocate(5)`` allows us to access ``array[4]`` again, -and calling ``readMap(4, 128)`` returns 256 even without another call to ``writeMap``. +考虑一下上é¢çš„例å­å’Œä¸‹é¢çš„调用åºåˆ—: ``allocate(10)``, ``writeMap(4, 128, 256)``。 +此时,调用 ``readMap(4, 128)`` 返回256。 +如果我们调用 ``eraseMaps``,状æ€å˜é‡ ``array`` 的长度被清零, +但由于它的 ``mapping`` 元素ä¸èƒ½è¢«æ¸…零,它们的信æ¯åœ¨åˆçº¦çš„存储中ä»ç„¶å­˜åœ¨ã€‚ +删除 ``array`` åŽï¼Œè°ƒç”¨ ``allocate(5)`` å…许我们å†æ¬¡è®¿é—® ``array[4]``, +调用 ``readMap(4, 128)`` 则返回256,å³ä½¿æ²¡æœ‰å†æ¬¡è°ƒç”¨ ``writeMap``。 -If your ``mapping`` information must be deleted, consider using a library similar to -`iterable mapping `_, -allowing you to traverse the keys and delete their values in the appropriate ``mapping``. +如果您的 ``mapping`` ä¿¡æ¯å¿…须被删除,å¯ä»¥è€ƒè™‘使用类似于 +`å¯è¿­ä»£çš„映射 `_ 的库, +它å…许您在适当的 ``mapping`` 中é历键并删除其值。 -Minor Details +细æžæœ«èŠ‚ ============= -- Types that do not occupy the full 32 bytes might contain "dirty higher order bits". - This is especially important if you access ``msg.data`` - it poses a malleability risk: - You can craft transactions that call a function ``f(uint8 x)`` - with a raw byte argument of ``0xff000001`` and with ``0x00000001``. - Both are fed to the contract and both will look like the number ``1`` as far as ``x`` is concerned, - but ``msg.data`` will be different, so if you use ``keccak256(msg.data)`` for anything, - you will get different results. +- 没有å æ»¡32字节的类型å¯èƒ½åŒ…å« â€œè„高ä½â€ã€‚ + 这在当您访问 ``msg.data`` 的时候尤为é‡è¦ —— 它带æ¥äº†å»¶å±•æ€§é£Žé™©ï¼š + 您既å¯ä»¥ç”¨åŽŸå§‹å­—节 ``0xff000001``,也å¯ä»¥ç”¨ ``0x00000001`` 作为å‚æ•°æ¥è°ƒç”¨ + 函数 ``f(uint8 x)`` 以构造交易。 + 这两个å‚数都会被正常æ供给åˆçº¦ï¼Œå°± ``x`` 而言,两者看起æ¥éƒ½æ˜¯æ•°å­— ``1``, + 但 ``msg.data`` 将是ä¸åŒçš„,所以如果您无论怎么使用 ``keccak256(msg.data)``, + 您都会得到ä¸åŒçš„结果。 + *************** -Recommendations +推èåšæ³• *************** -Take Warnings Seriously +认真对待警告 ======================= -If the compiler warns you about something, you should change it. -Even if you do not think that this particular warning has security implications, -there might be another issue buried beneath it. -Any compiler warning we issue can be silenced by slight changes to the code. +如果编译器警告您一些事情,您应该改å˜å®ƒã€‚ +å³ä½¿æ‚¨ä¸è®¤ä¸ºè¿™ä¸ªç‰¹å®šçš„警告有安全问题, +但也å¯èƒ½åœ¨å®ƒä¸‹é¢åŸ‹è—ç€å¦ä¸€ä¸ªé—®é¢˜ã€‚ +我们å‘出的任何编译器警告都å¯ä»¥é€šè¿‡å¯¹ä»£ç çš„轻微修改æ¥æ¶ˆé™¤ã€‚ -Always use the latest version of the compiler to be notified about all recently introduced warnings. +始终使用最新版本的编译器,以获知所有最近引入的警告。 -Messages of type ``info``, issued by the compiler, are not dangerous -and simply represent extra suggestions and optional information -that the compiler thinks might be useful to the user. +编译器å‘出的 ``info`` 类型的信æ¯å¹¶ä¸å±é™©ï¼Œ +åªæ˜¯ä»£è¡¨ç¼–译器认为å¯èƒ½å¯¹ç”¨æˆ·æœ‰ç”¨çš„é¢å¤–建议和å¯é€‰ä¿¡æ¯ã€‚ -Restrict the Amount of Ether +é™åˆ¶ä»¥å¤ªå¸çš„æ•°é‡ ============================ -Restrict the amount of Ether (or other tokens) that can be stored in a smart contract. -If your source code, the compiler or the platform has a bug, these funds may be lost. -If you want to limit your loss, limit the amount of Ether. +é™åˆ¶æ™ºèƒ½åˆçº¦ä¸­å¯å­˜å‚¨çš„以太å¸ï¼ˆæˆ–其他代å¸ï¼‰çš„æ•°é‡ã€‚ +如果您的æºä»£ç ï¼Œç¼–译器或平å°æœ‰é”™è¯¯ï¼Œè¿™äº›èµ„金å¯èƒ½ä¼šä¸¢å¤±ã€‚ +如果您想é™åˆ¶æ‚¨çš„æŸå¤±ï¼Œå°±é™åˆ¶ä»¥å¤ªå¸çš„æ•°é‡ã€‚ -Keep it Small and Modular +ä¿æŒåˆçº¦ç®€ç»ƒä¸”模å—化 ========================= -Keep your contracts small and easily understandable. -Single out unrelated functionality in other contracts or into libraries. -General recommendations about the source code quality of course apply: -Limit the amount of local variables, the length of functions and so on. -Document your functions so that others can see what your intention was -and whether it is different than what the code does. +ä¿æŒæ‚¨çš„åˆçº¦çŸ­å°è€Œå®¹æ˜“ç†è§£ã€‚ +把ä¸ç›¸å…³çš„功能å•ç‹¬æ”¾åœ¨å…¶ä»–åˆçº¦ä¸­æˆ–放在库åˆçº¦ä¸­ã€‚ +关于æºä»£ç è´¨é‡çš„一般建议当然也适用: +é™åˆ¶å±€éƒ¨å˜é‡çš„æ•°é‡å’Œå‡½æ•°çš„长度,等等。 +给您的函数添加注释,这样别人就å¯ä»¥çœ‹åˆ°æ‚¨çš„æ„图是什么, +并判断它是å¦ä¸Žä»£ç çš„作用ä¸åŒã€‚ -Use the Checks-Effects-Interactions Pattern -=========================================== +使用“检查-生效-交互â€ï¼ˆChecks-Effects-Interactionsï¼‰æ¨¡å¼ +======================================================= -Most functions will first perform some checks and they should be done first -(who called the function, are the arguments in range, did they send enough Ether, -does the person have tokens, etc.). +大多数函数会首先进行一些检查,并且应该首先完æˆè¿™äº›æ£€æŸ¥ +(è°è°ƒç”¨äº†è¿™ä¸ªå‡½æ•°ï¼Œå‚数是å¦åœ¨èŒƒå›´å†…,他们是å¦å‘é€äº†è¶³å¤Ÿçš„以太, +这个人是å¦æœ‰ä»£å¸ï¼Œç­‰ç­‰ï¼‰ã€‚ -As the second step, if all checks passed, effects to the state variables of the current contract should be made. -Interaction with other contracts should be the very last step in any function. +第二步,如果所有的检查都通过了,就应该对当å‰åˆçº¦çš„状æ€å˜é‡è¿›è¡Œå½±å“。 +与其他åˆçº¦çš„交互应该是任何函数的最åŽä¸€æ­¥ã€‚ -Early contracts delayed some effects and waited for external function calls to return in a non-error state. -This is often a serious mistake because of the reentrancy problem explained above. +早期的åˆçº¦å»¶è¿Ÿäº†ä¸€äº›æ•ˆæžœï¼Œç­‰å¾…外部函数调用在éžé”™è¯¯çŠ¶æ€ä¸‹è¿”回。 +这往往是一个严é‡çš„错误,因为上é¢è§£é‡Šäº†é‡å…¥é—®é¢˜ã€‚ -Note that, also, calls to known contracts might in turn cause calls to -unknown contracts, so it is probably better to just always apply this pattern. +请注æ„,对已知åˆçº¦çš„调用也å¯èƒ½å过æ¥å¯¼è‡´å¯¹æœªçŸ¥åˆçº¦çš„调用,因此,最好总是应用这ç§æ¨¡å¼ã€‚ -Include a Fail-Safe Mode -======================== +包å«æ•…éšœ-安全(Fail-Safeï¼‰æ¨¡å¼ +============================== -While making your system fully decentralized will remove any intermediary, -it might be a good idea, especially for new code, to include some kind of fail-safe mechanism: +尽管将系统完全去中心化å¯ä»¥çœåŽ»è®¸å¤šä¸­é—´çŽ¯èŠ‚, +但包å«æŸç§æ•…éšœ-安全模å¼ä»ç„¶æ˜¯å¥½çš„åšæ³•ï¼Œ +尤其是对于新的代ç æ¥è¯´ï¼š -You can add a function in your smart contract that performs some self-checks like "Has any Ether leaked?", -"Is the sum of the tokens equal to the balance of the contract?" or similar things. -Keep in mind that you cannot use too much gas for that, -so help through off-chain computations might be needed there. +您å¯ä»¥åœ¨æ‚¨çš„智能åˆçº¦ä¸­æ·»åŠ ä¸€ä¸ªåŠŸèƒ½ï¼Œæ‰§è¡Œä¸€äº›è‡ªæˆ‘检查,如 “是å¦æœ‰ä»»ä½•ä»¥å¤ªå¸æ³„æ¼ï¼Ÿâ€ï¼Œ +“代å¸çš„总和是å¦ç­‰äºŽåˆçº¦çš„ä½™é¢ï¼Ÿâ€ 或类似的事情。 +请记ä½ï¼Œæ‚¨ä¸èƒ½ä¸ºæ­¤ä½¿ç”¨å¤ªå¤šçš„ gas, +所以å¯èƒ½éœ€è¦é€šè¿‡é“¾å¤–计算的帮助。 +<<<<<<< HEAD +如果自我检查失败,åˆçº¦ä¼šè‡ªåŠ¨åˆ‡æ¢åˆ°æŸç§ “故障安全†模å¼ï¼Œ +例如,ç¦ç”¨å¤§éƒ¨åˆ†åŠŸèƒ½ï¼Œ +将控制æƒç§»äº¤ç»™ä¸€ä¸ªå›ºå®šçš„,å¯ä¿¡èµ–的第三方, +或者åªæ˜¯å°†åˆçº¦è½¬æ¢ä¸ºä¸€ä¸ªç®€å•çš„ “退回我的钱†的åˆçº¦ã€‚ +======= If the self-check fails, the contract automatically switches into some kind of "failsafe" mode, which, for example, disables most of the features, hands over control to a fixed and trusted third party or just converts the contract into a simple "give me back my Ether" contract. +>>>>>>> english/develop -Ask for Peer Review +请求åŒè¡Œè¯„审 =================== -The more people examine a piece of code, the more issues are found. -Asking people to review your code also helps as a cross-check to find out -whether your code is easy to understand - -a very important criterion for good smart contracts. +检查一段代ç çš„人越多,å‘现的问题就越多。 +è¦æ±‚其他人审查您的代ç ä¹Ÿæœ‰åŠ©äºŽä½œä¸ºäº¤å‰æ£€æŸ¥ï¼Œ +找出您的代ç æ˜¯å¦å®¹æ˜“ç†è§£ - +这是好的智能åˆçº¦çš„一个éžå¸¸é‡è¦çš„标准。 diff --git a/docs/smtchecker.rst b/docs/smtchecker.rst index f8085b63de6f..bd2d6d1e1e26 100644 --- a/docs/smtchecker.rst +++ b/docs/smtchecker.rst @@ -1,76 +1,65 @@ .. _formal_verification: ################################## -SMTChecker and Formal Verification +SMT检查器和形å¼åŒ–éªŒè¯ ################################## -Using formal verification it is possible to perform an automated mathematical -proof that your source code fulfills a certain formal specification. -The specification is still formal (just as the source code), but usually much -simpler. +使用形å¼åŒ–验è¯ï¼Œæœ‰å¯èƒ½è¿›è¡Œè‡ªåŠ¨æ•°å­¦è¯æ˜Žï¼Œ +è¯æ˜Žæ‚¨çš„æºä»£ç ç¬¦åˆæŸç§å½¢å¼åŒ–规范。 +该规范ä»ç„¶æ˜¯æ­£å¼çš„(就åƒæºä»£ç ä¸€æ ·ï¼‰ï¼Œä½†é€šå¸¸è¦ç®€å•å¾—多。 -Note that formal verification itself can only help you understand the -difference between what you did (the specification) and how you did it -(the actual implementation). You still need to check whether the specification -is what you wanted and that you did not miss any unintended effects of it. +请注æ„,形å¼åŒ–验è¯æœ¬èº«åªèƒ½å¸®åŠ©æ‚¨ç†è§£æ‚¨æ‰€åšçš„(规范)和您如何åšçš„(实际实现)之间的区别。 +您ä»ç„¶éœ€è¦æ£€æŸ¥è§„范是å¦æ˜¯æ‚¨æƒ³è¦çš„,以åŠæ‚¨æ²¡æœ‰é—æ¼ä»»ä½•æ„想ä¸åˆ°çš„效果。 -Solidity implements a formal verification approach based on -`SMT (Satisfiability Modulo Theories) `_ and -`Horn `_ solving. -The SMTChecker module automatically tries to prove that the code satisfies the -specification given by ``require`` and ``assert`` statements. That is, it considers -``require`` statements as assumptions and tries to prove that the conditions -inside ``assert`` statements are always true. If an assertion failure is -found, a counterexample may be given to the user showing how the assertion can -be violated. If no warning is given by the SMTChecker for a property, -it means that the property is safe. +Solidity 实现了基于 `SMT(å¯æ»¡è¶³æ€§æ¨¡åž‹ç†è®ºï¼ˆSatisfiability Modulo Theories) `_ +å’Œ `Horn `_ 解决的形å¼éªŒè¯æ–¹æ³•ã€‚ +SMT检查器模å—自动å°è¯•è¯æ˜Žä»£ç æ»¡è¶³ç”± ``require`` å’Œ ``assert`` 语å¥ç»™å‡ºçš„规范。 +也就是说,它把 ``require`` 语å¥è§†ä¸ºå‡è®¾ï¼Œå¹¶è¯•å›¾è¯æ˜Ž ``assert`` 语å¥ä¸­çš„æ¡ä»¶æ€»æ˜¯çœŸçš„。 +如果å‘现断言失败,则å¯ä»¥å‘用户æ供一个å例,说明断言是如何被è¿å的。 +如果 SMT 检查器对æŸä¸€å±žæ€§æ²¡æœ‰ç»™å‡ºè­¦å‘Šï¼Œè¿™æ„味ç€è¯¥å±žæ€§æ˜¯å®‰å…¨çš„。 -The other verification targets that the SMTChecker checks at compile time are: +SMT 检查器在编译时检查的其他验è¯ç›®æ ‡æœ‰ï¼š -- Arithmetic underflow and overflow. -- Division by zero. -- Trivial conditions and unreachable code. -- Popping an empty array. -- Out of bounds index access. -- Insufficient funds for a transfer. +- 算术上的下溢和溢出。 +- 除以0的除法。 +- 无用的æ¡ä»¶å’Œæ— æ³•è®¿é—®çš„代ç ã€‚ +- 弹出一个空数组。 +- 超出界é™çš„索引访问。 +- 转账资金ä¸è¶³ã€‚ -All the targets above are automatically checked by default if all engines are -enabled, except underflow and overflow for Solidity >=0.8.7. +如果所有检查引擎都被å¯ç”¨ï¼Œä¸Šè¿°æ‰€æœ‰ç›®æ ‡éƒ½è¢«é»˜è®¤ä¸ºè‡ªåŠ¨æ£€æŸ¥ï¼Œ +除了 Solidity >=0.8.7 的下溢和溢出。 -The potential warnings that the SMTChecker reports are: +SMT 检查器所报告的潜在警告是: -- `` happens here.``. This means that the SMTChecker proved that a certain property fails. A counterexample may be given, however in complex situations it may also not show a counterexample. This result may also be a false positive in certain cases, when the SMT encoding adds abstractions for Solidity code that is either hard or impossible to express. -- `` might happen here``. This means that the solver could not prove either case within the given timeout. Since the result is unknown, the SMTChecker reports the potential failure for soundness. This may be solved by increasing the query timeout, but the problem might also simply be too hard for the engine to solve. +- ``<失败的属性> å‘生在这里``。这æ„å‘³ç€ SMT 检查器è¯æ˜Žäº†æŸä¸€å±žæ€§å¤±è´¥ã€‚å¯èƒ½ä¼šç»™å‡ºä¸€ä¸ªå例,但是在å¤æ‚的情况下,也å¯èƒ½ä¸ä¼šæ˜¾ç¤ºå例。在æŸäº›æƒ…况下,当 SMT ç¼–ç ä¸º Solidity 代ç æ·»åŠ äº†éš¾ä»¥è¡¨è¾¾æˆ–无法表达的抽象时,这个结果也å¯èƒ½æ˜¯ä¸€ä¸ªå‡é˜³æ€§ã€‚ +- ``<失败的属性> å¯èƒ½å‘生在这里``。这æ„味ç€æ±‚解器无法在给定的超时时间内è¯æ˜Žä¸¤ç§æƒ…况。由于结果是未知的,SMT 检查器会报告潜在的å¥å…¨æ€§å¤±è´¥ã€‚è¿™å¯ä»¥é€šè¿‡å¢žåŠ æŸ¥è¯¢è¶…时时间æ¥è§£å†³ï¼Œä½†é—®é¢˜ä¹Ÿå¯èƒ½åªæ˜¯å¯¹å¼•æ“Žæ¥è¯´å¤ªéš¾è§£å†³ã€‚ -To enable the SMTChecker, you must select :ref:`which engine should run`, -where the default is no engine. Selecting the engine enables the SMTChecker on all files. +è¦å¯ç”¨SMT检查器,您必须选择 :ref:`应该è¿è¡Œå“ªä¸€ä¸ªå¼•æ“Ž `, +其中默认的是没有引擎。选择引擎å¯ä»¥åœ¨æ‰€æœ‰æ–‡ä»¶ä¸Šå¯ç”¨SMT检查器。 .. note:: - Prior to Solidity 0.8.4, the default way to enable the SMTChecker was via - ``pragma experimental SMTChecker;`` and only the contracts containing the - pragma would be analyzed. That pragma has been deprecated, and although it - still enables the SMTChecker for backwards compatibility, it will be removed - in Solidity 0.9.0. Note also that now using the pragma even in a single file - enables the SMTChecker for all files. + 在 Solidity 0.8.4 之å‰ï¼Œå¯ç”¨SMT检查器的默认方å¼æ˜¯é€šè¿‡ ``pragma experimental SMTChecker;`` + 并且åªæœ‰åŒ…å« pragma çš„åˆçº¦æ‰ä¼šè¢«åˆ†æžã€‚该 pragma 已被弃用, + 尽管它ä»èƒ½ä½¿SMT检查器å‘åŽå…¼å®¹ï¼Œä½†å®ƒå°†åœ¨ Solidity 0.9.0 中被移除。 + 还è¦æ³¨æ„的是,现在å³ä½¿åœ¨ä¸€ä¸ªæ–‡ä»¶ä¸­ä½¿ç”¨ pragma,也会对所有文件å¯ç”¨SMT检查器。 .. note:: - The lack of warnings for a verification target represents an undisputed - mathematical proof of correctness, assuming no bugs in the SMTChecker and - the underlying solver. Keep in mind that these problems are - *very hard* and sometimes *impossible* to solve automatically in the - general case. Therefore, several properties might not be solved or might - lead to false positives for large contracts. Every proven property should - be seen as an important achievement. For advanced users, see :ref:`SMTChecker Tuning ` - to learn a few options that might help proving more complex - properties. + å‡è®¾SMT检查器和底层求解器中没有错误, + 那么验è¯ç›®æ ‡æ²¡æœ‰è­¦å‘Šå°±ä»£è¡¨äº†ä¸€ä¸ªæ— å¯äº‰è®®çš„正确性数学è¯æ˜Žã€‚ + 请记ä½ï¼Œè¿™äº›é—®é¢˜åœ¨ä¸€èˆ¬æƒ…况下是 *很难* 的,有时是 *ä¸å¯èƒ½* 自动解决的。 + 因此,有几个属性å¯èƒ½æ— æ³•è§£å†³ï¼Œæˆ–者å¯èƒ½å¯¼è‡´å¤§åž‹åˆçº¦çš„å‡é˜³æ€§ã€‚ + æ¯ä¸€ä¸ªè¢«è¯æ˜Žçš„属性都应该被看作是一个é‡è¦çš„æˆå°±ã€‚ + 对于高级用户,请å‚阅 :ref:`SMT检查器 调优 ` + æ¥äº†è§£ä¸€äº›å¯èƒ½æœ‰åŠ©äºŽè¯æ˜Žæ›´å¤æ‚属性的选项。 ******** -Tutorial +教程 ******** -Overflow +溢出 ======== .. code-block:: solidity @@ -95,12 +84,20 @@ Overflow } } +<<<<<<< HEAD +上é¢çš„åˆçº¦æ˜¾ç¤ºäº†ä¸€ä¸ªæº¢å‡ºæ£€æŸ¥çš„例å­ã€‚ +对于 Solidity >=0.8.7,SMT检查器默认ä¸æ£€æŸ¥ä¸‹æº¢å’Œæº¢å‡ºï¼Œ +所以我们需è¦ä½¿ç”¨å‘½ä»¤è¡Œé€‰é¡¹ ``--model-checker-targets "underflow,overflow"`` +或者JSON选项 ``settings.modelChecker.targets = ["underflow", "overflow"]``。 +å‚è§ :ref:`本节的目标é…ç½® `。此处,它报告如下: +======= The contract above shows an overflow check example. The SMTChecker does not check underflow and overflow by default for Solidity >=0.8.7, so we need to use the command-line option ``--model-checker-targets "underflow,overflow"`` or the JSON option ``settings.modelChecker.targets = ["underflow", "overflow"]``. See :ref:`this section for targets configuration`. Here, it reports the following: +>>>>>>> english/develop .. code-block:: text @@ -119,8 +116,8 @@ Here, it reports the following: 9 | return x_ + y_; | ^^^^^^^ -If we add ``require`` statements that filter out overflow cases, -the SMTChecker proves that no overflow is reachable (by not reporting warnings): +如果我们添加了过滤掉溢出情况的 ``require`` 语å¥ï¼Œ +SMT检查器就会è¯æ˜Žæ²¡æœ‰æº¢å‡ºæ˜¯å¯ä»¥è¾¾åˆ°çš„(会通过ä¸æŠ¥å‘Šè­¦å‘Šè¡¨çŽ°å‡ºæ¥ï¼‰ã€‚ .. code-block:: solidity @@ -147,18 +144,17 @@ the SMTChecker proves that no overflow is reachable (by not reporting warnings): } -Assert +断言 ====== -An assertion represents an invariant in your code: a property that must be true -*for all transactions, including all input and storage values*, otherwise there is a bug. +断言表示代ç ä¸­çš„一个ä¸å˜é‡ï¼š *对于所有的事务,包括所有的输入和存储值*, +一个属性必须为真,å¦åˆ™å°±ä¼šå‡ºçŽ°é”™è¯¯ã€‚ -The code below defines a function ``f`` that guarantees no overflow. -Function ``inv`` defines the specification that ``f`` is monotonically increasing: -for every possible pair ``(a, b)``, if ``b > a`` then ``f(b) > f(a)``. -Since ``f`` is indeed monotonically increasing, the SMTChecker proves that our -property is correct. You are encouraged to play with the property and the function -definition to see what results come out! +下é¢çš„代ç å®šä¹‰äº†ä¸€ä¸ªä¿è¯æ²¡æœ‰æº¢å‡ºçš„函数 ``f``。 +函数 ``inv`` 定义了 ``f`` 是å•è°ƒé€’增的规范: +对于æ¯ä¸ªå¯èƒ½çš„数值对 ``(a, b)``,如果 ``b > a``,那么 ``f(b) > f(a)``。 +由于 ``f`` 确实是å•è°ƒå¢žé•¿çš„,SMT检查器è¯æ˜Žäº†æˆ‘们的属性是正确的。 +我们鼓励您试试这个属性和函数定义,看看会有什么样的结果! .. code-block:: solidity @@ -177,10 +173,9 @@ definition to see what results come out! } } -We can also add assertions inside loops to verify more complicated properties. -The following code searches for the maximum element of an unrestricted array of -numbers, and asserts the property that the found element must be greater or -equal every element in the array. +我们还å¯ä»¥åœ¨å¾ªçŽ¯ä¸­æ·»åŠ æ–­è¨€ï¼Œä»¥éªŒè¯æ›´å¤šçš„å¤æ‚的属性。 +下é¢çš„代ç æœç´¢ä¸€ä¸ªä¸å—é™åˆ¶çš„数字数组的最大元素, +并断言找到的元素必须大于或等于数组中的æ¯ä¸ªå…ƒç´ çš„属性。 .. code-block:: solidity @@ -201,20 +196,18 @@ equal every element in the array. } } -Note that in this example the SMTChecker will automatically try to prove three properties: +注æ„,在这个例å­ä¸­ï¼ŒSMT检查器将自动å°è¯•è¯æ˜Žä¸‰ä¸ªå±žæ€§ï¼š -1. ``++i`` in the first loop does not overflow. -2. ``++i`` in the second loop does not overflow. -3. The assertion is always true. +1. 第一个循环中的 ``++i`` ä¸ä¼šæº¢å‡ºã€‚ +2. 第二个循环中的 ``++i`` ä¸ä¼šæº¢å‡ºã€‚ +3. 该断言始终是正确的。 .. note:: - The properties involve loops, which makes it *much much* harder than the previous - examples, so beware of loops! + 这些属性涉åŠåˆ°å¾ªçŽ¯ï¼Œè¿™ä½¿å¾—它比å‰é¢çš„ä¾‹å­ *更加* 难了,所以è¦å½“å¿ƒå¾ªçŽ¯çš„é—®é¢˜ï¼ -All the properties are correctly proven safe. Feel free to change the -properties and/or add restrictions on the array to see different results. -For example, changing the code to +所有的属性都被正确è¯æ˜Žæ˜¯å®‰å…¨çš„。 +å¯ä»¥éšæ„改å˜å±žæ€§å’Œ/或在数组上添加é™åˆ¶ï¼Œä»¥çœ‹åˆ°ä¸åŒçš„结果。例如,将代ç æ”¹ä¸º .. code-block:: solidity @@ -236,7 +229,7 @@ For example, changing the code to } } -gives us: +我们得到的结果: .. code-block:: text @@ -254,19 +247,17 @@ gives us: 14 | assert(m > a[i]); -State Properties +状æ€å±žæ€§ ================ -So far the examples only demonstrated the use of the SMTChecker over pure code, -proving properties about specific operations or algorithms. -A common type of properties in smart contracts are properties that involve the -state of the contract. Multiple transactions might be needed to make an assertion -fail for such a property. +到目å‰ä¸ºæ­¢ï¼Œè¿™äº›ä¾‹å­åªå±•ç¤ºäº†SMT检查器在纯代ç ä¸Šçš„使用, +è¯æ˜Žäº†å…³äºŽç‰¹å®šæ“作或算法的属性。 +智能åˆçº¦ä¸­å¸¸è§çš„属性类型是涉åŠåˆçº¦çŠ¶æ€çš„属性。 +对于这样的属性,å¯èƒ½éœ€è¦å¤šä¸ªäº¤æ˜“æ¥ä½¿æ–­è¨€å¤±æ•ˆã€‚ -As an example, consider a 2D grid where both axis have coordinates in the range (-2^128, 2^128 - 1). -Let us place a robot at position (0, 0). The robot can only move diagonally, one step at a time, -and cannot move outside the grid. The robot's state machine can be represented by the smart contract -below. +举一个例å­ï¼Œè€ƒè™‘一个二维网格,其中两个轴的å标都在(-2^128, 2^128 - 1)范围内。 +让我们在ä½ç½®ï¼ˆ0,0)放置一个机器人。该机器人åªèƒ½åœ¨å¯¹è§’线上移动,一次åªèƒ½èµ°ä¸€æ­¥ï¼Œ +ä¸èƒ½åœ¨ç½‘格外移动。机器人的状æ€æœºå¯ä»¥ç”¨ä¸‹é¢çš„智能åˆçº¦æ¥è¡¨ç¤ºã€‚ .. code-block:: solidity @@ -308,16 +299,13 @@ below. } } -Function ``inv`` represents an invariant of the state machine that ``x + y`` -must be even. -The SMTChecker manages to prove that regardless how many commands we give the -robot, even if infinitely many, the invariant can *never* fail. The interested -reader may want to prove that fact manually as well. Hint: this invariant is -inductive. +函数 ``inv`` 代表状æ€æœºçš„一个ä¸å˜é‡ï¼Œå³ ``x + y`` 必须是å¶æ•°ã€‚ +SMT检查器设法è¯æ˜Žï¼Œæ— è®ºæˆ‘们给机器人多少æ¡å‘½ä»¤ï¼Œ +å³ä½¿æ˜¯æ— é™å¤šçš„命令,这个ä¸å˜é‡éƒ½ *ä¸ä¼š* 失败。 +有兴趣的读者å¯èƒ½ä¹Ÿæƒ³æ‰‹åŠ¨è¯æ˜Žè¿™ä¸ªäº‹å®žã€‚ æ示:这个ä¸å˜é‡æ˜¯å½’纳性的。 -We can also trick the SMTChecker into giving us a path to a certain position we -think might be reachable. We can add the property that (2, 4) is *not* -reachable, by adding the following function. +我们也å¯ä»¥æ¬ºéª—SMT检查器,让它给我们æ供一æ¡é€šå¾€æŸä¸ªæˆ‘们认为å¯èƒ½æ˜¯å¯è®¿é—®çš„ä½ç½®çš„路径。 +我们å¯ä»¥é€šè¿‡æ·»åŠ ä»¥ä¸‹å‡½æ•°ï¼Œæ¥å¢žåŠ (2, 4)是 *ä¸* å¯è®¿é—®çš„属性。 .. code-block:: solidity @@ -325,8 +313,8 @@ reachable, by adding the following function. assert(!(x == 2 && y == 4)); } -This property is false, and while proving that the property is false, -the SMTChecker tells us exactly *how* to reach (2, 4): +这个属性是å‡çš„,在è¯æ˜Žè¿™ä¸ªå±žæ€§æ˜¯å‡çš„åŒæ—¶ï¼Œ +SMT检查器准确地告诉我们 *如何* 访问到(2, 4)。 .. code-block:: text @@ -351,22 +339,20 @@ the SMTChecker tells us exactly *how* to reach (2, 4): 35 | assert(!(x == 2 && y == 4)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Note that the path above is not necessarily deterministic, as there are -other paths that could reach (2, 4). The choice of which path is shown -might change depending on the used solver, its version, or just randomly. +请注æ„,上é¢çš„路径ä¸ä¸€å®šæ˜¯ç¡®å®šçš„, +因为还有其他路径å¯ä»¥è®¿é—®ï¼ˆ2,4)。 +选择哪æ¡è·¯å¾„å¯èƒ½ä¼šæ ¹æ®æ‰€ä½¿ç”¨çš„解算器,其使用版本,或者åªæ˜¯éšæœºåœ°æ”¹å˜ã€‚ -External Calls and Reentrancy +外部调用和é‡å…¥ ============================= -Every external call is treated as a call to unknown code by the SMTChecker. -The reasoning behind that is that even if the code of the called contract is -available at compile time, there is no guarantee that the deployed contract -will indeed be the same as the contract where the interface came from at -compile time. +æ¯ä¸ªå¤–部调用都被SMT检查器视为对未知代ç çš„调用。 +这背åŽçš„原因是,å³ä½¿è¢«è°ƒç”¨åˆçº¦çš„代ç åœ¨ç¼–译时是å¯ç”¨çš„, +也ä¸èƒ½ä¿è¯éƒ¨ç½²çš„åˆçº¦ç¡®å®žä¸Žç¼–译时接å£æ‰€åœ¨çš„åˆçº¦ç›¸åŒã€‚ -In some cases, it is possible to automatically infer properties over state -variables that are still true even if the externally called code can do -anything, including reenter the caller contract. +在æŸäº›æƒ…况下,有å¯èƒ½åœ¨çŠ¶æ€å˜é‡ä¸Šè‡ªåŠ¨æŽ¨æ–­å‡ºå±žæ€§ï¼Œ +å³ä½¿å¤–部调用的代ç å¯ä»¥åšä»»ä½•äº‹æƒ…,包括é‡æ–°è¿›å…¥è°ƒç”¨è€…åˆçº¦ï¼Œ +这些属性ä»ç„¶æ˜¯çœŸçš„。 .. code-block:: solidity @@ -406,14 +392,18 @@ anything, including reenter the caller contract. } } -The example above shows a contract that uses a mutex flag to forbid reentrancy. -The solver is able to infer that when ``unknown.run()`` is called, the contract -is already "locked", so it would not be possible to change the value of ``x``, -regardless of what the unknown called code does. +上é¢çš„例å­æ˜¾ç¤ºäº†ä¸€ä¸ªä½¿ç”¨äº’斥标志æ¥ç¦æ­¢é‡å…¥çš„åˆçº¦ã€‚ +解算器能够推断出,当 ``unknown.run()`` 被调用时,åˆçº¦å·²ç»è¢« “é”定â€ï¼Œ +所以无论未知的调用代ç åšä»€ä¹ˆï¼Œéƒ½ä¸å¯èƒ½æ”¹å˜ ``x`` 的值。 +<<<<<<< HEAD +如果我们 “忘记†在函数 ``set`` 上使用 ``mutex`` 修饰符, +SMT检查器就能åˆæˆå¤–部调用代ç çš„行为,从而使断言失败。 +======= If we "forget" to use the ``mutex`` modifier on function ``set``, the SMTChecker is able to synthesize the behavior of the externally called code so that the assertion fails: +>>>>>>> english/develop .. code-block:: text @@ -436,105 +426,97 @@ that the assertion fails: .. _smtchecker_options: ***************************** -SMTChecker Options and Tuning +SMT检查器选项和调试 ***************************** -Timeout +超时 ======= -The SMTChecker uses a hardcoded resource limit (``rlimit``) chosen per solver, -which is not precisely related to time. We chose the ``rlimit`` option as the default -because it gives more determinism guarantees than time inside the solver. +SMT检查器使用了一个硬编ç çš„资æºé™åˆ¶ï¼ˆ ``rlimit`` ), +这个é™åˆ¶æ˜¯æ ¹æ®æ¯ä¸ªæ±‚解器选择的,与时间没有确切的关系。 +我们选择 ``rlimit`` 选项作为默认值,因为它比求解器内部的时间æ供了更多的确定性ä¿è¯ã€‚ -This options translates roughly to "a few seconds timeout" per query. Of course many properties -are very complex and need a lot of time to be solved, where determinism does not matter. -If the SMTChecker does not manage to solve the contract properties with the default ``rlimit``, -a timeout can be given in milliseconds via the CLI option ``--model-checker-timeout