Compare commits
No commits in common. "develop" and "v0.8.12" have entirely different histories.
@ -7,15 +7,15 @@ The docker images are build locally on the developer machine:
|
||||
```sh
|
||||
cd .circleci/docker/
|
||||
|
||||
docker build -t ethereum/solidity-buildpack-deps:ubuntu2204-<revision> -f Dockerfile.ubuntu2204 .
|
||||
docker push ethereum/solidity-buildpack-deps:ubuntu2204-<revision>
|
||||
docker build -t ethereum/solidity-buildpack-deps:ubuntu2004-<revision> -f Dockerfile.ubuntu2004 .
|
||||
docker push ethereum/solidity-buildpack-deps:ubuntu2004-<revision>
|
||||
```
|
||||
|
||||
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 `<image-desc>-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 (`<revision>` 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.
|
||||
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 `<image-desc>-docker-image-rev` (e.g., `ubuntu-2004-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 (`<revision>` 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-<revision>
|
||||
https://hub.docker.com/r/ethereum/solidity-buildpack-deps:ubuntu2004-<revision>
|
||||
|
||||
where the image tag reflects the target OS and revision to build Solidity and run its tests on.
|
||||
|
||||
@ -24,7 +24,7 @@ where the image tag reflects the target OS and revision to build Solidity and ru
|
||||
```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-<revision> /bin/bash
|
||||
docker run -v `pwd`:/src/solidity -ti ethereum/solidity-buildpack-deps:ubuntu2004-<revision> /bin/bash
|
||||
cd /src/solidity
|
||||
<commands_to_test_build_with_new_docker_image>
|
||||
```
|
||||
|
@ -1 +0,0 @@
|
||||
leak:*libcln*
|
@ -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 <http://www.gnu.org/licenses/>
|
||||
#
|
||||
# (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
|
1980
.circleci/config.yml
@ -52,8 +52,7 @@ function validate_checksum {
|
||||
|
||||
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 unlink python
|
||||
brew install boost
|
||||
brew install cmake
|
||||
brew install wget
|
||||
@ -62,11 +61,11 @@ then
|
||||
./scripts/install_obsolete_jsoncpp_1_7_4.sh
|
||||
|
||||
# z3
|
||||
z3_version="4.12.1"
|
||||
z3_version="4.8.14"
|
||||
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
|
||||
validate_checksum "$z3_package" 1341671670e0c4e72da80815128a68975ee90816d50ceaf6bd820f06babe2cfd
|
||||
unzip "$z3_package"
|
||||
rm "$z3_package"
|
||||
cp "${z3_dir}/bin/libz3.a" /usr/local/lib
|
||||
@ -75,11 +74,18 @@ then
|
||||
rm -r "$z3_dir"
|
||||
|
||||
# evmone
|
||||
evmone_version="0.10.0"
|
||||
evmone_version="0.8.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
|
||||
validate_checksum "$evmone_package" e8efef478822f0ed6d0493e89004181e895893f93963152a2a81589acc3a0828
|
||||
tar xzpf "$evmone_package" -C /usr/local
|
||||
rm "$evmone_package"
|
||||
|
||||
# hera
|
||||
hera_version="0.5.0"
|
||||
hera_package="hera-${hera_version}-darwin-x86_64.tar.gz"
|
||||
wget "https://github.com/ewasm/hera/releases/download/v${hera_version}/${hera_package}"
|
||||
validate_checksum "$hera_package" 190050d7ace384ecd79ec1b1f607a9ff40e196b4eec75932958d4814d221d059
|
||||
tar xzpf "$hera_package" -C /usr/local
|
||||
rm "$hera_package"
|
||||
fi
|
||||
|
@ -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 <http://www.gnu.org/licenses/>
|
||||
#
|
||||
# (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
|
@ -1,45 +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
|
||||
'~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,
|
||||
)
|
@ -6,7 +6,7 @@ cd "$PSScriptRoot\.."
|
||||
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
|
||||
.\build\test\Release\soltest.exe --color_output=no --show_progress=yes --logger=JUNIT,error,test_results/result.xml -- --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." }
|
||||
.\build\test\Release\soltest.exe --color_output=no --show_progress=yes --logger=JUNIT,error,test_results/result_opt.xml -- --optimize --no-smt
|
||||
if ( -not $? ) { throw "Optimized soltest run failed." }
|
@ -36,7 +36,6 @@ 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"
|
||||
@ -68,14 +67,14 @@ get_logfile_basename() {
|
||||
# long-running test cases are next to each other.
|
||||
CIRCLE_NODE_INDEX=$(((CIRCLE_NODE_INDEX + 23 * INDEX_SHIFT) % CIRCLE_NODE_TOTAL))
|
||||
|
||||
CPUs=3
|
||||
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"
|
||||
"--logger=JUNIT,error,test_results/$(get_logfile_basename "$run").xml"
|
||||
"${BOOST_TEST_ARGS[@]}"
|
||||
)
|
||||
SOLTEST_ARGS=("--evm-version=$EVM" "${SOLTEST_FLAGS[@]}")
|
||||
@ -92,7 +91,7 @@ do
|
||||
done
|
||||
|
||||
# wait for individual processes to get their exit status
|
||||
for pid in "${PIDs[@]}"
|
||||
for pid in ${PIDs[*]}
|
||||
do
|
||||
wait "$pid"
|
||||
done
|
||||
|
@ -31,8 +31,8 @@ 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=(homestead byzantium constantinople petersburg istanbul berlin london)
|
||||
DEFAULT_EVM=london
|
||||
[[ " ${EVM_VALUES[*]} " =~ $DEFAULT_EVM ]]
|
||||
OPTIMIZE_VALUES=(0 1)
|
||||
|
||||
@ -50,6 +50,9 @@ for OPTIMIZE in "${OPTIMIZE_VALUES[@]}"
|
||||
do
|
||||
for EVM in "${EVM_VALUES[@]}"
|
||||
do
|
||||
# run tests against hera ewasm evmc vm, only if OPTIMIZE == 0 and evm version is byzantium
|
||||
EWASM_ARGS=""
|
||||
[ "${EVM}" = "byzantium" ] && [ "${OPTIMIZE}" = "0" ] && EWASM_ARGS="--ewasm"
|
||||
ENFORCE_GAS_ARGS=""
|
||||
[ "${EVM}" = "${DEFAULT_EVM}" ] && ENFORCE_GAS_ARGS="--enforce-gas-cost"
|
||||
# Run SMTChecker tests only when OPTIMIZE == 0
|
||||
@ -58,11 +61,11 @@ do
|
||||
|
||||
EVM="$EVM" \
|
||||
OPTIMIZE="$OPTIMIZE" \
|
||||
SOLTEST_FLAGS="$SOLTEST_FLAGS $ENFORCE_GAS_ARGS" \
|
||||
SOLTEST_FLAGS="$SOLTEST_FLAGS $ENFORCE_GAS_ARGS $EWASM_ARGS" \
|
||||
BOOST_TEST_ARGS="-t !@nooptions $DISABLE_SMTCHECKER" \
|
||||
INDEX_SHIFT="$INDEX_SHIFT" \
|
||||
"${REPODIR}/.circleci/soltest.sh"
|
||||
|
||||
INDEX_SHIFT=$((INDEX_SHIFT + 1))
|
||||
done
|
||||
done
|
||||
done
|
@ -12,7 +12,7 @@ Language: Cpp
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignEscapedNewlines: Left
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
|
1
.github/CODEOWNERS
vendored
@ -1 +0,0 @@
|
||||
/docs/style-guide.rst @fulldecent
|
7
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,10 +1,5 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Problems, deficiencies, inaccuracies or crashes discovered on Solidity.
|
||||
title: ''
|
||||
labels: 'bug :bug:'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--## Prerequisites
|
||||
@ -36,7 +31,7 @@ assignees: ''
|
||||
|
||||
<!--
|
||||
Please provide a *minimal* source code example to trigger the bug you have found.
|
||||
Please also mention any command-line flags that are necessary for triggering the bug.
|
||||
Please also mention any command line flags that are necessary for triggering the bug.
|
||||
Provide as much information as necessary to reproduce the bug.
|
||||
|
||||
```solidity
|
||||
|
15
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,5 +1,14 @@
|
||||
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.
|
||||
- name: Bug Report
|
||||
url: https://github.com/ethereum/solidity/issues/new?template=bug_report.md&projects=ethereum/solidity/43&labels=bug+%3Abug%3A
|
||||
about: Bug reports about the Solidity Compiler.
|
||||
- name: Documentation Issue
|
||||
url: https://github.com/ethereum/solidity/issues/new?template=documentation_issue.md&projects=ethereum/solidity/43&labels=documentation+%3Abook%3A
|
||||
about: Solidity documentation.
|
||||
- name: Feature Request
|
||||
url: https://github.com/ethereum/solidity/issues/new?template=feature_request.md&projects=ethereum/solidity/43&labels=feature
|
||||
about: Solidity language or infrastructure feature requests.
|
||||
- name: Report a security vulnerability
|
||||
url: https://github.com/ethereum/solidity/security/policy
|
||||
about: Please review our security policy for more details.
|
||||
|
@ -1,10 +1,5 @@
|
||||
---
|
||||
name: Documentation Issue
|
||||
about: Corrections, improvements or requests for new content on Solidity's documentation.
|
||||
title: ''
|
||||
labels: 'documentation :book:'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Page
|
||||
|
8
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,11 +1,5 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Ideas, comments or messages asking for a particular functionality to be added
|
||||
to Solidity.
|
||||
title: ''
|
||||
labels: feature
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--## Prerequisites
|
||||
@ -16,8 +10,6 @@ assignees: ''
|
||||
- [Solidity chat](https://gitter.im/ethereum/solidity)
|
||||
- [Stack Overflow](https://ethereum.stackexchange.com/)
|
||||
- Ensure the issue isn't already reported (check `feature` and `language design` labels).
|
||||
- If you feel uncertain about your feature request, perhaps it's better to open a language design or feedback forum thread via the issue selector, or by going to the forum directly.
|
||||
- [Solidity forum](https://forum.soliditylang.org/)
|
||||
|
||||
*Delete the above section and the instructions in the sections below before submitting*
|
||||
-->
|
||||
|
14
.github/workflows/buildpack-deps.yml
vendored
@ -5,10 +5,9 @@ on:
|
||||
branches: [ develop ]
|
||||
paths:
|
||||
- 'scripts/docker/buildpack-deps/Dockerfile.emscripten'
|
||||
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz'
|
||||
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz'
|
||||
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2004.clang'
|
||||
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2004'
|
||||
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang'
|
||||
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204'
|
||||
|
||||
jobs:
|
||||
buildpack-deps:
|
||||
@ -23,7 +22,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2204.clang, ubuntu2204]
|
||||
image_variant: [emscripten, ubuntu1604.clang.ossfuzz, ubuntu2004.clang, ubuntu2004]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@ -38,9 +37,6 @@ jobs:
|
||||
|
||||
- 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
|
||||
uses: aarlt/comment-on-pr@v1.2.0
|
||||
with:
|
||||
msg: "`${{ env.DOCKER_IMAGE }} ${{ env.DOCKER_REPO_DIGEST }}`."
|
||||
check_for_duplicate_msg: false
|
||||
|
||||
msg: "`${{ env.DOCKER_IMAGE }} ${{ env.DOCKER_REPO_DIGEST }}`."
|
51
.github/workflows/stale.yml
vendored
@ -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
|
37
.github/workflows/welcome-external-pr.yml
vendored
@ -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
|
40
.gitignore
vendored
@ -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
|
||||
|
@ -1,18 +0,0 @@
|
||||
version: 2
|
||||
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
|
||||
sphinx:
|
||||
builder: html
|
||||
configuration: docs/conf.py
|
||||
|
||||
formats:
|
||||
- pdf
|
||||
- epub
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
@ -1,11 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.13.0)
|
||||
|
||||
set(ETH_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake" CACHE PATH "The path to the cmake directory")
|
||||
set(ETH_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake" CACHE PATH "The the path to the cmake directory")
|
||||
list(APPEND CMAKE_MODULE_PATH ${ETH_CMAKE_DIR})
|
||||
|
||||
# Set the build type, if none was specified.
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
if(EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
set(DEFAULT_BUILD_TYPE "RelWithDebInfo")
|
||||
else()
|
||||
set(DEFAULT_BUILD_TYPE "Release")
|
||||
@ -21,7 +21,7 @@ include(EthPolicy)
|
||||
eth_policy()
|
||||
|
||||
# project name and version should be set after cmake_policy CMP0048
|
||||
set(PROJECT_VERSION "0.8.22")
|
||||
set(PROJECT_VERSION "0.8.12")
|
||||
# OSX target needed in order to support std::visit
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14")
|
||||
project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX)
|
||||
@ -35,8 +35,6 @@ endif()
|
||||
option(SOLC_LINK_STATIC "Link solc executable statically on supported platforms" OFF)
|
||||
option(SOLC_STATIC_STDLIBS "Link solc against static versions of libgcc and libstdc++ on supported platforms" OFF)
|
||||
option(STRICT_Z3_VERSION "Use the latest version of Z3" ON)
|
||||
option(PEDANTIC "Enable extra warnings and pedantic build flags. Treat all warnings as errors." ON)
|
||||
option(PROFILE_OPTIMIZER_STEPS "Output performance metrics for the optimiser steps." OFF)
|
||||
|
||||
# Setup cccache.
|
||||
include(EthCcache)
|
||||
@ -50,14 +48,6 @@ include_directories(SYSTEM ${JSONCPP_INCLUDE_DIR})
|
||||
|
||||
find_package(Threads)
|
||||
|
||||
if(NOT PEDANTIC)
|
||||
message(WARNING "-- Pedantic build flags turned off. Warnings will not make compilation fail. This is NOT recommended in development builds.")
|
||||
endif()
|
||||
|
||||
if (PROFILE_OPTIMIZER_STEPS)
|
||||
add_definitions(-DPROFILE_OPTIMIZER_STEPS)
|
||||
endif()
|
||||
|
||||
# Figure out what compiler and system are we using
|
||||
include(EthCompilerSettings)
|
||||
|
||||
@ -66,17 +56,17 @@ include(EthUtils)
|
||||
|
||||
# Create license.h from LICENSE.txt and template
|
||||
# Converting to char array is required due to MSVC's string size limit.
|
||||
file(READ ${PROJECT_SOURCE_DIR}/LICENSE.txt LICENSE_TEXT HEX)
|
||||
file(READ ${CMAKE_SOURCE_DIR}/LICENSE.txt LICENSE_TEXT HEX)
|
||||
string(REGEX MATCHALL ".." LICENSE_TEXT "${LICENSE_TEXT}")
|
||||
string(REGEX REPLACE ";" ",\n\t0x" LICENSE_TEXT "${LICENSE_TEXT}")
|
||||
set(LICENSE_TEXT "0x${LICENSE_TEXT}")
|
||||
|
||||
configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/license.h.in" include/license.h)
|
||||
configure_file("${CMAKE_SOURCE_DIR}/cmake/templates/license.h.in" include/license.h)
|
||||
|
||||
include(EthOptions)
|
||||
configure_project(TESTS)
|
||||
set(LATEST_Z3_VERSION "4.12.1")
|
||||
set(MINIMUM_Z3_VERSION "4.8.16")
|
||||
set(LATEST_Z3_VERSION "4.8.14")
|
||||
set(MINIMUM_Z3_VERSION "4.8.0")
|
||||
find_package(Z3)
|
||||
if (${Z3_FOUND})
|
||||
if (${STRICT_Z3_VERSION})
|
||||
@ -140,7 +130,6 @@ add_subdirectory(libevmasm)
|
||||
add_subdirectory(libyul)
|
||||
add_subdirectory(libsolidity)
|
||||
add_subdirectory(libsolc)
|
||||
add_subdirectory(libstdlib)
|
||||
add_subdirectory(tools)
|
||||
|
||||
if (NOT EMSCRIPTEN)
|
||||
|
@ -55,8 +55,10 @@ 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.
|
||||
reported by contacting the project team at chris@ethereum.org which only goes to
|
||||
Christian Reitwiessner or axic@ethereum.org which only goes to Alex Beregszaszi.
|
||||
To report an issue involving either of them please email Hudson Jameson at
|
||||
hudson@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.
|
||||
|
@ -51,11 +51,10 @@ To set indentation and tab width settings uniformly, the repository contains an
|
||||
## 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.
|
||||
2. Use `using namespace std;` in cpp files, but avoid importing namespaces from boost and others.
|
||||
3. All symbols should be declared in a namespace except for final applications.
|
||||
4. Use anonymous namespaces for helpers whose scope is a cpp file only.
|
||||
5. Preprocessor symbols should be prefixed with the namespace in all-caps and an underscore.
|
||||
|
||||
Only in the header:
|
||||
```cpp
|
||||
@ -66,6 +65,16 @@ std::tuple<float, float> meanAndSigma(std::vector<float> const& _v);
|
||||
}
|
||||
```
|
||||
|
||||
Only in the cpp file:
|
||||
```cpp
|
||||
#include <cassert>
|
||||
using namespace std;
|
||||
tuple<float, float> myNamespace::meanAndSigma(vector<float> const& _v)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## 2. Preprocessor
|
||||
|
||||
1. File comment is always at top, and includes:
|
||||
@ -107,7 +116,7 @@ Use `solAssert` and `solUnimplementedAssert` generously to check assumptions tha
|
||||
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.
|
||||
4. Favour declarations close to use; don't 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.
|
||||
@ -170,7 +179,7 @@ for (map<ComplexTypeOne, ComplexTypeTwo>::iterator i = l.begin(); i != l.end();
|
||||
|
||||
## 9. Naming
|
||||
|
||||
1. Avoid unpronounceable names.
|
||||
1. Avoid unpronouncable 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:
|
||||
|
281
Changelog.md
@ -1,284 +1,3 @@
|
||||
### 0.8.22 (unreleased)
|
||||
|
||||
Language Features:
|
||||
* Allow defining events at file level.
|
||||
|
||||
|
||||
Compiler Features:
|
||||
* Parser: Remove the experimental error recovery mode (``--error-recovery`` / ``settings.parserErrorRecovery``).
|
||||
* 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.
|
||||
|
||||
|
||||
### 0.8.21 (2023-07-19)
|
||||
|
||||
Important Bugfixes:
|
||||
* Code Generator: Always generate code for the expression in ``<expression>.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:
|
||||
|
10
README.md
@ -27,11 +27,11 @@ For a good overview and starting point, please check out the official [Solidity
|
||||
|
||||
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,
|
||||
network where nobody has special authority over the execution, and thus they allow 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
|
||||
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).
|
||||
|
||||
@ -66,7 +66,7 @@ browser-based IDE. Here are some example contracts:
|
||||
|
||||
## Documentation
|
||||
|
||||
The Solidity documentation is hosted using [Read the Docs](https://docs.soliditylang.org).
|
||||
The Solidity documentation is hosted at [Read the docs](https://docs.soliditylang.org).
|
||||
|
||||
## Development
|
||||
|
||||
@ -79,8 +79,8 @@ 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).
|
||||
|
@ -1,97 +1,67 @@
|
||||
## 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).
|
||||
- [ ] Lauchpad (Ubuntu One) account
|
||||
- [ ] gnupg key (has to be version 1, gpg2 won't work) for `your-name@ethereum.org` created and uploaded
|
||||
- [ ] Readthedocs account, access to the Solidity project
|
||||
- [ ] Write access to https://github.com/ethereum/homebrew-ethereum
|
||||
|
||||
### 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.
|
||||
### Documentation check
|
||||
- [ ] 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.
|
||||
|
||||
### 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).
|
||||
- [ ] Create a post on https://github.com/ethereum/solidity-blog and explain some of the new features or concepts.
|
||||
|
||||
### 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.
|
||||
- [ ] Sort the changelog entries alphabetically and correct any errors you notice.
|
||||
- [ ] Create a commit on a new branch that updates the ``Changelog`` to include a release date.
|
||||
- [ ] Run ``./scripts/tests.sh`` to update the bug list.
|
||||
- [ ] Create a pull request and wait for the tests, merge it.
|
||||
|
||||
### 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<previous version>`` to get initial list of names.
|
||||
Remove different variants of the same name manually before using the output.
|
||||
- [ ] Create Github release page: https://github.com/ethereum/solidity/releases/new
|
||||
- [ ] On the release page, select the ``develop`` branch as new target and set tag to the new version (e.g. `v0.8.5`) (make sure you only `SAVE DRAFT` instead of `PUBLISH RELEASE` before the actual release)
|
||||
- [ ] Thank voluntary contributors in the Github release page (use ``git shortlog -s -n -e v0.5.3..origin/develop``).
|
||||
- [ ] Check that all tests on the latest commit in ``develop`` are green.
|
||||
- [ ] Click the ``Publish release`` button on the release page, creating the tag.
|
||||
- [ ] 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.
|
||||
### Download Binaries
|
||||
- [ ] Take the ``solc.exe`` binary from the ``b_win_release`` run of the released commit in circle-ci and add it to the release page as ``solc-windows.exe``.
|
||||
- [ ] Take the ``solc`` binary from the ``b_osx`` run of the released commit in circle-ci and add it to the release page as ``solc-macos``.
|
||||
- [ ] Take the ``solc`` binary from the ``b_ubu_static`` run of the released commit in circle-ci and add it to the release page as ``solc-static-linux``.
|
||||
- [ ] Take the ``soljson.js`` binary from the ``b_ems`` run of the released commit in circle-ci and add it to the release page as ``soljson.js``.
|
||||
|
||||
### Update [solc-bin](https://github.com/ethereum/solc-bin/)
|
||||
- [ ] Copy files to solc-bin:
|
||||
```bash
|
||||
VERSION=0.8.4
|
||||
COMMIT="c7e474f2"
|
||||
SOLC_BIN="/home/me/solc-bin"
|
||||
chmod +x solc-static-linux solc-macos
|
||||
cp soljson.js $SOLC_BIN/bin/soljson-v$VERSION+commit.$COMMIT.js
|
||||
cp solc-static-linux $SOLC_BIN/linux-amd64/solc-linux-amd64-v$VERSION+commit.$COMMIT
|
||||
cp solc-macos $SOLC_BIN/macosx-amd64/solc-macosx-amd64-v$VERSION+commit.$COMMIT
|
||||
cp solc-windows.exe $SOLC_BIN/windows-amd64/solc-windows-amd64-v$VERSION+commit.$COMMIT.exe
|
||||
- [ ] 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 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).
|
||||
- [ ] Update the version and the hash (``sha256sum solidity_$VERSION.tar.gz``) in https://github.com/Homebrew/homebrew-core/blob/master/Formula/solidity.rb
|
||||
- [ ] Update the version and the hash (``sha256sum solidity_$VERSION.tar.gz``) in https://github.com/ethereum/homebrew-ethereum/blob/master/solidity.rb
|
||||
|
||||
### Docker
|
||||
- [ ] Run ``./scripts/docker_deploy_manual.sh v$VERSION``.
|
||||
- [ ] 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``.
|
||||
- [ ] Make sure the ``ethereum/cpp-build-deps`` PPA repository contains libz3-static-dev builds for all current versions of ubuntu. If not run ``scripts/deps-ppa/static-z3.sh`` (after changing email address and key id and adding the missing ubuntu version) and wait for the builds to succeed before continuing.
|
||||
- [ ] Change ``scripts/release_ppa.sh`` to match your key's email and key id; double-check that ``DISTRIBUTIONS`` contains the most recent versions.
|
||||
- [ ] Run ``scripts/release_ppa.sh v$VERSION`` to create the PPA release (you need the relevant openssl key).
|
||||
- [ ] Wait for the ``~ethereum/ubuntu/ethereum-static`` PPA build to be finished and published for *all platforms*. SERIOUSLY: DO NOT PROCEED EARLIER!!! *After* the static builds are *published*, copy the static package to the ``~ethereum/ubuntu/ethereum`` PPA for the destination series ``Trusty``, ``Xenial`` and ``Bionic`` while selecting ``Copy existing binaries``.
|
||||
|
||||
### Documentation
|
||||
- [ ] Build the new version on https://readthedocs.org/projects/solidity/ (select `latest` at the bottom of the page and click `BUILD`).
|
||||
- [ ] In the admin panel, select `Versions` in the menu and set the default version to the released one.
|
||||
|
||||
### Release solc-js
|
||||
- [ ] Wait until solc-bin was properly deployed. You can test this via remix - a test run through remix is advisable anyway.
|
||||
@ -101,17 +71,9 @@ At least a day before the release:
|
||||
- [ ] 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.
|
||||
- [ ] Publish the blog post.
|
||||
- [ ] 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 :).
|
||||
- [ ] Announce on Twitter, including links to the release and the blog post.
|
||||
- [ ] Share announcement on Reddit and Solidity forum.
|
||||
- [ ] Update the release information section on [soliditylang.org](https://github.com/ethereum/solidity-portal).
|
||||
- [ ] Lean back, wait for bug reports and repeat from step 1 :)
|
||||
|
@ -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 #<issue number>` 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.
|
@ -23,63 +23,47 @@ if(NOT EMSCRIPTEN)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(PEDANTIC)
|
||||
eth_add_cxx_compiler_flag_if_supported(-Wimplicit-fallthrough)
|
||||
endif()
|
||||
eth_add_cxx_compiler_flag_if_supported(-Wimplicit-fallthrough)
|
||||
|
||||
# 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")
|
||||
eth_add_cxx_compiler_flag_if_supported("-fmacro-prefix-map=${CMAKE_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()
|
||||
eth_add_cxx_compiler_flag_if_supported(-Wpessimizing-move)
|
||||
|
||||
# -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()
|
||||
eth_add_cxx_compiler_flag_if_supported(-Wredundant-move)
|
||||
|
||||
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)
|
||||
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($<$<COMPILE_LANGUAGE:CXX>:-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($<$<COMPILE_LANGUAGE:CXX>:-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()
|
||||
eth_add_cxx_compiler_flag_if_supported(
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Wextra-semi>
|
||||
)
|
||||
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)
|
||||
|
||||
# Configuration-specific compiler settings.
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -DETH_DEBUG")
|
||||
@ -173,9 +157,7 @@ elseif (DEFINED MSVC)
|
||||
|
||||
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(/WX) # enable warnings-as-errors
|
||||
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)
|
||||
|
@ -20,16 +20,4 @@ macro (eth_policy)
|
||||
# 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()
|
||||
|
@ -48,11 +48,3 @@ function(detect_stray_source_files FILELIST DIRECTORY)
|
||||
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()
|
||||
|
@ -2,11 +2,11 @@ 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
|
||||
PREFIX "${CMAKE_BINARY_DIR}/deps"
|
||||
DOWNLOAD_DIR "${CMAKE_SOURCE_DIR}/deps/downloads"
|
||||
DOWNLOAD_NAME fmt-8.0.1.tar.gz
|
||||
URL https://github.com/fmtlib/fmt/archive/8.0.1.tar.gz
|
||||
URL_HASH SHA256=b06ca3130158c625848f3fb7418f235155a4d389b2abc3a6245fb01cb0eb1e01
|
||||
)
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS "3.14.0")
|
||||
|
@ -6,7 +6,7 @@ else()
|
||||
set(JSONCPP_CMAKE_COMMAND ${CMAKE_COMMAND})
|
||||
endif()
|
||||
|
||||
set(prefix "${PROJECT_BINARY_DIR}/deps")
|
||||
set(prefix "${CMAKE_BINARY_DIR}/deps")
|
||||
set(JSONCPP_LIBRARY "${prefix}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsoncpp${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
set(JSONCPP_INCLUDE_DIR "${prefix}/include")
|
||||
|
||||
@ -42,7 +42,7 @@ endif()
|
||||
|
||||
ExternalProject_Add(jsoncpp-project
|
||||
PREFIX "${prefix}"
|
||||
DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads"
|
||||
DOWNLOAD_DIR "${CMAKE_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
|
||||
|
@ -6,15 +6,15 @@ else()
|
||||
set(RANGE_V3_CMAKE_COMMAND ${CMAKE_COMMAND})
|
||||
endif()
|
||||
|
||||
set(prefix "${PROJECT_BINARY_DIR}/deps")
|
||||
set(prefix "${CMAKE_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
|
||||
DOWNLOAD_DIR "${CMAKE_SOURCE_DIR}/deps/downloads"
|
||||
DOWNLOAD_NAME range-v3-0.11.0.tar.gz
|
||||
URL https://github.com/ericniebler/range-v3/archive/0.11.0.tar.gz
|
||||
URL_HASH SHA256=376376615dbba43d3bef75aa590931431ecb49eb36d07bb726a19f680c75e20c
|
||||
CMAKE_COMMAND ${RANGE_V3_CMAKE_COMMAND}
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
|
13
cmake/templates/ewasm_polyfill.in
Normal file
@ -0,0 +1,13 @@
|
||||
// The generation of this file is defined in libyul/CMakeLists.txt.
|
||||
// This file was generated by using the content of libyul/backends/wasm/polyfill/@EWASM_POLYFILL_NAME@.yul.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace solidity::yul::wasm::polyfill
|
||||
{
|
||||
|
||||
static char const @EWASM_POLYFILL_NAME@[] = {
|
||||
@EWASM_POLYFILL_CONTENT@, 0
|
||||
};
|
||||
|
||||
} // namespace solidity::yul::wasm::polyfill
|
@ -89,8 +89,8 @@ For most of the topics the compiler will provide suggestions.
|
||||
|
||||
* 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)``
|
||||
variables. For example, change ``uint[] x = m_x`` to ``uint[] storage x =
|
||||
m_x``, 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``.
|
||||
@ -137,7 +137,7 @@ For most of the topics the compiler will provide suggestions.
|
||||
``payable`` or create a new internal function for the program logic that
|
||||
uses ``msg.value``.
|
||||
|
||||
* For clarity reasons, the command-line interface now requires ``-`` if the
|
||||
* For clarity reasons, the command line interface now requires ``-`` if the
|
||||
standard input is used as source.
|
||||
|
||||
Deprecated Elements
|
||||
@ -147,18 +147,18 @@ 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``.
|
||||
|
||||
Command-line and JSON Interfaces
|
||||
Command Line and JSON Interfaces
|
||||
--------------------------------
|
||||
|
||||
* The command-line option ``--formal`` (used to generate Why3 output for
|
||||
* The command line option ``--formal`` (used to generate Why3 output for
|
||||
further formal verification) was deprecated and is now removed. A new
|
||||
formal verification module, the SMTChecker, is enabled via ``pragma
|
||||
experimental SMTChecker;``.
|
||||
|
||||
* The command-line option ``--julia`` was renamed to ``--yul`` due to the
|
||||
* The command line option ``--julia`` was renamed to ``--yul`` due to the
|
||||
renaming of the intermediate language ``Julia`` to ``Yul``.
|
||||
|
||||
* The ``--clone-bin`` and ``--combined-json clone-bin`` command-line options
|
||||
* The ``--clone-bin`` and ``--combined-json clone-bin`` command line options
|
||||
were removed.
|
||||
|
||||
* Remappings with empty prefix are disallowed.
|
||||
@ -483,7 +483,7 @@ New version:
|
||||
return data;
|
||||
}
|
||||
|
||||
using AddressMakePayable for address;
|
||||
using address_make_payable for address;
|
||||
// Data location for 'arr' must be specified
|
||||
function g(uint[] memory /* arr */, bytes8 x, OtherContract otherContract, address unknownContract) public payable {
|
||||
// 'otherContract.transfer' is not provided.
|
||||
@ -500,7 +500,7 @@ New version:
|
||||
// 'address payable' should be used whenever possible.
|
||||
// To increase clarity, we suggest the use of a library for
|
||||
// the conversion (provided after the contract in this example).
|
||||
address payable addr = unknownContract.makePayable();
|
||||
address payable addr = unknownContract.make_payable();
|
||||
require(addr.send(1 ether));
|
||||
|
||||
// Since uint32 (4 bytes) is smaller than bytes8 (8 bytes),
|
||||
@ -516,8 +516,8 @@ New version:
|
||||
|
||||
// We can define a library for explicitly converting ``address``
|
||||
// to ``address payable`` as a workaround.
|
||||
library AddressMakePayable {
|
||||
function makePayable(address x) internal pure returns (address payable) {
|
||||
library address_make_payable {
|
||||
function make_payable(address x) internal pure returns (address payable) {
|
||||
return address(uint160(x));
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ For the full list check
|
||||
Changes the Compiler Might not Warn About
|
||||
=========================================
|
||||
|
||||
This section lists changes where the behavior of your code might
|
||||
This section lists changes where the behaviour of your code might
|
||||
change without the compiler telling you about it.
|
||||
|
||||
* The resulting type of an exponentiation is the type of the base. It used to be the smallest type
|
||||
@ -53,8 +53,6 @@ For most of the topics the compiler will provide suggestions.
|
||||
If the name contains a dot, its prefix up to the dot may not conflict with any declaration outside the inline
|
||||
assembly block.
|
||||
|
||||
* In inline assembly, opcodes that do not take arguments are now represented as "built-in functions" instead of standalone identifiers. So ``gas`` is now ``gas()``.
|
||||
|
||||
* State variable shadowing is now disallowed. A derived contract can only
|
||||
declare a state variable ``x``, if there is no visible state variable with
|
||||
the same name in any of its bases.
|
||||
@ -105,23 +103,23 @@ Interface Changes
|
||||
=================
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
New Error 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.
|
||||
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 the deprecated old error reporter.
|
||||
|
||||
Metadata Hash Options
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The compiler now appends the `IPFS <https://ipfs.io/>`_ hash of the metadata file to the end of the bytecode by default
|
||||
(for details, see documentation on :doc:`contract metadata <metadata>`). Before 0.6.0, the compiler appended the
|
||||
`Swarm <https://ethersphere.github.io/swarm-home/>`_ 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.
|
||||
`Swarm <https://ethersphere.github.io/swarm-home/>`_ hash by default, and in order to still support this behaviour,
|
||||
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.
|
||||
|
||||
These changes can also be used via the :ref:`Standard JSON Interface<compiler-api>` and effect the metadata JSON generated by the compiler.
|
||||
@ -176,6 +174,3 @@ This section gives detailed instructions on how to update prior code for every b
|
||||
``override`` to every overriding function. For multiple inheritance, add ``override(A, B, ..)``,
|
||||
where you list all contracts that define the overridden function in the parentheses. When
|
||||
multiple bases define the same function, the inheriting contract must override all conflicting functions.
|
||||
|
||||
* In inline assembly, add ``()`` to all opcodes that do not otherwise accept an argument.
|
||||
For example, change ``pc`` to ``pc()``, and ``gas`` to ``gas()``.
|
||||
|
@ -10,18 +10,18 @@ For the full list check
|
||||
Silent Changes of the Semantics
|
||||
===============================
|
||||
|
||||
This section lists changes where existing code changes its behavior without
|
||||
This section lists changes where existing code changes its behaviour without
|
||||
the compiler notifying you about it.
|
||||
|
||||
* Arithmetic operations revert on underflow and overflow. You can use ``unchecked { ... }`` to use
|
||||
the previous wrapping behavior.
|
||||
the previous wrapping behaviour.
|
||||
|
||||
Checks for overflow are very common, so we made them the default to increase readability of code,
|
||||
even if it comes at a slight increase of gas costs.
|
||||
|
||||
* ABI coder v2 is activated by default.
|
||||
|
||||
You can choose to use the old behavior using ``pragma abicoder v1;``.
|
||||
You can choose to use the old behaviour using ``pragma abicoder v1;``.
|
||||
The pragma ``pragma experimental ABIEncoderV2;`` is still valid, but it is deprecated and has no effect.
|
||||
If you want to be explicit, please use ``pragma abicoder v2;`` instead.
|
||||
|
||||
@ -57,7 +57,7 @@ New Restrictions
|
||||
|
||||
This section lists changes that might cause existing contracts to not compile anymore.
|
||||
|
||||
* There are new restrictions related to explicit conversions of literals. The previous behavior in
|
||||
* There are new restrictions related to explicit conversions of literals. The previous behaviour in
|
||||
the following cases was likely ambiguous:
|
||||
|
||||
1. Explicit conversions from negative literals and literals larger than ``type(uint160).max`` to
|
||||
@ -106,7 +106,7 @@ This section lists changes that might cause existing contracts to not compile an
|
||||
|
||||
* The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed.
|
||||
|
||||
These are low-level functions that were largely unused. Their behavior can be accessed from inline assembly.
|
||||
These are low-level functions that were largely unused. Their behaviour can be accessed from inline assembly.
|
||||
|
||||
* ``enum`` definitions cannot contain more than 256 members.
|
||||
|
||||
@ -173,4 +173,4 @@ How to update your code
|
||||
- Change ``msg.sender.transfer(x)`` to ``payable(msg.sender).transfer(x)`` or use a stored variable of ``address payable`` type.
|
||||
- Change ``x**y**z`` to ``(x**y)**z``.
|
||||
- Use inline assembly as a replacement for ``log0``, ..., ``log4``.
|
||||
- Negate unsigned integers by subtracting them from the maximum value of the type and adding 1 (e.g. ``type(uint256).max - x + 1``, while ensuring that ``x`` is not zero)
|
||||
- Negate unsigned integers by subtracting them from the maximum value of the type and adding 1 (e.g. ``type(uint256).max - x + 1``, while ensuring that `x` is not zero)
|
||||
|
@ -34,6 +34,7 @@ help:
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@ -115,6 +116,12 @@ latexpdf:
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
latexpdfja:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
|
@ -1,23 +0,0 @@
|
||||
# Solidity Language Docs
|
||||
|
||||
## Local environment setup
|
||||
|
||||
1. Install python https://www.python.org/downloads/
|
||||
1. Install sphinx (the tool used to generate the docs) https://www.sphinx-doc.org/en/master/usage/installation.html
|
||||
|
||||
Go to `/docs` and run `./docs.sh` to install dependencies and build the project:
|
||||
|
||||
```sh
|
||||
cd docs
|
||||
./docs.sh
|
||||
```
|
||||
|
||||
That will output the generated htmls under _build/
|
||||
|
||||
## Serve environment
|
||||
|
||||
```py
|
||||
python3 -m http.server -d _build/html --cgi 8080
|
||||
```
|
||||
|
||||
Visit dev server at http://localhost:8080
|
595
docs/_static/css/custom-dark.css
vendored
@ -1,595 +0,0 @@
|
||||
|
||||
|
||||
/* DARK MODE STYLING */
|
||||
|
||||
/* code directives */
|
||||
|
||||
:root[style*=dark] .method dt,
|
||||
:root[style*=dark] .class dt,
|
||||
:root[style*=dark] .data dt,
|
||||
:root[style*=dark] .attribute dt,
|
||||
:root[style*=dark] .function dt,
|
||||
:root[style*=dark] .classmethod dt,
|
||||
:root[style*=dark] .exception dt,
|
||||
:root[style*=dark] .descclassname,
|
||||
:root[style*=dark] .descname {
|
||||
background-color: #2d2d2d !important;
|
||||
}
|
||||
|
||||
:root[style*=dark] .rst-content dl:not(.docutils) dt {
|
||||
background-color: #0008;
|
||||
border-top: solid 3px #fff2;
|
||||
border-left: solid 3px #fff2;
|
||||
}
|
||||
|
||||
:root[style*=dark] em.property {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
|
||||
/* tables */
|
||||
|
||||
:root[style*=dark] .rst-content table.docutils td {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
:root[style*=dark] .rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td {
|
||||
background-color: #0002;
|
||||
}
|
||||
|
||||
:root[style*=dark] .rst-content pre {
|
||||
background: none;
|
||||
}
|
||||
|
||||
/* inlined code highlights */
|
||||
|
||||
:root[style*=dark] .xref,
|
||||
:root[style*=dark] .py-meth {
|
||||
color: #aaddff !important;
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
/* highlight color search text */
|
||||
|
||||
:root[style*=dark] .rst-content .highlighted {
|
||||
background: #ff5722;
|
||||
box-shadow: 0 0 0 2px #f0978b;
|
||||
}
|
||||
|
||||
/* notes, warnings, hints */
|
||||
|
||||
:root[style*=dark] .hint .admonition-title {
|
||||
background: #2aa87c !important;
|
||||
}
|
||||
|
||||
:root[style*=dark] .warning .admonition-title {
|
||||
background: #cc4444 !important;
|
||||
}
|
||||
|
||||
:root[style*=dark] .admonition-title {
|
||||
background: #3a7ca8 !important;
|
||||
}
|
||||
|
||||
:root[style*=dark] .admonition,
|
||||
:root[style*=dark] .note {
|
||||
background-color: #0008 !important;
|
||||
}
|
||||
|
||||
|
||||
/* table of contents */
|
||||
|
||||
:root[style*=dark] .sidebar {
|
||||
background-color: #191919 !important;
|
||||
}
|
||||
|
||||
:root[style*=dark] .sidebar-title {
|
||||
background-color: #2b2b2b !important;
|
||||
}
|
||||
|
||||
:root[style*=dark] .wy-menu-vertical code.docutils.literal.notranslate {
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
|
||||
:root[style*=dark] .toc-backref {
|
||||
color: grey !important;
|
||||
}
|
||||
|
||||
:root[style*=dark] .highlight {
|
||||
background: #0008;
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
:root[style*=dark] .highlight .c {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment */
|
||||
|
||||
:root[style*=dark] .highlight .err {
|
||||
color: #960050;
|
||||
background-color: #1e0010
|
||||
}
|
||||
|
||||
|
||||
/* Error */
|
||||
|
||||
:root[style*=dark] .highlight .k {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword */
|
||||
|
||||
:root[style*=dark] .highlight .l {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal */
|
||||
|
||||
:root[style*=dark] .highlight .n {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name */
|
||||
|
||||
:root[style*=dark] .highlight .o {
|
||||
color: #f92672
|
||||
}
|
||||
|
||||
|
||||
/* Operator */
|
||||
|
||||
:root[style*=dark] .highlight .p {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Punctuation */
|
||||
|
||||
:root[style*=dark] .highlight .ch {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.Hashbang */
|
||||
|
||||
:root[style*=dark] .highlight .cm {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.Multiline */
|
||||
|
||||
:root[style*=dark] .highlight .cp {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.Preproc */
|
||||
|
||||
:root[style*=dark] .highlight .cpf {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.PreprocFile */
|
||||
|
||||
:root[style*=dark] .highlight .c1 {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.Single */
|
||||
|
||||
:root[style*=dark] .highlight .cs {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.Special */
|
||||
|
||||
:root[style*=dark] .highlight .gd {
|
||||
color: #f92672
|
||||
}
|
||||
|
||||
|
||||
/* Generic.Deleted */
|
||||
|
||||
:root[style*=dark] .highlight .ge {
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
|
||||
/* Generic.Emph */
|
||||
|
||||
:root[style*=dark] .highlight .gi {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Generic.Inserted */
|
||||
|
||||
:root[style*=dark] .highlight .gs {
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
|
||||
/* Generic.Strong */
|
||||
|
||||
:root[style*=dark] .highlight .gu {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Generic.Subheading */
|
||||
|
||||
:root[style*=dark] .highlight .kc {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Constant */
|
||||
|
||||
:root[style*=dark] .highlight .kd {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Declaration */
|
||||
|
||||
:root[style*=dark] .highlight .kn {
|
||||
color: #f92672
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Namespace */
|
||||
|
||||
:root[style*=dark] .highlight .kp {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Pseudo */
|
||||
|
||||
:root[style*=dark] .highlight .kr {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Reserved */
|
||||
|
||||
:root[style*=dark] .highlight .kt {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Type */
|
||||
|
||||
:root[style*=dark] .highlight .ld {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Date */
|
||||
|
||||
:root[style*=dark] .highlight .m {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number */
|
||||
|
||||
:root[style*=dark] .highlight .s {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String */
|
||||
|
||||
:root[style*=dark] .highlight .na {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Attribute */
|
||||
|
||||
:root[style*=dark] .highlight .nb {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Builtin */
|
||||
|
||||
:root[style*=dark] .highlight .nc {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Class */
|
||||
|
||||
:root[style*=dark] .highlight .no {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Name.Constant */
|
||||
|
||||
:root[style*=dark] .highlight .nd {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Decorator */
|
||||
|
||||
:root[style*=dark] .highlight .ni {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Entity */
|
||||
|
||||
:root[style*=dark] .highlight .ne {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Exception */
|
||||
|
||||
:root[style*=dark] .highlight .nf {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Function */
|
||||
|
||||
:root[style*=dark] .highlight .nl {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Label */
|
||||
|
||||
:root[style*=dark] .highlight .nn {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Namespace */
|
||||
|
||||
:root[style*=dark] .highlight .nx {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Other */
|
||||
|
||||
:root[style*=dark] .highlight .py {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Property */
|
||||
|
||||
:root[style*=dark] .highlight .nt {
|
||||
color: #f92672
|
||||
}
|
||||
|
||||
|
||||
/* Name.Tag */
|
||||
|
||||
:root[style*=dark] .highlight .nv {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Variable */
|
||||
|
||||
:root[style*=dark] .highlight .ow {
|
||||
color: #f92672
|
||||
}
|
||||
|
||||
|
||||
/* Operator.Word */
|
||||
|
||||
:root[style*=dark] .highlight .w {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Text.Whitespace */
|
||||
|
||||
:root[style*=dark] .highlight .mb {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number.Bin */
|
||||
|
||||
:root[style*=dark] .highlight .mf {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number.Float */
|
||||
|
||||
:root[style*=dark] .highlight .mh {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number.Hex */
|
||||
|
||||
:root[style*=dark] .highlight .mi {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number.Integer */
|
||||
|
||||
:root[style*=dark] .highlight .mo {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number.Oct */
|
||||
|
||||
:root[style*=dark] .highlight .sa {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Affix */
|
||||
|
||||
:root[style*=dark] .highlight .sb {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Backtick */
|
||||
|
||||
:root[style*=dark] .highlight .sc {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Char */
|
||||
|
||||
:root[style*=dark] .highlight .dl {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Delimiter */
|
||||
|
||||
:root[style*=dark] .highlight .sd {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Doc */
|
||||
|
||||
:root[style*=dark] .highlight .s2 {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Double */
|
||||
|
||||
:root[style*=dark] .highlight .se {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Escape */
|
||||
|
||||
:root[style*=dark] .highlight .sh {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Heredoc */
|
||||
|
||||
:root[style*=dark] .highlight .si {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Interpol */
|
||||
|
||||
:root[style*=dark] .highlight .sx {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Other */
|
||||
|
||||
:root[style*=dark] .highlight .sr {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Regex */
|
||||
|
||||
:root[style*=dark] .highlight .s1 {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Single */
|
||||
|
||||
:root[style*=dark] .highlight .ss {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Symbol */
|
||||
|
||||
:root[style*=dark] .highlight .bp {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Builtin.Pseudo */
|
||||
|
||||
:root[style*=dark] .highlight .fm {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Function.Magic */
|
||||
|
||||
:root[style*=dark] .highlight .vc {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Variable.Class */
|
||||
|
||||
:root[style*=dark] .highlight .vg {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Variable.Global */
|
||||
|
||||
:root[style*=dark] .highlight .vi {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Variable.Instance */
|
||||
|
||||
:root[style*=dark] .highlight .vm {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Variable.Magic */
|
||||
|
||||
:root[style*=dark] .highlight .il {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Grammar */
|
||||
|
||||
:root[style*=dark] .railroad-diagram {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
:root[style*=dark] .railroad-diagram path {
|
||||
stroke: white;
|
||||
}
|
||||
|
||||
:root[style*=dark] .railroad-diagram rect {
|
||||
stroke: white;
|
||||
}
|
||||
|
||||
:root[style*=dark] .a4 .sig-name {
|
||||
background-color: transparent !important;
|
||||
}
|
834
docs/_static/css/custom.css
vendored
@ -1,185 +1,23 @@
|
||||
/* ROOT DECLARATIONS */
|
||||
:root {
|
||||
/* Text */
|
||||
--color-a: #2B247C;
|
||||
--color-b: #672AC8;
|
||||
--color-c: #5554D9;
|
||||
--color-d: #9F94E8;
|
||||
--color-e: #AEC0F1;
|
||||
--color-f: #E6E3EC;
|
||||
/* Background */
|
||||
|
||||
--white: #FAF8FF;
|
||||
--black: #110C4E;
|
||||
--menu-bg: #2B247C06;
|
||||
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
|
||||
--navHeight: 4.5rem;
|
||||
--sideWidth: 300px;
|
||||
--maxWidth: 80rem;
|
||||
--desktopInlinePadding: 2rem;
|
||||
--mobileInlinePadding: 1rem;
|
||||
--currentVersionHeight: 45px;
|
||||
|
||||
text-rendering: geometricPrecision;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
a,
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
:root[style*=dark] {
|
||||
--color-a: #E6E3EC !important;
|
||||
--color-b: #AEC0F1 !important;
|
||||
--color-c: #9F94E8 !important;
|
||||
--color-d: #5554D9 !important;
|
||||
--color-e: #672AC8 !important;
|
||||
--color-f: #2B247C !important;
|
||||
|
||||
--white: #110C4E !important;
|
||||
--black: #FAF8FF !important;
|
||||
--menu-bg: #E6E3EC06 !important;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
.unified-header::before,
|
||||
.wy-nav-side,
|
||||
.rst-versions,
|
||||
code,
|
||||
div,
|
||||
input[type=text],
|
||||
a,
|
||||
.wy-grid-for-nav {
|
||||
transition: background 150ms ease-in-out;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
.wy-grid-for-nav {
|
||||
background-color: var(--color-f) !important;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Overpass", sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-c);
|
||||
}
|
||||
|
||||
a, section {
|
||||
scroll-margin-top: calc(var(--navHeight) + 2rem);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin-block: 2rem;
|
||||
border-color: var(--color-d) !important;
|
||||
}
|
||||
|
||||
|
||||
/* HEADER STYLES */
|
||||
h1 {
|
||||
font-family: 'Overpass', sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 44px;
|
||||
color: var(--color-a) !important;
|
||||
line-height: 1.1;
|
||||
text-wrap: balance;
|
||||
margin-top: 4rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
section:first-of-type h1:first-of-type {
|
||||
font-family: 'Overpass mono', monospace;
|
||||
font-size: 48px;
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 5rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: 'Overpass', sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 38px;
|
||||
color: var(--color-a) !important;
|
||||
line-height: 46px;
|
||||
text-wrap: balance;
|
||||
margin-top: 4rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
*:not([role=navigation])>p[role=heading]>span,
|
||||
h3 {
|
||||
font-family: 'Overpass', sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 32px;
|
||||
color: var(--color-a) !important;
|
||||
line-height: 46px;
|
||||
text-wrap: balance;
|
||||
margin-top: 4rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-family: 'Overpass', sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 32px;
|
||||
color: var(--color-a) !important;
|
||||
line-height: 46px;
|
||||
text-wrap: balance;
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-family: 'Overpass', sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 18px;
|
||||
color: var(--color-a) !important;
|
||||
line-height: 1.4;
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-family: 'Overpass', sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
color: var(--color-a) !important;
|
||||
line-height: 1.4;
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
span.pre,
|
||||
pre {
|
||||
/* css-3 */
|
||||
white-space: pre-wrap;
|
||||
/* Mozilla, since 1999 */
|
||||
white-space: -moz-pre-wrap;
|
||||
/* Opera 4-6 */
|
||||
white-space: -pre-wrap;
|
||||
/* Opera 7 */
|
||||
white-space: -o-pre-wrap;
|
||||
white-space: pre-wrap; /* css-3 */
|
||||
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
word-wrap: break-word;
|
||||
font-family: 'Overpass Mono', monospace;
|
||||
}
|
||||
|
||||
small,
|
||||
small * {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.wy-table-responsive table td,
|
||||
.wy-table-responsive table th {
|
||||
.wy-table-responsive table td, .wy-table-responsive table th {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.rst-content table.docutils td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* links */
|
||||
.rst-content a:not(:visited) {
|
||||
color: #002fa7;
|
||||
}
|
||||
|
||||
.rst-content .highlighted {
|
||||
background: #eac545;
|
||||
}
|
||||
@ -189,638 +27,60 @@ small * {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.wy-side-nav-search img.logo {
|
||||
width: 100px !important;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.wy-side-nav-search > a {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* project version (displayed under project logo) */
|
||||
.wy-side-nav-search>div.version {
|
||||
color: var(--color-b);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
text-align: start;
|
||||
.wy-side-nav-search .version {
|
||||
color: #272525 !important;
|
||||
}
|
||||
|
||||
/* menu section headers */
|
||||
.wy-menu .caption {
|
||||
color: #65afff !important;
|
||||
}
|
||||
|
||||
/* Link to Remix IDE shown next to code snippets */
|
||||
.rst-content p.remix-link-container {
|
||||
display: block;
|
||||
text-align: right;
|
||||
margin: 0;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
.rst-content .remix-link-container a.remix-link {
|
||||
font-size: 0.7em;
|
||||
padding: 0.1em 0.5em;
|
||||
background: transparent;
|
||||
color: var(--color-a) !important;
|
||||
border: 1px solid var(--color-a);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.rst-content div.highlight-solidity,
|
||||
.rst-content div.highlight-yul {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* CUSTOMIZATION UPDATES */
|
||||
|
||||
.wy-nav-content-wrap,
|
||||
.wy-nav-content {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.wy-side-nav-search {
|
||||
background-color: transparent !important;
|
||||
color: var(--color-a) !important;
|
||||
box-shadow: 0 4 4 0 var(--color-a);
|
||||
border-bottom: 1px solid var(--color-d) !important;
|
||||
}
|
||||
|
||||
.wy-side-nav-search svg {
|
||||
color: var(--color-a) !important;
|
||||
}
|
||||
|
||||
.wy-nav-top {
|
||||
background-color: transparent !important;
|
||||
color: var(--color-a) !important;
|
||||
}
|
||||
|
||||
.wy-nav-top a {
|
||||
color: var(--color-a) !important;
|
||||
}
|
||||
|
||||
.wy-breadcrumbs a.icon-home:before {
|
||||
content: "Documentation";
|
||||
font-family: "Overpass", sans-serif;
|
||||
}
|
||||
|
||||
.rst-content table.docutils thead {
|
||||
color: var(--color-a);
|
||||
}
|
||||
|
||||
code.docutils.literal.notranslate {
|
||||
padding: 2px 4px;
|
||||
font-size: 0.875em;
|
||||
font-family: "Overpass Mono", monospace;
|
||||
background: var(--white);
|
||||
color: var(--color-c);
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
dt code.docutils.literal.notranslate {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.wy-nav-content {
|
||||
color: var(--color-a);
|
||||
}
|
||||
|
||||
/* .rst-content a:not(:visited) { */
|
||||
/* color: var(--color-b) !important; */
|
||||
/* } */
|
||||
|
||||
.rst-content a:visited {
|
||||
color: var(--color-c) !important;
|
||||
}
|
||||
|
||||
.rst-content a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.rst-content a:where(:focus, :focus-visible, :hover) {
|
||||
color: var(--color-d) !important;
|
||||
}
|
||||
|
||||
.wy-side-scroll a {
|
||||
color: var(--color-a);
|
||||
background: transparent;
|
||||
font-size: 1rem;
|
||||
line-height: 125%;
|
||||
}
|
||||
|
||||
.wy-menu-vertical li.current a,
|
||||
.wy-menu-vertical li.current li a,
|
||||
.wy-menu-vertical li.current li a code {
|
||||
border: none;
|
||||
color: var(--color-a);
|
||||
}
|
||||
|
||||
ul.current ul,
|
||||
.wy-menu-vertical li.current a:hover,
|
||||
.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,
|
||||
.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,
|
||||
.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,
|
||||
.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,
|
||||
.wy-menu-vertical li.current {
|
||||
background: var(--menu-bg) !important;
|
||||
}
|
||||
|
||||
.wy-menu.wy-menu-vertical>ul {
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.wy-menu.wy-menu-vertical>p {
|
||||
color: var(--color-c);
|
||||
}
|
||||
|
||||
.wy-menu-vertical li.on a,
|
||||
.wy-menu-vertical li.current>a {
|
||||
background: var(--menu-bg) !important;
|
||||
border-bottom: 0px !important;
|
||||
border-top: 0px !important;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border-radius: 0;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.wy-breadcrumbs-aside a,
|
||||
.wy-breadcrumbs-aside a:visited,
|
||||
a.fa.fa-github,
|
||||
a.fa.fa-github:visited,
|
||||
a.fa.fa-github:not(:visited),
|
||||
a.btn.btn-neutral:visited,
|
||||
a.btn.btn-neutral:not(:visited),
|
||||
a.btn.btn-neutral {
|
||||
background: transparent !important;
|
||||
color: var(--color-a) !important;
|
||||
border: 2px solid var(--color-a) !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.rst-content .remix-link-container a.remix-link:hover,
|
||||
.wy-breadcrumbs-aside a:hover,
|
||||
a.fa.fa-github:hover,
|
||||
a.btn.btn-neutral:hover {
|
||||
background: var(--white) !important;
|
||||
color: var(--color-b) !important;
|
||||
border-color: var(--color-b) !important;
|
||||
}
|
||||
|
||||
footer .rst-footer-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Customization for the unified layout
|
||||
*/
|
||||
|
||||
/* Site wrapper, and two children: header and rest */
|
||||
.unified-wrapper {
|
||||
p.remix-link-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
inset: 0;
|
||||
max-width: var(--maxWidth);
|
||||
margin-inline: auto;
|
||||
right: -100%; /* Positioned next to the the top-right corner of the code block following it. */
|
||||
}
|
||||
|
||||
/* Site header */
|
||||
.unified-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
inset-inline: 0;
|
||||
z-index: 99999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-shadow: var(--shadow);
|
||||
a.remix-link {
|
||||
position: absolute; /* Remove it from normal flow not to affect the original position of the snippet. */
|
||||
top: 0.5em;
|
||||
width: 3.236em; /* Size of the margin (= right-side padding in .wy-nav-content in the current theme). */
|
||||
}
|
||||
|
||||
.unified-header .inner-header {
|
||||
display: flex;
|
||||
margin-inline: auto;
|
||||
width: 100%;
|
||||
max-width: var(--maxWidth);
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-inline: var(--desktopInlinePadding);
|
||||
padding-block: 1rem;
|
||||
}
|
||||
|
||||
.unified-header::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 95%;
|
||||
background: var(--color-f);
|
||||
z-index: -1;
|
||||
backdrop-filter: blur(3px);
|
||||
}
|
||||
|
||||
.unified-header .home-link {
|
||||
a.remix-link .link-icon {
|
||||
background: url("../img/solid-share-arrow.svg") no-repeat;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
width: 25px;
|
||||
height: 40px;
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.unified-header .home-link:hover .solidity-logo {
|
||||
transform: scale(1.1);
|
||||
transition: transform 100ms ease-in-out;
|
||||
a.remix-link .link-text {
|
||||
display: none; /* Visible only on hover. */
|
||||
width: 3.3em; /* Narrow enough to get two lines of text. */
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
font-size: 0.8em;
|
||||
line-height: normal;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.unified-header img.solidity-logo {
|
||||
transform: scale(1);
|
||||
transition: transform 100ms ease-in-out;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.unified-header .nav-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.unified-header .nav-bar .nav-button-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.unified-header .nav-link {
|
||||
display: inline-block;
|
||||
padding-inline: 8px;
|
||||
padding-block: 4px;
|
||||
font-size: 14px;
|
||||
font-family: 'Overpass Mono', monospace;
|
||||
text-decoration: none;
|
||||
color: var(--color-a);
|
||||
letter-spacing: -0.02em;
|
||||
font-weight: 400;
|
||||
box-sizing: content-box;
|
||||
border-bottom: 1px solid transparent;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.unified-header .nav-link.active {
|
||||
background: var(--white);
|
||||
}
|
||||
|
||||
.unified-header .nav-link:hover {
|
||||
color: var(--color-c);
|
||||
border-bottom: 1px solid var(--color-c);
|
||||
}
|
||||
|
||||
/* Rest: Flex-row, with two children: side bar, and content */
|
||||
.unified-wrapper .wy-grid-for-nav {
|
||||
position: relative !important;
|
||||
display: flex;
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
/* First child: Side bar */
|
||||
.unified-wrapper .wy-grid-for-nav nav.wy-nav-side {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--color-f);
|
||||
color: var(--color-a);
|
||||
padding-bottom: unset !important;
|
||||
z-index: 10 !important;
|
||||
min-height: unset !important;
|
||||
width: var(--sideWidth) !important;
|
||||
top: var(--navHeight);
|
||||
bottom: 0;
|
||||
left: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll {
|
||||
position: static !important;
|
||||
width: unset !important;
|
||||
overflow: unset !important;
|
||||
height: unset !important;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll .wy-side-nav-search {
|
||||
margin: 0 !important;
|
||||
width: var(--sideWidth) !important;
|
||||
}
|
||||
|
||||
.wy-nav-side,
|
||||
.wy-side-scroll,
|
||||
.wy-side-nav-search,
|
||||
.my-menu {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.wy-nav-side input[type=text] {
|
||||
font-family: "Overpass", sans-serif;
|
||||
border-radius: 0;
|
||||
border-color: var(--color-d);
|
||||
background: var(--white);
|
||||
box-shadow: none;
|
||||
color: var(--color-a);
|
||||
}
|
||||
|
||||
.wy-nav-side input[type=text]::placeholder {
|
||||
font-family: "Overpass", sans-serif;
|
||||
color: var(--color-e);
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
/* Second child: Content */
|
||||
.unified-wrapper .wy-grid-for-nav .wy-nav-content {
|
||||
width: 100%;
|
||||
max-width: unset !important; /* override */
|
||||
padding-inline: var(--desktopInlinePadding);
|
||||
margin-inline-start: var(--sideWidth);
|
||||
margin-top: var(--navHeight);
|
||||
}
|
||||
|
||||
.unified-wrapper .wy-grid-for-nav .wy-nav-content .rst-content {
|
||||
max-width: min(70ch, calc(100vw - 2 * var(--desktopInlinePadding) - var(--sideWidth)));
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.unified-wrapper.menu-open .backdrop {
|
||||
a.remix-link:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.unified-wrapper .wy-nav-side,
|
||||
.unified-wrapper .rst-versions {
|
||||
left: auto;
|
||||
|
||||
}
|
||||
|
||||
.unified-wrapper .backdrop {
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
h2 {
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Menu closed styles */
|
||||
.unified-header .nav-link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.unified-header .inner-header {
|
||||
padding-inline: var(--mobileInlinePadding);
|
||||
}
|
||||
|
||||
.unified-wrapper .wy-grid-for-nav nav.wy-nav-side {
|
||||
transform: translateX(-100%);
|
||||
transition: transform 200ms ease-in-out;
|
||||
}
|
||||
|
||||
/* Menu open styles */
|
||||
.unified-wrapper.menu-open nav.wy-nav-side {
|
||||
transform: translateX(0);
|
||||
transition: transform 200ms ease-in-out;
|
||||
}
|
||||
|
||||
.unified-wrapper.menu-open .rst-versions {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.unified-wrapper.menu-open .backdrop {
|
||||
display: block;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
opacity: 1;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
z-index: 5;
|
||||
background: #0006;
|
||||
}
|
||||
|
||||
a.skip-to-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wy-nav-content {
|
||||
margin-inline-start: 0 !important;
|
||||
}
|
||||
|
||||
.rst-content {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.wy-side-scroll {
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
ul.search .context {
|
||||
color: var(--color-a) !important;
|
||||
}
|
||||
|
||||
.rst-versions {
|
||||
background: var(--color-f);
|
||||
}
|
||||
|
||||
.rst-versions.shift-up {
|
||||
height: unset !important;
|
||||
max-height: unset !important;
|
||||
overflow-y: unset !important;
|
||||
}
|
||||
|
||||
.rst-content dl:not(.docutils) dt {
|
||||
color: var(--color-a);
|
||||
background-color: #fff8;
|
||||
border-top: solid 3px #0002;
|
||||
border-inline-start: solid 3px #0002;
|
||||
padding: 2px 6px;
|
||||
}
|
||||
|
||||
.rst-versions .rst-current-version {
|
||||
border-color: var(--color-d) !important;
|
||||
}
|
||||
|
||||
.rst-current-version *,
|
||||
.rst-current-version .fa:before,
|
||||
.rst-current-version .fa-element {
|
||||
color: var(--color-b) !important;
|
||||
}
|
||||
|
||||
.rst-current-version dt,
|
||||
.rst-current-version dd,
|
||||
.rst-current-version dd a,
|
||||
.rst-other-versions dl:last-of-type dt,
|
||||
.rst-other-versions dl:last-of-type dd,
|
||||
.rst-other-versions dl:last-of-type dd a {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
.rst-other-versions {
|
||||
background: var(--white) !important;
|
||||
color: var(--color-a) !important;
|
||||
max-height: calc(100vh - var(--navHeight) - var(--currentVersionHeight));
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.rst-other-versions a {
|
||||
text-decoration: underline;
|
||||
color: var(--color-c) !important;
|
||||
}
|
||||
|
||||
.rst-other-versions dt {
|
||||
color: var(--color-a) !important;
|
||||
}
|
||||
|
||||
.rst-other-versions dl {
|
||||
margin-bottom: 1.5rem !important;
|
||||
}
|
||||
|
||||
.rst-other-versions dl:last-of-type {
|
||||
margin-top: 2rem !important;
|
||||
}
|
||||
|
||||
/* Bottom Search */
|
||||
.wy-nav-side input[type=text],
|
||||
.rst-other-versions dl:last-of-type dd {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.rst-other-versions dl:last-of-type dt {
|
||||
color: var(--color-b) !important;
|
||||
}
|
||||
|
||||
.rst-other-versions dl:last-of-type div[style*=padding],
|
||||
.rst-other-versions dl dd:first-of-type a {
|
||||
padding-inline-start: 0 !important;
|
||||
}
|
||||
|
||||
button.toctree-expand {
|
||||
color: var(--black) !important;
|
||||
}
|
||||
|
||||
/* Light/dark color mode toggle 🌓 */
|
||||
button.color-toggle {
|
||||
display: inline-flex;
|
||||
appearance: none;
|
||||
-webkit-box-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
justify-content: center;
|
||||
user-select: none;
|
||||
outline: none;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 6px;
|
||||
margin: 6px;
|
||||
transition-duration: 200ms;
|
||||
transition-property: background-color,
|
||||
color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity;
|
||||
}
|
||||
|
||||
button.color-toggle:focus-visible {
|
||||
outline: 2px solid var(--color-c);
|
||||
color: var(--color-c);
|
||||
}
|
||||
|
||||
button.color-toggle:hover {
|
||||
color: var(--color-c);
|
||||
background: #0002;
|
||||
}
|
||||
|
||||
button.color-toggle .color-toggle-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
line-height: 1em;
|
||||
-webkit-flex-shrink: 0;
|
||||
-ms-flex-negative: 0;
|
||||
flex-shrink: 0;
|
||||
vertical-align: middle;
|
||||
/* color: var(--color-a); */
|
||||
}
|
||||
|
||||
|
||||
button.mobile-menu-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
nav.wy-nav-top {
|
||||
display: none;
|
||||
}
|
||||
|
||||
button.mobile-menu-button {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#search-results .search li:first-child,
|
||||
#search-results .search li {
|
||||
border-color: var(--color-d);
|
||||
}
|
||||
|
||||
#search-results .search li:last-child {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.forum-link::after {
|
||||
content: ' ↗';
|
||||
font-size: 14px;
|
||||
font-family: 'Overpass Mono', monospace;
|
||||
}
|
||||
|
||||
.wy-breadcrumbs>li {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.wy-breadcrumbs-aside a {
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 12px;
|
||||
font-family: "'Overpass'", sans-serif;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
a.skip-to-content:visited,
|
||||
a.skip-to-content:not(:visited),
|
||||
a.skip-to-content {
|
||||
a.remix-link:hover .link-text {
|
||||
display: block;
|
||||
pointer-events: none;
|
||||
width: fit-content;
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
padding: 2px 4px;
|
||||
font-size: 14px;
|
||||
margin-inline-end: auto;
|
||||
margin-inline-start: 1.5rem;
|
||||
color: var(--color-a);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
a.skip-to-content:focus {
|
||||
opacity: 1;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
}
|
||||
|
||||
#content {
|
||||
scroll-margin-top: 6rem;
|
||||
scroll-behavior: smooth;
|
||||
}
|
635
docs/_static/css/dark.css
vendored
Normal file
@ -0,0 +1,635 @@
|
||||
/* links */
|
||||
|
||||
.rst-content a:not(:visited) {
|
||||
color: #aaddff !important;
|
||||
}
|
||||
|
||||
/* code directives */
|
||||
|
||||
.method dt,
|
||||
.class dt,
|
||||
.data dt,
|
||||
.attribute dt,
|
||||
.function dt,
|
||||
.classmethod dt,
|
||||
.exception dt,
|
||||
.descclassname,
|
||||
.descname {
|
||||
background-color: #2d2d2d !important;
|
||||
}
|
||||
|
||||
.rst-content dl:not(.docutils) dt {
|
||||
color: #aaddff;
|
||||
background-color: #2d2d2d;
|
||||
border-top: solid 3px #525252;
|
||||
border-left: solid 3px #525252;
|
||||
}
|
||||
|
||||
em.property {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
|
||||
/* tables */
|
||||
|
||||
.rst-content table.docutils thead {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.rst-content table.docutils td {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td {
|
||||
background-color: #5a5a5a;
|
||||
}
|
||||
|
||||
.rst-content pre {
|
||||
background: none;
|
||||
}
|
||||
|
||||
/* inlined code highlights */
|
||||
|
||||
.xref,
|
||||
.py-meth,
|
||||
.rst-content a code {
|
||||
color: #aaddff !important;
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
.rst-content code {
|
||||
color: #eee !important;
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
code.literal {
|
||||
background-color: #2d2d2d !important;
|
||||
border: 1px solid #6d6d6d !important;
|
||||
}
|
||||
|
||||
code.docutils.literal.notranslate {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
/* highlight color search text */
|
||||
|
||||
.rst-content .highlighted {
|
||||
background: #ff5722;
|
||||
box-shadow: 0 0 0 2px #f0978b;
|
||||
}
|
||||
|
||||
/* notes, warnings, hints */
|
||||
|
||||
.hint .admonition-title {
|
||||
background: #2aa87c !important;
|
||||
}
|
||||
|
||||
.warning .admonition-title {
|
||||
background: #cc4444 !important;
|
||||
}
|
||||
|
||||
.admonition-title {
|
||||
background: #3a7ca8 !important;
|
||||
}
|
||||
|
||||
.admonition,
|
||||
.note {
|
||||
background-color: #2d2d2d !important;
|
||||
}
|
||||
|
||||
|
||||
/* table of contents */
|
||||
|
||||
.wy-nav-content-wrap {
|
||||
background-color: rgba(0, 0, 0, 0.6) !important;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-color: #191919 !important;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
background-color: #2b2b2b !important;
|
||||
}
|
||||
|
||||
.wy-menu-vertical a {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.wy-menu-vertical code.docutils.literal.notranslate {
|
||||
color: #404040;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.wy-nav-content {
|
||||
background: #3c3c3c;
|
||||
color: #dddddd;
|
||||
}
|
||||
|
||||
.wy-menu-vertical li.on a,
|
||||
.wy-menu-vertical li.current>a {
|
||||
background: #a3a3a3;
|
||||
border-bottom: 0px !important;
|
||||
border-top: 0px !important;
|
||||
}
|
||||
|
||||
.wy-menu-vertical li.current {
|
||||
background: #b3b3b3;
|
||||
}
|
||||
|
||||
.toc-backref {
|
||||
color: grey !important;
|
||||
}
|
||||
|
||||
.highlight .hll {
|
||||
background-color: #49483e
|
||||
}
|
||||
|
||||
.highlight {
|
||||
background: #222;
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
.highlight .c {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment */
|
||||
|
||||
.highlight .err {
|
||||
color: #960050;
|
||||
background-color: #1e0010
|
||||
}
|
||||
|
||||
|
||||
/* Error */
|
||||
|
||||
.highlight .k {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword */
|
||||
|
||||
.highlight .l {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal */
|
||||
|
||||
.highlight .n {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name */
|
||||
|
||||
.highlight .o {
|
||||
color: #f92672
|
||||
}
|
||||
|
||||
|
||||
/* Operator */
|
||||
|
||||
.highlight .p {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Punctuation */
|
||||
|
||||
.highlight .ch {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.Hashbang */
|
||||
|
||||
.highlight .cm {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.Multiline */
|
||||
|
||||
.highlight .cp {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.Preproc */
|
||||
|
||||
.highlight .cpf {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.PreprocFile */
|
||||
|
||||
.highlight .c1 {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.Single */
|
||||
|
||||
.highlight .cs {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Comment.Special */
|
||||
|
||||
.highlight .gd {
|
||||
color: #f92672
|
||||
}
|
||||
|
||||
|
||||
/* Generic.Deleted */
|
||||
|
||||
.highlight .ge {
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
|
||||
/* Generic.Emph */
|
||||
|
||||
.highlight .gi {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Generic.Inserted */
|
||||
|
||||
.highlight .gs {
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
|
||||
/* Generic.Strong */
|
||||
|
||||
.highlight .gu {
|
||||
color: #888
|
||||
}
|
||||
|
||||
|
||||
/* Generic.Subheading */
|
||||
|
||||
.highlight .kc {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Constant */
|
||||
|
||||
.highlight .kd {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Declaration */
|
||||
|
||||
.highlight .kn {
|
||||
color: #f92672
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Namespace */
|
||||
|
||||
.highlight .kp {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Pseudo */
|
||||
|
||||
.highlight .kr {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Reserved */
|
||||
|
||||
.highlight .kt {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Keyword.Type */
|
||||
|
||||
.highlight .ld {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Date */
|
||||
|
||||
.highlight .m {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number */
|
||||
|
||||
.highlight .s {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String */
|
||||
|
||||
.highlight .na {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Attribute */
|
||||
|
||||
.highlight .nb {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Builtin */
|
||||
|
||||
.highlight .nc {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Class */
|
||||
|
||||
.highlight .no {
|
||||
color: #66d9ef
|
||||
}
|
||||
|
||||
|
||||
/* Name.Constant */
|
||||
|
||||
.highlight .nd {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Decorator */
|
||||
|
||||
.highlight .ni {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Entity */
|
||||
|
||||
.highlight .ne {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Exception */
|
||||
|
||||
.highlight .nf {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Function */
|
||||
|
||||
.highlight .nl {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Label */
|
||||
|
||||
.highlight .nn {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Namespace */
|
||||
|
||||
.highlight .nx {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Other */
|
||||
|
||||
.highlight .py {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Property */
|
||||
|
||||
.highlight .nt {
|
||||
color: #f92672
|
||||
}
|
||||
|
||||
|
||||
/* Name.Tag */
|
||||
|
||||
.highlight .nv {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Variable */
|
||||
|
||||
.highlight .ow {
|
||||
color: #f92672
|
||||
}
|
||||
|
||||
|
||||
/* Operator.Word */
|
||||
|
||||
.highlight .w {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Text.Whitespace */
|
||||
|
||||
.highlight .mb {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number.Bin */
|
||||
|
||||
.highlight .mf {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number.Float */
|
||||
|
||||
.highlight .mh {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number.Hex */
|
||||
|
||||
.highlight .mi {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number.Integer */
|
||||
|
||||
.highlight .mo {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number.Oct */
|
||||
|
||||
.highlight .sa {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Affix */
|
||||
|
||||
.highlight .sb {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Backtick */
|
||||
|
||||
.highlight .sc {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Char */
|
||||
|
||||
.highlight .dl {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Delimiter */
|
||||
|
||||
.highlight .sd {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Doc */
|
||||
|
||||
.highlight .s2 {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Double */
|
||||
|
||||
.highlight .se {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Escape */
|
||||
|
||||
.highlight .sh {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Heredoc */
|
||||
|
||||
.highlight .si {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Interpol */
|
||||
|
||||
.highlight .sx {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Other */
|
||||
|
||||
.highlight .sr {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Regex */
|
||||
|
||||
.highlight .s1 {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Single */
|
||||
|
||||
.highlight .ss {
|
||||
color: #e6db74
|
||||
}
|
||||
|
||||
|
||||
/* Literal.String.Symbol */
|
||||
|
||||
.highlight .bp {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Builtin.Pseudo */
|
||||
|
||||
.highlight .fm {
|
||||
color: #a6e22e
|
||||
}
|
||||
|
||||
|
||||
/* Name.Function.Magic */
|
||||
|
||||
.highlight .vc {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Variable.Class */
|
||||
|
||||
.highlight .vg {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Variable.Global */
|
||||
|
||||
.highlight .vi {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Variable.Instance */
|
||||
|
||||
.highlight .vm {
|
||||
color: #f8f8f2
|
||||
}
|
||||
|
||||
|
||||
/* Name.Variable.Magic */
|
||||
|
||||
.highlight .il {
|
||||
color: #ae81ff
|
||||
}
|
||||
|
||||
|
||||
/* Literal.Number.Integer.Long */
|
||||
|
||||
|
||||
/* Link to Remix IDE shown over code snippets */
|
||||
a.remix-link {
|
||||
filter: invert(1); /* The icon is black. In dark mode we want it white. */
|
||||
}
|
2
docs/_static/css/fonts.css
vendored
@ -1,2 +0,0 @@
|
||||
@import url("https://fonts.cdnfonts.com/css/overpass");
|
||||
@import url("https://fonts.cdnfonts.com/css/overpass-mono");
|
399
docs/_static/css/pygments.css
vendored
@ -1,399 +0,0 @@
|
||||
pre {
|
||||
line-height: 125%;
|
||||
}
|
||||
|
||||
td.linenos .normal {
|
||||
color: inherit;
|
||||
background-color: transparent;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
span.linenos {
|
||||
color: inherit;
|
||||
background-color: transparent;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
td.linenos .special {
|
||||
color: #000000;
|
||||
background-color: #ffffc0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
span.linenos.special {
|
||||
color: #000000;
|
||||
background-color: #ffffc0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.highlight .hll {
|
||||
background-color: #ffffcc
|
||||
}
|
||||
|
||||
.highlight {
|
||||
background: #eeffcc;
|
||||
}
|
||||
|
||||
.highlight .c {
|
||||
color: #408090;
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Comment */
|
||||
.highlight .err {
|
||||
border: 1px solid #FF0000
|
||||
}
|
||||
|
||||
/* Error */
|
||||
.highlight .k {
|
||||
color: #007020;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Keyword */
|
||||
.highlight .o {
|
||||
color: #666666
|
||||
}
|
||||
|
||||
/* Operator */
|
||||
.highlight .ch {
|
||||
color: #408090;
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Comment.Hashbang */
|
||||
.highlight .cm {
|
||||
color: #408090;
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Comment.Multiline */
|
||||
.highlight .cp {
|
||||
color: #007020
|
||||
}
|
||||
|
||||
/* Comment.Preproc */
|
||||
.highlight .cpf {
|
||||
color: #408090;
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Comment.PreprocFile */
|
||||
.highlight .c1 {
|
||||
color: #408090;
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Comment.Single */
|
||||
.highlight .cs {
|
||||
color: #408090;
|
||||
background-color: #fff0f0
|
||||
}
|
||||
|
||||
/* Comment.Special */
|
||||
.highlight .gd {
|
||||
color: #A00000
|
||||
}
|
||||
|
||||
/* Generic.Deleted */
|
||||
.highlight .ge {
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Generic.Emph */
|
||||
.highlight .gr {
|
||||
color: #FF0000
|
||||
}
|
||||
|
||||
/* Generic.Error */
|
||||
.highlight .gh {
|
||||
color: #000080;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Generic.Heading */
|
||||
.highlight .gi {
|
||||
color: #00A000
|
||||
}
|
||||
|
||||
/* Generic.Inserted */
|
||||
.highlight .go {
|
||||
color: #333333
|
||||
}
|
||||
|
||||
/* Generic.Output */
|
||||
.highlight .gp {
|
||||
color: #c65d09;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Generic.Prompt */
|
||||
.highlight .gs {
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Generic.Strong */
|
||||
.highlight .gu {
|
||||
color: #800080;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Generic.Subheading */
|
||||
.highlight .gt {
|
||||
color: #0044DD
|
||||
}
|
||||
|
||||
/* Generic.Traceback */
|
||||
.highlight .kc {
|
||||
color: #007020;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Keyword.Constant */
|
||||
.highlight .kd {
|
||||
color: #007020;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Keyword.Declaration */
|
||||
.highlight .kn {
|
||||
color: #007020;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Keyword.Namespace */
|
||||
.highlight .kp {
|
||||
color: #007020
|
||||
}
|
||||
|
||||
/* Keyword.Pseudo */
|
||||
.highlight .kr {
|
||||
color: #007020;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Keyword.Reserved */
|
||||
.highlight .kt {
|
||||
color: #902000
|
||||
}
|
||||
|
||||
/* Keyword.Type */
|
||||
.highlight .m {
|
||||
color: #208050
|
||||
}
|
||||
|
||||
/* Literal.Number */
|
||||
.highlight .s {
|
||||
color: #4070a0
|
||||
}
|
||||
|
||||
/* Literal.String */
|
||||
.highlight .na {
|
||||
color: #4070a0
|
||||
}
|
||||
|
||||
/* Name.Attribute */
|
||||
.highlight .nb {
|
||||
color: #007020
|
||||
}
|
||||
|
||||
/* Name.Builtin */
|
||||
.highlight .nc {
|
||||
color: #0e84b5;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Name.Class */
|
||||
.highlight .no {
|
||||
color: #60add5
|
||||
}
|
||||
|
||||
/* Name.Constant */
|
||||
.highlight .nd {
|
||||
color: #555555;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Name.Decorator */
|
||||
.highlight .ni {
|
||||
color: #d55537;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Name.Entity */
|
||||
.highlight .ne {
|
||||
color: #007020
|
||||
}
|
||||
|
||||
/* Name.Exception */
|
||||
.highlight .nf {
|
||||
color: #06287e
|
||||
}
|
||||
|
||||
/* Name.Function */
|
||||
.highlight .nl {
|
||||
color: #002070;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Name.Label */
|
||||
.highlight .nn {
|
||||
color: #0e84b5;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Name.Namespace */
|
||||
.highlight .nt {
|
||||
color: #062873;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Name.Tag */
|
||||
.highlight .nv {
|
||||
color: #bb60d5
|
||||
}
|
||||
|
||||
/* Name.Variable */
|
||||
.highlight .ow {
|
||||
color: #007020;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Operator.Word */
|
||||
.highlight .w {
|
||||
color: #bbbbbb
|
||||
}
|
||||
|
||||
/* Text.Whitespace */
|
||||
.highlight .mb {
|
||||
color: #208050
|
||||
}
|
||||
|
||||
/* Literal.Number.Bin */
|
||||
.highlight .mf {
|
||||
color: #208050
|
||||
}
|
||||
|
||||
/* Literal.Number.Float */
|
||||
.highlight .mh {
|
||||
color: #208050
|
||||
}
|
||||
|
||||
/* Literal.Number.Hex */
|
||||
.highlight .mi {
|
||||
color: #208050
|
||||
}
|
||||
|
||||
/* Literal.Number.Integer */
|
||||
.highlight .mo {
|
||||
color: #208050
|
||||
}
|
||||
|
||||
/* Literal.Number.Oct */
|
||||
.highlight .sa {
|
||||
color: #4070a0
|
||||
}
|
||||
|
||||
/* Literal.String.Affix */
|
||||
.highlight .sb {
|
||||
color: #4070a0
|
||||
}
|
||||
|
||||
/* Literal.String.Backtick */
|
||||
.highlight .sc {
|
||||
color: #4070a0
|
||||
}
|
||||
|
||||
/* Literal.String.Char */
|
||||
.highlight .dl {
|
||||
color: #4070a0
|
||||
}
|
||||
|
||||
/* Literal.String.Delimiter */
|
||||
.highlight .sd {
|
||||
color: #4070a0;
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Literal.String.Doc */
|
||||
.highlight .s2 {
|
||||
color: #4070a0
|
||||
}
|
||||
|
||||
/* Literal.String.Double */
|
||||
.highlight .se {
|
||||
color: #4070a0;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Literal.String.Escape */
|
||||
.highlight .sh {
|
||||
color: #4070a0
|
||||
}
|
||||
|
||||
/* Literal.String.Heredoc */
|
||||
.highlight .si {
|
||||
color: #70a0d0;
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Literal.String.Interpol */
|
||||
.highlight .sx {
|
||||
color: #c65d09
|
||||
}
|
||||
|
||||
/* Literal.String.Other */
|
||||
.highlight .sr {
|
||||
color: #235388
|
||||
}
|
||||
|
||||
/* Literal.String.Regex */
|
||||
.highlight .s1 {
|
||||
color: #4070a0
|
||||
}
|
||||
|
||||
/* Literal.String.Single */
|
||||
.highlight .ss {
|
||||
color: #517918
|
||||
}
|
||||
|
||||
/* Literal.String.Symbol */
|
||||
.highlight .bp {
|
||||
color: #007020
|
||||
}
|
||||
|
||||
/* Name.Builtin.Pseudo */
|
||||
.highlight .fm {
|
||||
color: #06287e
|
||||
}
|
||||
|
||||
/* Name.Function.Magic */
|
||||
.highlight .vc {
|
||||
color: #bb60d5
|
||||
}
|
||||
|
||||
/* Name.Variable.Class */
|
||||
.highlight .vg {
|
||||
color: #bb60d5
|
||||
}
|
||||
|
||||
/* Name.Variable.Global */
|
||||
.highlight .vi {
|
||||
color: #bb60d5
|
||||
}
|
||||
|
||||
/* Name.Variable.Instance */
|
||||
.highlight .vm {
|
||||
color: #bb60d5
|
||||
}
|
||||
|
||||
/* Name.Variable.Magic */
|
||||
.highlight .il {
|
||||
color: #208050
|
||||
}
|
||||
|
||||
/* Literal.Number.Integer.Long */
|
15
docs/_static/css/toggle.css
vendored
@ -9,13 +9,6 @@ input[type=checkbox] {
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: var(--color-f);
|
||||
border-top: 1px solid var(--color-c);
|
||||
}
|
||||
|
||||
.fa-caret-down,
|
||||
.fa-book {
|
||||
color: var(--color-a) !important;
|
||||
}
|
||||
|
||||
.rst-versions .rst-current-version .fa-book,
|
||||
@ -83,6 +76,8 @@ html.transition *:after {
|
||||
transition-delay: 0 !important;
|
||||
}
|
||||
|
||||
.wy-menu-vertical a:hover {
|
||||
background-color: #0002;
|
||||
}
|
||||
nav.wy-nav-side {
|
||||
/* The default padding of 2em is too small and the "Keyword Index" link gets obscured
|
||||
* by the version toggle. */
|
||||
padding-bottom: 3em;
|
||||
}
|
||||
|
BIN
docs/_static/img/favicon.ico
vendored
Before Width: | Height: | Size: 15 KiB |
BIN
docs/_static/img/favicon.png
vendored
Before Width: | Height: | Size: 949 B |
3
docs/_static/img/hamburger-dark.svg
vendored
@ -1,3 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="#E6E3EC" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
|
||||
<path d="M 3 5 A 1.0001 1.0001 0 1 0 3 7 L 21 7 A 1.0001 1.0001 0 1 0 21 5 L 3 5 z M 3 11 A 1.0001 1.0001 0 1 0 3 13 L 21 13 A 1.0001 1.0001 0 1 0 21 11 L 3 11 z M 3 17 A 1.0001 1.0001 0 1 0 3 19 L 21 19 A 1.0001 1.0001 0 1 0 21 17 L 3 17 z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 413 B |
3
docs/_static/img/hamburger-light.svg
vendored
@ -1,3 +0,0 @@
|
||||
<svg width="24px" height="24px" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
|
||||
<path fill="#2B247C" d="M 3 5 A 1.0001 1.0001 0 1 0 3 7 L 21 7 A 1.0001 1.0001 0 1 0 21 5 L 3 5 z M 3 11 A 1.0001 1.0001 0 1 0 3 13 L 21 13 A 1.0001 1.0001 0 1 0 21 11 L 3 11 z M 3 17 A 1.0001 1.0001 0 1 0 3 19 L 21 19 A 1.0001 1.0001 0 1 0 21 17 L 3 17 z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 437 B |
8
docs/_static/img/logo-dark.svg
vendored
@ -1,8 +0,0 @@
|
||||
<svg width="100" height="160" viewBox="0 0 100 160" fill="#E6E3EC" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.8" d="M50 44.3013L25 1L0 44.3013L25 87.6025L50 44.3013Z" />
|
||||
<path opacity="0.45" d="M50 44.3091L75 1.00781L25 1.00781L0 44.3091H50Z" />
|
||||
<path opacity="0.6" d="M75 1.00781L25 1.00781L50 44.3091H100L75 1.00781Z" />
|
||||
<path opacity="0.8" d="M50 115.699L75 159L100 115.699L75 72.3975L50 115.699Z" />
|
||||
<path opacity="0.45" d="M50 115.691L25 158.993H75L100 115.691L50 115.691Z" />
|
||||
<path opacity="0.6" d="M25 158.993H75L50 115.691L0 115.691L25 158.993Z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 574 B |
8
docs/_static/img/logo.svg
vendored
@ -1,8 +0,0 @@
|
||||
<svg width="100" height="160" viewBox="0 0 100 160" fill="#2B247C" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.8" d="M50 44.3013L25 1L0 44.3013L25 87.6025L50 44.3013Z" />
|
||||
<path opacity="0.45" d="M50 44.3091L75 1.00781L25 1.00781L0 44.3091H50Z" />
|
||||
<path opacity="0.6" d="M75 1.00781L25 1.00781L50 44.3091H100L75 1.00781Z" />
|
||||
<path opacity="0.8" d="M50 115.699L75 159L100 115.699L75 72.3975L50 115.699Z" />
|
||||
<path opacity="0.45" d="M50 115.691L25 158.993H75L100 115.691L50 115.691Z" />
|
||||
<path opacity="0.6" d="M25 158.993H75L50 115.691L0 115.691L25 158.993Z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 574 B |
3
docs/_static/img/moon.svg
vendored
@ -1,3 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="#2B247C" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
|
||||
<path d="M21.4,13.7C20.6,13.9,19.8,14,19,14c-5,0-9-4-9-9c0-0.8,0.1-1.6,0.3-2.4c0.1-0.3,0-0.7-0.3-1 c-0.3-0.3-0.6-0.4-1-0.3C4.3,2.7,1,7.1,1,12c0,6.1,4.9,11,11,11c4.9,0,9.3-3.3,10.6-8.1c0.1-0.3,0-0.7-0.3-1 C22.1,13.7,21.7,13.6,21.4,13.7z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 408 B |
13
docs/_static/img/sun.svg
vendored
@ -1,13 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
|
||||
<g stroke-linejoin="round" stroke-linecap="round" stroke-width="2" fill="none" stroke="#E6E3EC">
|
||||
<circle cx="12" cy="12" r="5" />
|
||||
<path d="M12 1v2" />
|
||||
<path d="M12 21v2" />
|
||||
<path d="M4.22 4.22l1.42 1.42" />
|
||||
<path d="M18.36 18.36l1.42 1.42" />
|
||||
<path d="M1 12h2" />
|
||||
<path d="M21 12h2" />
|
||||
<path d="M4.22 19.78l1.42-1.42" />
|
||||
<path d="M18.36 5.64l1.42-1.42" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 554 B |
38
docs/_static/js/constants.js
vendored
@ -1,38 +0,0 @@
|
||||
// Site URL
|
||||
const SITE_URL = "https://docs.soliditylang.org"
|
||||
const { origin, pathname } = location;
|
||||
const pathSplit = pathname.split("/");
|
||||
const rootPath = origin.includes(SITE_URL) && pathSplit.length > 3 ? pathSplit.splice(1, 2).join("/") : ''
|
||||
const ROOT_URL = `${origin}/${rootPath}`;
|
||||
|
||||
// Color mode constants
|
||||
const [DARK, LIGHT] = ["dark", "light"];
|
||||
const LIGHT_LOGO_PATH = `${ROOT_URL}/_static/img/logo.svg`;
|
||||
const DARK_LOGO_PATH = `${ROOT_URL}/_static/img/logo-dark.svg`;
|
||||
const SUN_ICON_PATH = `${ROOT_URL}/_static/img/sun.svg`;
|
||||
const MOON_ICON_PATH = `${ROOT_URL}/_static/img/moon.svg`;
|
||||
const LIGHT_HAMBURGER_PATH = `${ROOT_URL}/_static/img/hamburger-light.svg`;
|
||||
const DARK_HAMBURGER_PATH = `${ROOT_URL}/_static/img/hamburger-dark.svg`;
|
||||
const COLOR_TOGGLE_ICON_CLASS = "color-toggle-icon";
|
||||
const SOLIDITY_LOGO_CLASS = "solidity-logo";
|
||||
const LS_COLOR_SCHEME = "color-scheme";
|
||||
|
||||
// Solidity navigation constants
|
||||
const SOLIDITY_HOME_URL = "https://soliditylang.org";
|
||||
const BLOG_URL = `${SOLIDITY_HOME_URL}/blog`;
|
||||
const DOCS_URL = "/";
|
||||
const USE_CASES_PATH = `${SOLIDITY_HOME_URL}/use-cases`;
|
||||
const CONTRIBUTE_PATH = `/en/latest/contributing.html`;
|
||||
const ABOUT_PATH = `${SOLIDITY_HOME_URL}/about`;
|
||||
const FORUM_URL = "https://forum.soliditylang.org/";
|
||||
const NAV_LINKS = [
|
||||
{ name: "Blog", href: BLOG_URL },
|
||||
{ name: "Documentation", href: DOCS_URL },
|
||||
{ name: "Use cases", href: USE_CASES_PATH },
|
||||
{ name: "Contribute", href: CONTRIBUTE_PATH },
|
||||
{ name: "About", href: ABOUT_PATH },
|
||||
{ name: "Forum", href: FORUM_URL },
|
||||
];
|
||||
|
||||
const MOBILE_MENU_TOGGLE_CLASS = "shift";
|
||||
const WRAPPER_CLASS = "unified-wrapper";
|
250
docs/_static/js/initialize.js
vendored
@ -1,250 +0,0 @@
|
||||
const getLogoSrc = (isDark) => (isDark ? DARK_LOGO_PATH : LIGHT_LOGO_PATH);
|
||||
|
||||
const getModeIconSrc = (isDark) => (isDark ? SUN_ICON_PATH : MOON_ICON_PATH);
|
||||
|
||||
const getMenuIconSrc = (isDark) =>
|
||||
isDark ? DARK_HAMBURGER_PATH : LIGHT_HAMBURGER_PATH;
|
||||
|
||||
function addFooterNote() {
|
||||
const contentInfo = document.querySelector("div[role=contentinfo]");
|
||||
const footerNote = document.createElement("p");
|
||||
footerNote.classList.add("footer-note");
|
||||
footerNote.innerHTML =
|
||||
'Customized with ❤️ by the <a href="https://ethereum.org/" target="_blank">ethereum.org</a> team.';
|
||||
contentInfo.parentNode.insertBefore(footerNote, contentInfo.nextSibling);
|
||||
}
|
||||
|
||||
function rearrangeDom() {
|
||||
const bodyDivs = document.querySelectorAll("body>div");
|
||||
bodyDivs.forEach((div) => div.remove());
|
||||
const wrapperDiv = document.createElement("div");
|
||||
wrapperDiv.classList.add(WRAPPER_CLASS);
|
||||
bodyDivs.forEach((div) => wrapperDiv.appendChild(div));
|
||||
document.body.prepend(wrapperDiv);
|
||||
|
||||
const rstVersions = document.querySelector(".rst-versions");
|
||||
rstVersions.remove();
|
||||
const wyNavSide = document.querySelector("nav.wy-nav-side");
|
||||
wyNavSide.appendChild(rstVersions);
|
||||
const backdrop = document.createElement("div");
|
||||
backdrop.classList.add("backdrop");
|
||||
wrapperDiv.appendChild(backdrop);
|
||||
|
||||
const content = document.querySelector(".wy-nav-content");
|
||||
content.id = "content";
|
||||
const oldWrap = document.querySelector("section.wy-nav-content-wrap");
|
||||
oldWrap.remove();
|
||||
document.querySelector(".wy-grid-for-nav").appendChild(content);
|
||||
}
|
||||
|
||||
function buildHeader() {
|
||||
const isDarkMode = localStorage.getItem(LS_COLOR_SCHEME) == DARK;
|
||||
|
||||
const header = document.createElement("div");
|
||||
header.classList.add("unified-header");
|
||||
document.querySelector(`.${WRAPPER_CLASS}`).prepend(header);
|
||||
|
||||
const innerHeader = document.createElement("div");
|
||||
innerHeader.classList.add("inner-header");
|
||||
header.appendChild(innerHeader);
|
||||
|
||||
const homeLink = document.createElement("a");
|
||||
homeLink.classList.add("home-link");
|
||||
homeLink.href = SOLIDITY_HOME_URL;
|
||||
homeLink.ariaLabel = "Solidity home";
|
||||
innerHeader.appendChild(homeLink);
|
||||
|
||||
const logo = document.createElement("img");
|
||||
logo.classList.add(SOLIDITY_LOGO_CLASS);
|
||||
logo.src = getLogoSrc(isDarkMode);
|
||||
logo.alt = "Solidity logo";
|
||||
homeLink.appendChild(logo);
|
||||
|
||||
const skipToContent = document.createElement("a");
|
||||
skipToContent.classList.add("skip-to-content");
|
||||
skipToContent.href = "#content";
|
||||
skipToContent.innerText = "{skip to content}";
|
||||
innerHeader.appendChild(skipToContent);
|
||||
|
||||
const navBar = document.createElement("nav");
|
||||
navBar.classList.add("nav-bar");
|
||||
innerHeader.appendChild(navBar);
|
||||
|
||||
const linkElements = NAV_LINKS.map(({ name, href }) => {
|
||||
const link = document.createElement("a");
|
||||
link.classList.add("nav-link");
|
||||
link.setAttribute("key", name);
|
||||
link.setAttribute("href", href);
|
||||
link.setAttribute("aria-label", name);
|
||||
if (href === FORUM_URL) {
|
||||
link.classList.add("forum-link");
|
||||
link.setAttribute("target", "_blank");
|
||||
link.setAttribute("rel", "noopener noreferrer");
|
||||
}
|
||||
link.innerText = name;
|
||||
return link;
|
||||
});
|
||||
linkElements.forEach((link) => navBar.appendChild(link));
|
||||
|
||||
// Flex wrapper for color mode and mobile menu buttons
|
||||
const navButtonContainer = document.createElement("div");
|
||||
navButtonContainer.classList.add("nav-button-container");
|
||||
navBar.appendChild(navButtonContainer);
|
||||
|
||||
// Build color toggle
|
||||
const toggleIcon = document.createElement("img");
|
||||
toggleIcon.classList.add(COLOR_TOGGLE_ICON_CLASS);
|
||||
toggleIcon.src = getModeIconSrc(isDarkMode);
|
||||
toggleIcon.alt = "Color mode toggle icon";
|
||||
toggleIcon.setAttribute("aria-hidden", "true");
|
||||
toggleIcon.setAttribute("key", "toggle icon");
|
||||
const colorModeButton = document.createElement("button");
|
||||
colorModeButton.classList.add("color-toggle");
|
||||
colorModeButton.setAttribute("type", "button");
|
||||
colorModeButton.setAttribute("aria-label", "Toggle light dark mode");
|
||||
colorModeButton.setAttribute("key", "color mode button");
|
||||
colorModeButton.addEventListener("click", toggleColorMode);
|
||||
colorModeButton.appendChild(toggleIcon);
|
||||
navButtonContainer.appendChild(colorModeButton);
|
||||
|
||||
// Build mobile hamburger menu
|
||||
const menuIcon = document.createElement("img");
|
||||
menuIcon.classList.add(COLOR_TOGGLE_ICON_CLASS);
|
||||
menuIcon.src = getMenuIconSrc(isDarkMode);
|
||||
menuIcon.alt = "Toggle menu";
|
||||
menuIcon.setAttribute("aria-hidden", "true");
|
||||
menuIcon.setAttribute("key", "menu icon");
|
||||
const menuButton = document.createElement("button");
|
||||
menuButton.classList.add("color-toggle");
|
||||
menuButton.classList.add("mobile-menu-button");
|
||||
menuButton.setAttribute("type", "button");
|
||||
menuButton.setAttribute("aria-label", "Toggle menu");
|
||||
menuButton.setAttribute("key", "menu button");
|
||||
menuButton.addEventListener("click", toggleMenu);
|
||||
menuButton.appendChild(menuIcon);
|
||||
navButtonContainer.appendChild(menuButton);
|
||||
}
|
||||
|
||||
const updateActiveNavLink = () => {
|
||||
const navLinks = document.querySelectorAll(".unified-header .nav-link");
|
||||
navLinks.forEach((link) => {
|
||||
const href = link.getAttribute("href");
|
||||
if (document.documentURI.includes("contributing.html")) {
|
||||
link.classList[href.includes("contributing.html") ? "add" : "remove"](
|
||||
"active"
|
||||
);
|
||||
} else {
|
||||
link.classList[document.documentURI.includes(href) ? "add" : "remove"](
|
||||
"active"
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener("locationchange", updateActiveNavLink);
|
||||
|
||||
function updateGitHubEditPath() {
|
||||
// Replaces the version number in the GitHub edit path with "develop"
|
||||
const gitHubEditAnchor = document.querySelector(".wy-breadcrumbs-aside > a");
|
||||
const url = new URL(gitHubEditAnchor.href);
|
||||
const split = url.pathname.split("/");
|
||||
const versionIndex = split.indexOf("blob") + 1;
|
||||
split[versionIndex] = "develop";
|
||||
url.pathname = split.join("/");
|
||||
gitHubEditAnchor.setAttribute("href", url.toString());
|
||||
gitHubEditAnchor.setAttribute("target", "_blank");
|
||||
gitHubEditAnchor.setAttribute("rel", "noopener noreferrer");
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
// Rearrange DOM elements for styling
|
||||
rearrangeDom();
|
||||
|
||||
// Check localStorage for existing color scheme preference
|
||||
var prefersDark = localStorage.getItem(LS_COLOR_SCHEME) == DARK;
|
||||
// Check link for search param "color"... it may be "light" or "dark"
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.size > 0) {
|
||||
// This is used for color mode continuity between the main Solidity Lang site and the docs
|
||||
var colorSchemeParam = urlParams.get("color");
|
||||
// If present, overwrite prefersDark accordingly
|
||||
if (colorSchemeParam) {
|
||||
prefersDark = colorSchemeParam == DARK;
|
||||
}
|
||||
|
||||
// Remove "color" search param from URL
|
||||
const { location, title } = document;
|
||||
const { pathname, origin, search, hash } = location;
|
||||
const newSearchParams = new URLSearchParams(search);
|
||||
newSearchParams.delete("color");
|
||||
const sanitizedSearch =
|
||||
newSearchParams.size < 1 ? "" : "?" + newSearchParams.toString();
|
||||
window.history.replaceState(
|
||||
origin,
|
||||
title,
|
||||
pathname + sanitizedSearch + hash
|
||||
);
|
||||
}
|
||||
|
||||
// In case none existed, establish localStorage color scheme preference
|
||||
var mode = prefersDark ? DARK : LIGHT;
|
||||
localStorage.setItem(LS_COLOR_SCHEME, mode);
|
||||
|
||||
// Select the root element and set the style attribute to denote color-scheme attribute
|
||||
document
|
||||
.querySelector(":root")
|
||||
.setAttribute("style", `--color-scheme: ${mode}`);
|
||||
|
||||
// Remove old input and RTD logo anchor element
|
||||
document.querySelector("input[name=mode]").remove();
|
||||
document.querySelector("label[for=switch]").remove();
|
||||
document.querySelector(".wy-side-nav-search > a").remove();
|
||||
|
||||
// Add footer note
|
||||
addFooterNote();
|
||||
|
||||
// Build header
|
||||
buildHeader();
|
||||
|
||||
// Close menu
|
||||
toggleMenu({ force: false });
|
||||
|
||||
// Update active nav link
|
||||
updateActiveNavLink();
|
||||
|
||||
// Update GitHub edit path to direct to `develop` branch
|
||||
updateGitHubEditPath();
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", initialize);
|
||||
|
||||
const handleClick = (e) => {
|
||||
if (e.target.closest(".backdrop")) {
|
||||
toggleMenu({ force: false });
|
||||
}
|
||||
|
||||
if (e.target.closest("a")) {
|
||||
const target = e.target.closest("a");
|
||||
const href = target.getAttribute("href");
|
||||
if (href.includes(SOLIDITY_HOME_URL)) {
|
||||
const url = new URL(href);
|
||||
const params = new URLSearchParams(url.search);
|
||||
params.set("color", localStorage.getItem(LS_COLOR_SCHEME));
|
||||
url.search = params.toString();
|
||||
target.setAttribute("href", url.toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
document.addEventListener("click", handleClick);
|
||||
|
||||
const handleKeyDown = (e) => {
|
||||
if (e.metaKey && e.key === "k") {
|
||||
document.querySelector("#rtd-search-form input").focus();
|
||||
} else if (e.key === "Escape") {
|
||||
toggleMenu({ force: false });
|
||||
}
|
||||
if (e.metaKey && e.code === "Backslash") {
|
||||
toggleColorMode();
|
||||
}
|
||||
};
|
||||
document.addEventListener("keydown", handleKeyDown);
|
77
docs/_static/js/toggle.js
vendored
@ -1,47 +1,38 @@
|
||||
function toggleColorMode() {
|
||||
// Check localStorage for previous color scheme preference, assign the opposite
|
||||
var newMode = localStorage.getItem(LS_COLOR_SCHEME) == DARK ? LIGHT : DARK;
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
// Update localStorage with new color scheme preference
|
||||
localStorage.setItem(LS_COLOR_SCHEME, newMode);
|
||||
function toggleCssMode(isDay) {
|
||||
var mode = (isDay ? "Day" : "Night");
|
||||
localStorage.setItem("css-mode", mode);
|
||||
|
||||
// Update the root element with the new color scheme preference
|
||||
document
|
||||
.querySelector(":root")
|
||||
.setAttribute("style", `--color-scheme: ${newMode}`);
|
||||
var daysheet = $('link[href="_static/pygments.css"]')[0].sheet;
|
||||
daysheet.disabled = !isDay;
|
||||
|
||||
// Update logo
|
||||
document
|
||||
.querySelector(`img.${SOLIDITY_LOGO_CLASS}`)
|
||||
.setAttribute("src", newMode === LIGHT ? LIGHT_LOGO_PATH : DARK_LOGO_PATH);
|
||||
|
||||
// Update color mode toggle icon
|
||||
document
|
||||
.querySelector(`img.${COLOR_TOGGLE_ICON_CLASS}`)
|
||||
.setAttribute("src", newMode === LIGHT ? MOON_ICON_PATH : SUN_ICON_PATH);
|
||||
|
||||
// Update hamburger menu icon color
|
||||
document
|
||||
.querySelector("button.mobile-menu-button img")
|
||||
.setAttribute(
|
||||
"src",
|
||||
newMode === LIGHT ? LIGHT_HAMBURGER_PATH : DARK_HAMBURGER_PATH
|
||||
);
|
||||
}
|
||||
|
||||
function toggleMenu(options = {}) {
|
||||
const handleClassToggle = ({ classList }, className) => {
|
||||
if (typeof options.force !== "undefined") {
|
||||
classList.toggle(className, options.force);
|
||||
} else {
|
||||
classList.toggle(className);
|
||||
var nightsheet = $('link[href="_static/css/dark.css"]')[0];
|
||||
if (!isDay && nightsheet === undefined) {
|
||||
var element = document.createElement("link");
|
||||
element.setAttribute("rel", "stylesheet");
|
||||
element.setAttribute("type", "text/css");
|
||||
element.setAttribute("href", "_static/css/dark.css");
|
||||
document.getElementsByTagName("head")[0].appendChild(element);
|
||||
return;
|
||||
}
|
||||
if (nightsheet !== undefined) {
|
||||
nightsheet.sheet.disabled = isDay;
|
||||
}
|
||||
}
|
||||
};
|
||||
document
|
||||
.querySelectorAll('[data-toggle="rst-versions"]')
|
||||
.forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS));
|
||||
document
|
||||
.querySelectorAll('[data-toggle="wy-nav-shift"]')
|
||||
.forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS));
|
||||
handleClassToggle(document.querySelector(`.${WRAPPER_CLASS}`), "menu-open");
|
||||
}
|
||||
|
||||
var initial = localStorage.getItem("css-mode") != "Night";
|
||||
var checkbox = document.querySelector('input[name=mode]');
|
||||
|
||||
toggleCssMode(initial);
|
||||
checkbox.checked = initial;
|
||||
|
||||
checkbox.addEventListener('change', function() {
|
||||
document.documentElement.classList.add('transition');
|
||||
window.setTimeout(() => {
|
||||
document.documentElement.classList.remove('transition');
|
||||
}, 1000)
|
||||
toggleCssMode(this.checked);
|
||||
})
|
||||
|
||||
});
|
@ -13,13 +13,13 @@ The Contract Application Binary Interface (ABI) is the standard way to interact
|
||||
from outside the blockchain and for contract-to-contract interaction. Data is encoded according to its type,
|
||||
as described in this specification. The encoding is not self describing and thus requires a schema in order to decode.
|
||||
|
||||
We assume that the interface functions of a contract are strongly typed, known at compilation time and static.
|
||||
We assume 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
|
||||
.. index:: selector
|
||||
|
||||
Function Selector
|
||||
=================
|
||||
@ -29,7 +29,7 @@ first (left, high-order in big-endian) four bytes of the Keccak-256 hash of the
|
||||
the function. The signature is defined as the canonical expression of the basic prototype without data
|
||||
location specifier, i.e.
|
||||
the function name with the parenthesised list of parameter types. Parameter types are split by a single
|
||||
comma — no spaces are used.
|
||||
comma - no spaces are used.
|
||||
|
||||
.. note::
|
||||
The return type of a function is not part of this signature. In
|
||||
@ -133,7 +133,7 @@ The encoding is designed to have the following properties, which are especially
|
||||
previous version of the ABI, the number of reads scaled linearly with the total number of dynamic
|
||||
parameters in the worst case.
|
||||
|
||||
2. The data of a variable or an array element is not interleaved with other data and it is
|
||||
2. The data of a variable or array element is not interleaved with other data and it is
|
||||
relocatable, i.e. it only uses relative "addresses".
|
||||
|
||||
|
||||
@ -191,9 +191,9 @@ on the type of ``X`` being
|
||||
|
||||
- ``T[]`` where ``X`` has ``k`` elements (``k`` is assumed to be of type ``uint256``):
|
||||
|
||||
``enc(X) = enc(k) enc((X[0], ..., X[k-1]))``
|
||||
``enc(X) = enc(k) enc([X[0], ..., X[k-1]])``
|
||||
|
||||
i.e. it is encoded as if it were a tuple with ``k`` elements of the same type (resp. an array of static size ``k``), prefixed with
|
||||
i.e. it is encoded as if it were an array of static size ``k``, prefixed with
|
||||
the number of elements.
|
||||
|
||||
- ``bytes``, of length ``k`` (which is assumed to be of type ``uint256``):
|
||||
@ -252,7 +252,7 @@ Given the contract:
|
||||
}
|
||||
|
||||
|
||||
Thus, for our ``Foo`` example if we wanted to call ``baz`` with the parameters ``69`` and
|
||||
Thus for our ``Foo`` example if we wanted to call ``baz`` with the parameters ``69`` and
|
||||
``true``, we would pass 68 bytes total, which can be broken down into:
|
||||
|
||||
- ``0xcdcd77c0``: the Method ID. This is derived as the first 4 bytes of the Keccak hash of
|
||||
@ -308,10 +308,10 @@ In total:
|
||||
Use of Dynamic Types
|
||||
====================
|
||||
|
||||
A call to a function with the signature ``f(uint256,uint32[],bytes10,bytes)`` with values
|
||||
A call to a function with the signature ``f(uint,uint32[],bytes10,bytes)`` with values
|
||||
``(0x123, [0x456, 0x789], "1234567890", "Hello, world!")`` is encoded in the following way:
|
||||
|
||||
We take the first four bytes of ``keccak("f(uint256,uint32[],bytes10,bytes)")``, i.e. ``0x8be65246``.
|
||||
We take the first four bytes of ``sha3("f(uint256,uint32[],bytes10,bytes)")``, i.e. ``0x8be65246``.
|
||||
Then we encode the head parts of all four arguments. For the static types ``uint256`` and ``bytes10``,
|
||||
these are directly the values we want to pass, whereas for the dynamic types ``uint32[]`` and ``bytes``,
|
||||
we use the offset in bytes to the start of their data area, measured from the start of the value
|
||||
@ -348,7 +348,7 @@ All together, the encoding is (newline after function selector and each 32-bytes
|
||||
000000000000000000000000000000000000000000000000000000000000000d
|
||||
48656c6c6f2c20776f726c642100000000000000000000000000000000000000
|
||||
|
||||
Let us apply the same principle to encode the data for a function with a signature ``g(uint256[][],string[])``
|
||||
Let us apply the same principle to encode the data for a function with a signature ``g(uint[][],string[])``
|
||||
with values ``([[1, 2], [3]], ["one", "two", "three"])`` but start from the most atomic parts of the encoding:
|
||||
|
||||
First we encode the length and data of the first embedded dynamic array ``[1, 2]`` of the first root array ``[[1, 2], [3]]``:
|
||||
@ -417,7 +417,7 @@ thus ``e = 0x00000000000000000000000000000000000000000000000000000000000000e0``.
|
||||
|
||||
|
||||
Note that the encodings of the embedded elements of the root arrays are not dependent on each other
|
||||
and have the same encodings for a function with a signature ``g(string[],uint256[][])``.
|
||||
and have the same encodings for a function with a signature ``g(string[],uint[][])``.
|
||||
|
||||
Then we encode the length of the first root array:
|
||||
|
||||
@ -503,7 +503,6 @@ efficient search and arbitrary legibility by defining events with two arguments
|
||||
indexed, one not — intended to hold the same value.
|
||||
|
||||
.. _abi_errors:
|
||||
.. index:: error, selector; of an error
|
||||
|
||||
Errors
|
||||
======
|
||||
@ -563,7 +562,7 @@ A function description is a JSON object with the fields:
|
||||
blockchain state <pure-functions>`), ``view`` (:ref:`specified to not modify the blockchain
|
||||
state <view-functions>`), ``nonpayable`` (function does not accept Ether - the default) and ``payable`` (function accepts Ether).
|
||||
|
||||
Constructor, receive, and fallback never have ``name`` or ``outputs``. Receive and fallback do not have ``inputs`` either.
|
||||
Constructor and fallback function never have ``name`` or ``outputs``. Fallback function doesn't have ``inputs`` either.
|
||||
|
||||
.. note::
|
||||
Sending non-zero Ether to non-payable function will revert the transaction.
|
||||
@ -581,7 +580,7 @@ An event description is a JSON object with fairly similar fields:
|
||||
* ``name``: the name of the parameter.
|
||||
* ``type``: the canonical type of the parameter (more below).
|
||||
* ``components``: used for tuple types (more below).
|
||||
* ``indexed``: ``true`` if the field is part of the log's topics, ``false`` if it is one of the log's data segments.
|
||||
* ``indexed``: ``true`` if the field is part of the log's topics, ``false`` if it one of the log's data segment.
|
||||
|
||||
- ``anonymous``: ``true`` if the event was declared as ``anonymous``.
|
||||
|
||||
@ -597,7 +596,7 @@ Errors look as follows:
|
||||
|
||||
.. note::
|
||||
There can be multiple errors with the same name and even with identical signature
|
||||
in the JSON array; for example, if the errors originate from different
|
||||
in the JSON array, for example if the errors originate from different
|
||||
files in the smart contract or are referenced from another smart contract.
|
||||
For the ABI, only the name of the error itself is relevant and not where it is
|
||||
defined.
|
||||
@ -646,7 +645,7 @@ would result in the JSON:
|
||||
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
|
||||
Despite that names are intentionally not part of the ABI encoding they do make a lot of sense to be included
|
||||
in the JSON to enable displaying it to the end user. The structure is nested in the following way:
|
||||
|
||||
An object with members ``name``, ``type`` and potentially ``components`` describes a typed variable.
|
||||
@ -654,7 +653,7 @@ The canonical type is determined until a tuple type is reached and the string de
|
||||
to that point is stored in ``type`` prefix with the word ``tuple``, i.e. it will be ``tuple`` followed by
|
||||
a sequence of ``[]`` and ``[k]`` with
|
||||
integers ``k``. The components of the tuple are then stored in the member ``components``,
|
||||
which is of an array type and has the same structure as the top-level object except that
|
||||
which is of array type and has the same structure as the top-level object except that
|
||||
``indexed`` is not allowed there.
|
||||
|
||||
As an example, the code
|
||||
@ -738,10 +737,10 @@ Strict Encoding Mode
|
||||
====================
|
||||
|
||||
Strict encoding mode is the mode that leads to exactly the same encoding as defined in the formal specification above.
|
||||
This means that offsets have to be as small as possible while still not creating overlaps in the data areas, and thus no gaps are
|
||||
This means 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
|
||||
Usually, ABI decoders are written in a straightforward way 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.
|
||||
|
||||
@ -777,7 +776,7 @@ More specifically:
|
||||
encoding of its elements **with** padding.
|
||||
- Dynamically-sized types like ``string``, ``bytes`` or ``uint[]`` are encoded
|
||||
without their length field.
|
||||
- The encoding of ``string`` or ``bytes`` does not apply padding at the end,
|
||||
- The encoding of ``string`` or ``bytes`` does not apply padding at the end
|
||||
unless it is part of an array or struct (then it is padded to a multiple of
|
||||
32 bytes).
|
||||
|
||||
@ -805,7 +804,7 @@ Encoding of Indexed Event Parameters
|
||||
====================================
|
||||
|
||||
Indexed event parameters that are not value types, i.e. arrays and structs are not
|
||||
stored directly but instead a Keccak-256 hash of an encoding is stored. This encoding
|
||||
stored directly but instead a keccak256-hash of an encoding is stored. This encoding
|
||||
is defined as follows:
|
||||
|
||||
- the encoding of a ``bytes`` and ``string`` value is just the string contents
|
||||
|
@ -11,7 +11,7 @@ visual diff of the assembly before and after a change is often very enlightening
|
||||
|
||||
Consider the following contract (named, say ``contract.sol``):
|
||||
|
||||
.. code-block:: solidity
|
||||
.. code-block:: Solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.9.0;
|
||||
|
@ -8,7 +8,7 @@ Inline Assembly
|
||||
|
||||
|
||||
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,
|
||||
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.
|
||||
|
||||
The language used for inline assembly in Solidity is called :ref:`Yul <yul>`
|
||||
@ -45,19 +45,19 @@ Solidity language without a compiler change.
|
||||
pragma solidity >=0.4.16 <0.9.0;
|
||||
|
||||
library GetCode {
|
||||
function at(address addr) public view returns (bytes memory code) {
|
||||
function at(address _addr) public view returns (bytes memory o_code) {
|
||||
assembly {
|
||||
// retrieve the size of the code, this needs assembly
|
||||
let size := extcodesize(addr)
|
||||
let size := extcodesize(_addr)
|
||||
// allocate output byte array - this could also be done without assembly
|
||||
// by using code = new bytes(size)
|
||||
code := mload(0x40)
|
||||
// by using o_code = new bytes(size)
|
||||
o_code := mload(0x40)
|
||||
// new "memory end" including padding
|
||||
mstore(0x40, add(code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
|
||||
mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
|
||||
// store length in memory
|
||||
mstore(code, size)
|
||||
mstore(o_code, size)
|
||||
// actually retrieve the code, this needs assembly
|
||||
extcodecopy(addr, add(code, 0x20), 0, size)
|
||||
extcodecopy(_addr, add(o_code, 0x20), 0, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,49 +74,49 @@ 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];
|
||||
function sumSolidity(uint[] memory _data) public pure returns (uint sum) {
|
||||
for (uint i = 0; i < _data.length; ++i)
|
||||
sum += _data[i];
|
||||
}
|
||||
|
||||
// We know that we only access the array in bounds, so we can avoid the check.
|
||||
// 0x20 needs to be added to an array because the first slot contains the
|
||||
// array length.
|
||||
function sumAsm(uint[] memory data) public pure returns (uint sum) {
|
||||
for (uint i = 0; i < data.length; ++i) {
|
||||
function sumAsm(uint[] memory _data) public pure returns (uint sum) {
|
||||
for (uint i = 0; i < _data.length; ++i) {
|
||||
assembly {
|
||||
sum := add(sum, mload(add(add(data, 0x20), mul(i, 0x20))))
|
||||
sum := add(sum, mload(add(add(_data, 0x20), mul(i, 0x20))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Same as above, but accomplish the entire code within inline assembly.
|
||||
function sumPureAsm(uint[] memory data) public pure returns (uint sum) {
|
||||
function sumPureAsm(uint[] memory _data) public pure returns (uint sum) {
|
||||
assembly {
|
||||
// Load the length (first 32 bytes)
|
||||
let len := mload(data)
|
||||
let len := mload(_data)
|
||||
|
||||
// Skip over the length field.
|
||||
//
|
||||
// Keep temporary variable so it can be incremented in place.
|
||||
//
|
||||
// NOTE: incrementing data would result in an unusable
|
||||
// data variable after this assembly block
|
||||
let dataElementLocation := add(data, 0x20)
|
||||
// NOTE: incrementing _data would result in an unusable
|
||||
// _data variable after this assembly block
|
||||
let data := add(_data, 0x20)
|
||||
|
||||
// Iterate until the bound is not met.
|
||||
for
|
||||
{ let end := add(dataElementLocation, mul(len, 0x20)) }
|
||||
lt(dataElementLocation, end)
|
||||
{ dataElementLocation := add(dataElementLocation, 0x20) }
|
||||
{ let end := add(data, mul(len, 0x20)) }
|
||||
lt(data, end)
|
||||
{ data := add(data, 0x20) }
|
||||
{
|
||||
sum := add(sum, mload(dataElementLocation))
|
||||
sum := add(sum, mload(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.. index:: selector; of a function
|
||||
|
||||
|
||||
Access to External Variables, Functions and Libraries
|
||||
-----------------------------------------------------
|
||||
@ -126,20 +126,20 @@ You can access Solidity variables and other identifiers by using their name.
|
||||
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.
|
||||
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 <conventions-in-solidity>`.
|
||||
|
||||
Similarly, local variables that refer to statically-sized calldata arrays or calldata structs
|
||||
evaluate to the address of the variable in calldata, not the value itself.
|
||||
The variable can also be assigned a new offset, but note that no validation is performed to ensure that
|
||||
the variable will not point beyond ``calldatasize()``.
|
||||
The variable can also be assigned a new offset, but note that no validation to ensure that
|
||||
the variable will not point beyond ``calldatasize()`` is performed.
|
||||
|
||||
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:
|
||||
Both values are can be assigned to. For example:
|
||||
|
||||
.. code-block:: solidity
|
||||
:force:
|
||||
@ -205,7 +205,7 @@ Local Solidity variables are available for assignments, for example:
|
||||
``assembly { signextend(<num_bytes_of_x_minus_one>, x) }``
|
||||
|
||||
|
||||
Since Solidity 0.6.0, the name of a inline assembly variable may not
|
||||
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).
|
||||
|
||||
@ -228,11 +228,6 @@ of their block is reached.
|
||||
Conventions in 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
|
||||
@ -242,18 +237,13 @@ This means that if you access such a variable
|
||||
from within inline assembly, you might have to manually clean the higher-order bits
|
||||
first.
|
||||
|
||||
.. _assembly-memory-management:
|
||||
|
||||
Memory Management
|
||||
=================
|
||||
|
||||
Solidity manages memory in the following way. There is a "free memory pointer"
|
||||
at position ``0x40`` in memory. If you want to allocate memory, use the memory
|
||||
starting from where this pointer points at and update it.
|
||||
There is no guarantee that the memory has not been used before and thus
|
||||
you cannot assume that its contents are zero bytes.
|
||||
There is no built-in mechanism to release or free allocated memory.
|
||||
Here is an assembly snippet you can use for allocating memory that follows the process outlined above:
|
||||
Here is an assembly snippet you can use for allocating memory that follows the process outlined above
|
||||
|
||||
.. code-block:: yul
|
||||
|
||||
@ -276,103 +266,5 @@ 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,
|
||||
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 <ir-breaking-changes>`:
|
||||
this code generation path can move local variables from stack to memory to avoid stack-too-deep errors and
|
||||
perform additional memory optimizations, if it can rely on certain assumptions about memory use.
|
||||
|
||||
While we recommend to always respect Solidity's memory model, inline assembly allows you to use memory
|
||||
in an incompatible way. Therefore, moving stack variables to memory and additional memory optimizations are,
|
||||
by default, globally disabled in the presence of any inline assembly block that contains a memory operation
|
||||
or assigns to Solidity variables in memory.
|
||||
|
||||
However, you can specifically annotate an assembly block to indicate that it in fact respects Solidity's memory
|
||||
model as follows:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
assembly ("memory-safe") {
|
||||
...
|
||||
}
|
||||
|
||||
In particular, a memory-safe assembly block may only access the following memory ranges:
|
||||
|
||||
- Memory allocated by yourself using a mechanism like the ``allocate`` function described above.
|
||||
- Memory allocated by Solidity, e.g. memory within the bounds of a memory array you reference.
|
||||
- The scratch space between memory offset 0 and 64 mentioned above.
|
||||
- Temporary memory that is located *after* the value of the free memory pointer at the beginning of the assembly block,
|
||||
i.e. memory that is "allocated" at the free memory pointer without updating the free memory pointer.
|
||||
|
||||
Furthermore, if the assembly block assigns to Solidity variables in memory, you need to assure that accesses to
|
||||
the Solidity variables only access these memory ranges.
|
||||
|
||||
Since this is mainly about the optimizer, these restrictions still need to be followed, even if the assembly block
|
||||
reverts or terminates. As an example, the following assembly snippet is not memory safe, because the value of
|
||||
``returndatasize()`` may exceed the 64 byte scratch space:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
assembly {
|
||||
returndatacopy(0, 0, returndatasize())
|
||||
revert(0, returndatasize())
|
||||
}
|
||||
|
||||
On the other hand, the following code *is* memory safe, because memory beyond the location pointed to by the
|
||||
free memory pointer can safely be used as temporary scratch space:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
assembly ("memory-safe") {
|
||||
let p := mload(0x40)
|
||||
returndatacopy(p, 0, returndatasize())
|
||||
revert(p, returndatasize())
|
||||
}
|
||||
|
||||
Note that you do not need to update the free memory pointer if there is no following allocation,
|
||||
but you can only use memory starting from the current offset given by the free memory pointer.
|
||||
|
||||
If the memory operations use a length of zero, it is also fine to just use any offset (not only if it falls into the scratch space):
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
assembly ("memory-safe") {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
Note that not only memory operations in inline assembly itself can be memory-unsafe, but also assignments to
|
||||
Solidity variables of reference type in memory. For example the following is not memory-safe:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
bytes memory x;
|
||||
assembly {
|
||||
x := 0x40
|
||||
}
|
||||
x[0x20] = 0x42;
|
||||
|
||||
Inline assembly that neither involves any operations that access memory nor assigns to any Solidity variables
|
||||
in memory is automatically considered memory-safe and does not need to be annotated.
|
||||
|
||||
.. warning::
|
||||
It is your responsibility to make sure that the assembly actually satisfies the memory model. If you annotate
|
||||
an assembly block as memory-safe, but violate one of the memory assumptions, this **will** lead to incorrect and
|
||||
undefined behavior that cannot easily be discovered by testing.
|
||||
|
||||
In case you are developing a library that is meant to be compatible across multiple versions
|
||||
of Solidity, you can use a special comment to annotate an assembly block as memory-safe:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
...
|
||||
}
|
||||
|
||||
Note that we will disallow the annotation via comment in a future breaking release; so, if you are not concerned with
|
||||
backward-compatibility with older compiler versions, prefer using the dialect string.
|
||||
|
@ -67,7 +67,7 @@ When using the Solidity logo, please respect the Solidity logo guidelines.
|
||||
Solidity Logo Guidelines
|
||||
========================
|
||||
|
||||
.. image:: solidity_logo.svg
|
||||
.. image:: logo.svg
|
||||
:width: 256
|
||||
|
||||
*(Right click on the logo to download it.)*
|
||||
|
107
docs/bugs.json
@ -1,110 +1,4 @@
|
||||
[
|
||||
{
|
||||
"uid": "SOL-2023-2",
|
||||
"name": "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"summary": "Optimizer sequences containing FullInliner do not preserve the evaluation order of arguments of inlined function calls in code that is not in expression-split form.",
|
||||
"description": "Function call arguments in Yul are evaluated right to left. This order matters when the argument expressions have side-effects, and changing it may change contract behavior. FullInliner is an optimizer step that can replace a function call with the body of that function. The transformation involves assigning argument expressions to temporary variables, which imposes an explicit evaluation order. FullInliner was written with the assumption that this order does not necessarily have to match usual argument evaluation order because the argument expressions have no side-effects. In most circumstances this assumption is true because the default optimization step sequence contains the ExpressionSplitter step. ExpressionSplitter ensures that the code is in *expression-split form*, which means that function calls cannot appear nested inside expressions, and all function call arguments have to be variables. The assumption is, however, not guaranteed to be true in general. Version 0.6.7 introduced a setting allowing users to specify an arbitrary optimization step sequence, making it possible for the FullInliner to actually encounter argument expressions with side-effects, which can result in behavior differences between optimized and unoptimized bytecode. Contracts compiled without optimization or with the default optimization sequence are not affected. To trigger the bug the user has to explicitly choose compiler settings that contain a sequence with FullInliner step not preceded by ExpressionSplitter.",
|
||||
"link": "https://blog.soliditylang.org/2023/07/19/full-inliner-non-expression-split-argument-evaluation-order-bug/",
|
||||
"introduced": "0.6.7",
|
||||
"fixed": "0.8.21",
|
||||
"severity": "low",
|
||||
"conditions": {
|
||||
"yulOptimizer": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2023-1",
|
||||
"name": "MissingSideEffectsOnSelectorAccess",
|
||||
"summary": "Accessing the ``.selector`` member on complex expressions leaves the expression unevaluated in the legacy code generation.",
|
||||
"description": "When accessing the ``.selector`` member on an expression with side-effects, like an assignment, a function call or a conditional, the expression would not be evaluated in the legacy code generation. This would happen in expressions where the functions used in the expression were all known at compilation time, regardless of whether the whole expression could be evaluated at compilation time or not. Note that the code generated by the IR pipeline was unaffected and would behave as expected.",
|
||||
"link": "https://blog.soliditylang.org/2023/07/19/missing-side-effects-on-selector-access-bug/",
|
||||
"introduced": "0.6.2",
|
||||
"fixed": "0.8.21",
|
||||
"severity": "low",
|
||||
"conditions": {
|
||||
"viaIR": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2022-7",
|
||||
"name": "StorageWriteRemovalBeforeConditionalTermination",
|
||||
"summary": "Calling functions that conditionally terminate the external EVM call using the assembly statements ``return(...)`` or ``stop()`` may result in incorrect removals of prior storage writes.",
|
||||
"description": "A call to a Yul function that conditionally terminates the external EVM call could result in prior storage writes being incorrectly removed by the Yul optimizer. This used to happen in cases in which it would have been valid to remove the store, if the Yul function in question never actually terminated the external call, and the control flow always returned back to the caller instead. Conditional termination within the same Yul block instead of within a called function was not affected. In Solidity with optimized via-IR code generation, any storage write before a function conditionally calling ``return(...)`` or ``stop()`` in inline assembly, may have been incorrectly removed, whenever it would have been valid to remove the write without the ``return(...)`` or ``stop()``. In optimized legacy code generation, only inline assembly that did not refer to any Solidity variables and that involved conditionally-terminating user-defined assembly functions could be affected.",
|
||||
"link": "https://blog.soliditylang.org/2022/09/08/storage-write-removal-before-conditional-termination/",
|
||||
"introduced": "0.8.13",
|
||||
"fixed": "0.8.17",
|
||||
"severity": "medium/high",
|
||||
"conditions": {
|
||||
"yulOptimizer": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2022-6",
|
||||
"name": "AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"summary": "ABI-encoding a tuple with a statically-sized calldata array in the last component would corrupt 32 leading bytes of its first dynamically encoded component.",
|
||||
"description": "When ABI-encoding a statically-sized calldata array, the compiler always pads the data area to a multiple of 32-bytes and ensures that the padding bytes are zeroed. In some cases, this cleanup used to be performed by always writing exactly 32 bytes, regardless of how many needed to be zeroed. This was done with the assumption that the data that would eventually occupy the area past the end of the array had not yet been written, because the encoder processes tuple components in the order they were given. While this assumption is mostly true, there is an important corner case: dynamically encoded tuple components are stored separately from the statically-sized ones in an area called the *tail* of the encoding and the tail immediately follows the *head*, which is where the statically-sized components are placed. The aforementioned cleanup, if performed for the last component of the head would cross into the tail and overwrite up to 32 bytes of the first component stored there with zeros. The only array type for which the cleanup could actually result in an overwrite were arrays with ``uint256`` or ``bytes32`` as the base element type and in this case the size of the corrupted area was always exactly 32 bytes. The problem affected tuples at any nesting level. This included also structs, which are encoded as tuples in the ABI. Note also that lists of parameters and return values of functions, events and errors are encoded as tuples.",
|
||||
"link": "https://blog.soliditylang.org/2022/08/08/calldata-tuple-reencoding-head-overflow-bug/",
|
||||
"introduced": "0.5.8",
|
||||
"fixed": "0.8.16",
|
||||
"severity": "medium",
|
||||
"conditions": {
|
||||
"ABIEncoderV2": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2022-5",
|
||||
"name": "DirtyBytesArrayToStorage",
|
||||
"summary": "Copying ``bytes`` arrays from memory or calldata to storage may result in dirty storage values.",
|
||||
"description": "Copying ``bytes`` arrays from memory or calldata to storage is done in chunks of 32 bytes even if the length is not a multiple of 32. Thereby, extra bytes past the end of the array may be copied from calldata or memory to storage. These dirty bytes may then become observable after a ``.push()`` without arguments to the bytes array in storage, i.e. such a push will not result in a zero value at the end of the array as expected. This bug only affects the legacy code generation pipeline, the new code generation pipeline via IR is not affected.",
|
||||
"link": "https://blog.soliditylang.org/2022/06/15/dirty-bytes-array-to-storage-bug/",
|
||||
"introduced": "0.0.1",
|
||||
"fixed": "0.8.15",
|
||||
"severity": "low"
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2022-4",
|
||||
"name": "InlineAssemblyMemorySideEffects",
|
||||
"summary": "The Yul optimizer may incorrectly remove memory writes from inline assembly blocks, that do not access solidity variables.",
|
||||
"description": "The Yul optimizer considers all memory writes in the outermost Yul block that are never read from as unused and removes them. This is valid when that Yul block is the entire Yul program, which is always the case for the Yul code generated by the new via-IR pipeline. Inline assembly blocks are never optimized in isolation when using that pipeline. Instead they are optimized as a part of the whole Yul input. However, the legacy code generation pipeline (which is still the default) runs the Yul optimizer individually on an inline assembly block if the block does not refer to any local variables defined in the surrounding Solidity code. Consequently, memory writes in such inline assembly blocks are removed as well, if the written memory is never read from in the same assembly block, even if the written memory is accessed later, for example by a subsequent inline assembly block.",
|
||||
"link": "https://blog.soliditylang.org/2022/06/15/inline-assembly-memory-side-effects-bug/",
|
||||
"introduced": "0.8.13",
|
||||
"fixed": "0.8.15",
|
||||
"severity": "medium",
|
||||
"conditions": {
|
||||
"yulOptimizer": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2022-3",
|
||||
"name": "DataLocationChangeInInternalOverride",
|
||||
"summary": "It was possible to change the data location of the parameters or return variables from ``calldata`` to ``memory`` and vice-versa while overriding internal and public functions. This caused invalid code to be generated when calling such a function internally through virtual function calls.",
|
||||
"description": "When calling external functions, it is irrelevant if the data location of the parameters is ``calldata`` or ``memory``, the encoding of the data does not change. Because of that, changing the data location when overriding external functions is allowed. The compiler incorrectly also allowed a change in the data location for overriding public and internal functions. Since public functions can be called internally as well as externally, this causes invalid code to be generated when such an incorrectly overridden function is called internally through the base contract. The caller provides a memory pointer, but the called function interprets it as a calldata pointer or vice-versa.",
|
||||
"link": "https://blog.soliditylang.org/2022/05/17/data-location-inheritance-bug/",
|
||||
"introduced": "0.6.9",
|
||||
"fixed": "0.8.14",
|
||||
"severity": "very low"
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2022-2",
|
||||
"name": "NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"summary": "ABI-reencoding of nested dynamic calldata arrays did not always perform proper size checks against the size of calldata and could read beyond ``calldatasize()``.",
|
||||
"description": "Calldata validation for nested dynamic types is deferred until the first access to the nested values. Such an access may for example be a copy to memory or an index or member access to the outer type. While in most such accesses calldata validation correctly checks that the data area of the nested array is completely contained in the passed calldata (i.e. in the range [0, calldatasize()]), this check may not be performed, when ABI encoding such nested types again directly from calldata. For instance, this can happen, if a value in calldata with a nested dynamic array is passed to an external call, used in ``abi.encode`` or emitted as event. In such cases, if the data area of the nested array extends beyond ``calldatasize()``, ABI encoding it did not revert, but continued reading values from beyond ``calldatasize()`` (i.e. zero values).",
|
||||
"link": "https://blog.soliditylang.org/2022/05/17/calldata-reencode-size-check-bug/",
|
||||
"introduced": "0.5.8",
|
||||
"fixed": "0.8.14",
|
||||
"severity": "very low"
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2022-1",
|
||||
"name": "AbiEncodeCallLiteralAsFixedBytesBug",
|
||||
"summary": "Literals used for a fixed length bytes parameter in ``abi.encodeCall`` were encoded incorrectly.",
|
||||
"description": "For the encoding, the compiler only considered the types of the expressions in the second argument of ``abi.encodeCall`` itself, but not the parameter types of the function given as first argument. In almost all cases the abi encoding of the type of the expression matches the abi encoding of the parameter type of the given function. This is because the type checker ensures the expression is implicitly convertible to the respective parameter type. However this is not true for number literals used for fixed bytes types shorter than 32 bytes, nor for string literals used for any fixed bytes type. Number literals were encoded as numbers instead of being shifted to become left-aligned. String literals were encoded as dynamically sized memory strings instead of being converted to a left-aligned bytes value.",
|
||||
"link": "https://blog.soliditylang.org/2022/03/16/encodecall-bug/",
|
||||
"introduced": "0.8.11",
|
||||
"fixed": "0.8.13",
|
||||
"severity": "very low"
|
||||
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2021-4",
|
||||
"name": "UserDefinedValueTypesBug",
|
||||
@ -114,6 +8,7 @@
|
||||
"introduced": "0.8.8",
|
||||
"fixed": "0.8.9",
|
||||
"severity": "very low"
|
||||
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2021-3",
|
||||
|
@ -68,7 +68,7 @@ conditions
|
||||
If no conditions are given, assume that the bug is present.
|
||||
check
|
||||
This field contains different checks that report whether the smart contract
|
||||
contains the bug or not. The first type of check are JavaScript regular
|
||||
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
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"0.1.0": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -23,7 +22,6 @@
|
||||
},
|
||||
"0.1.1": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -45,7 +43,6 @@
|
||||
},
|
||||
"0.1.2": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -67,7 +64,6 @@
|
||||
},
|
||||
"0.1.3": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -89,7 +85,6 @@
|
||||
},
|
||||
"0.1.4": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -112,7 +107,6 @@
|
||||
},
|
||||
"0.1.5": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -135,7 +129,6 @@
|
||||
},
|
||||
"0.1.6": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -160,7 +153,6 @@
|
||||
},
|
||||
"0.1.7": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -185,7 +177,6 @@
|
||||
},
|
||||
"0.2.0": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -211,7 +202,6 @@
|
||||
},
|
||||
"0.2.1": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -237,7 +227,6 @@
|
||||
},
|
||||
"0.2.2": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -263,7 +252,6 @@
|
||||
},
|
||||
"0.3.0": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -291,7 +279,6 @@
|
||||
},
|
||||
"0.3.1": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -318,7 +305,6 @@
|
||||
},
|
||||
"0.3.2": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -345,7 +331,6 @@
|
||||
},
|
||||
"0.3.3": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -371,7 +356,6 @@
|
||||
},
|
||||
"0.3.4": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -397,7 +381,6 @@
|
||||
},
|
||||
"0.3.5": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -423,7 +406,6 @@
|
||||
},
|
||||
"0.3.6": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -447,7 +429,6 @@
|
||||
},
|
||||
"0.4.0": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -471,7 +452,6 @@
|
||||
},
|
||||
"0.4.1": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -495,7 +475,6 @@
|
||||
},
|
||||
"0.4.10": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -518,7 +497,6 @@
|
||||
},
|
||||
"0.4.11": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -540,7 +518,6 @@
|
||||
},
|
||||
"0.4.12": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -561,7 +538,6 @@
|
||||
},
|
||||
"0.4.13": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -582,7 +558,6 @@
|
||||
},
|
||||
"0.4.14": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -602,7 +577,6 @@
|
||||
},
|
||||
"0.4.15": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -621,7 +595,6 @@
|
||||
},
|
||||
"0.4.16": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -643,7 +616,6 @@
|
||||
},
|
||||
"0.4.17": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -666,7 +638,6 @@
|
||||
},
|
||||
"0.4.18": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -688,7 +659,6 @@
|
||||
},
|
||||
"0.4.19": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -711,7 +681,6 @@
|
||||
},
|
||||
"0.4.2": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -734,7 +703,6 @@
|
||||
},
|
||||
"0.4.20": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -757,7 +725,6 @@
|
||||
},
|
||||
"0.4.21": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -780,7 +747,6 @@
|
||||
},
|
||||
"0.4.22": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -803,7 +769,6 @@
|
||||
},
|
||||
"0.4.23": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -825,7 +790,6 @@
|
||||
},
|
||||
"0.4.24": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -847,7 +811,6 @@
|
||||
},
|
||||
"0.4.25": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -867,7 +830,6 @@
|
||||
},
|
||||
"0.4.26": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -884,7 +846,6 @@
|
||||
},
|
||||
"0.4.3": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -906,7 +867,6 @@
|
||||
},
|
||||
"0.4.4": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -927,7 +887,6 @@
|
||||
},
|
||||
"0.4.5": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -951,7 +910,6 @@
|
||||
},
|
||||
"0.4.6": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -974,7 +932,6 @@
|
||||
},
|
||||
"0.4.7": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -997,7 +954,6 @@
|
||||
},
|
||||
"0.4.8": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -1020,7 +976,6 @@
|
||||
},
|
||||
"0.4.9": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
"DynamicArrayCleanup",
|
||||
@ -1043,7 +998,6 @@
|
||||
},
|
||||
"0.5.0": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1063,7 +1017,6 @@
|
||||
},
|
||||
"0.5.1": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1083,9 +1036,6 @@
|
||||
},
|
||||
"0.5.10": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1101,9 +1051,6 @@
|
||||
},
|
||||
"0.5.11": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1118,9 +1065,6 @@
|
||||
},
|
||||
"0.5.12": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1135,9 +1079,6 @@
|
||||
},
|
||||
"0.5.13": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1152,9 +1093,6 @@
|
||||
},
|
||||
"0.5.14": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1171,9 +1109,6 @@
|
||||
},
|
||||
"0.5.15": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1189,9 +1124,6 @@
|
||||
},
|
||||
"0.5.16": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1206,9 +1138,6 @@
|
||||
},
|
||||
"0.5.17": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1222,7 +1151,6 @@
|
||||
},
|
||||
"0.5.2": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1242,7 +1170,6 @@
|
||||
},
|
||||
"0.5.3": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1262,7 +1189,6 @@
|
||||
},
|
||||
"0.5.4": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1282,7 +1208,6 @@
|
||||
},
|
||||
"0.5.5": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1304,7 +1229,6 @@
|
||||
},
|
||||
"0.5.6": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1326,7 +1250,6 @@
|
||||
},
|
||||
"0.5.7": {
|
||||
"bugs": [
|
||||
"DirtyBytesArrayToStorage",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1346,9 +1269,6 @@
|
||||
},
|
||||
"0.5.8": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1367,9 +1287,6 @@
|
||||
},
|
||||
"0.5.9": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1387,9 +1304,6 @@
|
||||
},
|
||||
"0.6.0": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1405,9 +1319,6 @@
|
||||
},
|
||||
"0.6.1": {
|
||||
"bugs": [
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1422,12 +1333,6 @@
|
||||
},
|
||||
"0.6.10": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1438,12 +1343,6 @@
|
||||
},
|
||||
"0.6.11": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1454,12 +1353,6 @@
|
||||
},
|
||||
"0.6.12": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1470,10 +1363,6 @@
|
||||
},
|
||||
"0.6.2": {
|
||||
"bugs": [
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1488,10 +1377,6 @@
|
||||
},
|
||||
"0.6.3": {
|
||||
"bugs": [
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1506,10 +1391,6 @@
|
||||
},
|
||||
"0.6.4": {
|
||||
"bugs": [
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
"EmptyByteArrayCopy",
|
||||
@ -1524,10 +1405,6 @@
|
||||
},
|
||||
"0.6.5": {
|
||||
"bugs": [
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1542,10 +1419,6 @@
|
||||
},
|
||||
"0.6.6": {
|
||||
"bugs": [
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1559,11 +1432,6 @@
|
||||
},
|
||||
"0.6.7": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1577,11 +1445,6 @@
|
||||
},
|
||||
"0.6.8": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1592,12 +1455,6 @@
|
||||
},
|
||||
"0.6.9": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1609,12 +1466,6 @@
|
||||
},
|
||||
"0.7.0": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1625,12 +1476,6 @@
|
||||
},
|
||||
"0.7.1": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1642,12 +1487,6 @@
|
||||
},
|
||||
"0.7.2": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1658,12 +1497,6 @@
|
||||
},
|
||||
"0.7.3": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching",
|
||||
@ -1673,12 +1506,6 @@
|
||||
},
|
||||
"0.7.4": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching"
|
||||
@ -1687,12 +1514,6 @@
|
||||
},
|
||||
"0.7.5": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching"
|
||||
@ -1701,12 +1522,6 @@
|
||||
},
|
||||
"0.7.6": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching"
|
||||
@ -1715,12 +1530,6 @@
|
||||
},
|
||||
"0.8.0": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching"
|
||||
@ -1729,12 +1538,6 @@
|
||||
},
|
||||
"0.8.1": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching"
|
||||
@ -1742,135 +1545,27 @@
|
||||
"released": "2021-01-27"
|
||||
},
|
||||
"0.8.10": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation"
|
||||
],
|
||||
"bugs": [],
|
||||
"released": "2021-11-09"
|
||||
},
|
||||
"0.8.11": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"AbiEncodeCallLiteralAsFixedBytesBug"
|
||||
],
|
||||
"bugs": [],
|
||||
"released": "2021-12-20"
|
||||
},
|
||||
"0.8.12": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"AbiEncodeCallLiteralAsFixedBytesBug"
|
||||
],
|
||||
"bugs": [],
|
||||
"released": "2022-02-16"
|
||||
},
|
||||
"0.8.13": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"StorageWriteRemovalBeforeConditionalTermination",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"InlineAssemblyMemorySideEffects",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation"
|
||||
],
|
||||
"released": "2022-03-16"
|
||||
},
|
||||
"0.8.14": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"StorageWriteRemovalBeforeConditionalTermination",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"InlineAssemblyMemorySideEffects"
|
||||
],
|
||||
"released": "2022-05-17"
|
||||
},
|
||||
"0.8.15": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"StorageWriteRemovalBeforeConditionalTermination",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup"
|
||||
],
|
||||
"released": "2022-06-15"
|
||||
},
|
||||
"0.8.16": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"StorageWriteRemovalBeforeConditionalTermination"
|
||||
],
|
||||
"released": "2022-08-08"
|
||||
},
|
||||
"0.8.17": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess"
|
||||
],
|
||||
"released": "2022-09-08"
|
||||
},
|
||||
"0.8.18": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess"
|
||||
],
|
||||
"released": "2023-02-01"
|
||||
},
|
||||
"0.8.19": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess"
|
||||
],
|
||||
"released": "2023-02-22"
|
||||
},
|
||||
"0.8.2": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory",
|
||||
"KeccakCaching"
|
||||
],
|
||||
"released": "2021-03-02"
|
||||
},
|
||||
"0.8.20": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess"
|
||||
],
|
||||
"released": "2023-05-10"
|
||||
},
|
||||
"0.8.21": {
|
||||
"bugs": [],
|
||||
"released": "2023-07-19"
|
||||
},
|
||||
"0.8.3": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables",
|
||||
"ABIDecodeTwoDimensionalArrayMemory"
|
||||
],
|
||||
@ -1878,74 +1573,37 @@
|
||||
},
|
||||
"0.8.4": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables"
|
||||
],
|
||||
"released": "2021-04-21"
|
||||
},
|
||||
"0.8.5": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables"
|
||||
],
|
||||
"released": "2021-06-10"
|
||||
},
|
||||
"0.8.6": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables"
|
||||
],
|
||||
"released": "2021-06-22"
|
||||
},
|
||||
"0.8.7": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"SignedImmutables"
|
||||
],
|
||||
"released": "2021-08-11"
|
||||
},
|
||||
"0.8.8": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||
"UserDefinedValueTypesBug",
|
||||
"SignedImmutables"
|
||||
],
|
||||
"released": "2021-09-27"
|
||||
},
|
||||
"0.8.9": {
|
||||
"bugs": [
|
||||
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||
"MissingSideEffectsOnSelectorAccess",
|
||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||
"DirtyBytesArrayToStorage",
|
||||
"DataLocationChangeInInternalOverride",
|
||||
"NestedCalldataArrayAbiReencodingSizeValidation"
|
||||
],
|
||||
"bugs": [],
|
||||
"released": "2021-09-29"
|
||||
}
|
||||
}
|
@ -2,17 +2,75 @@
|
||||
Cheatsheet
|
||||
**********
|
||||
|
||||
.. index:: operator;precedence
|
||||
.. index:: precedence
|
||||
|
||||
.. _order:
|
||||
|
||||
Order of Precedence of Operators
|
||||
================================
|
||||
|
||||
.. include:: types/operator-precedence-table.rst
|
||||
The following is the order of precedence for operators, listed in order of evaluation.
|
||||
|
||||
.. index:: abi;decode, abi;encode, abi;encodePacked, abi;encodeWithSelector, abi;encodeCall, abi;encodeWithSignature
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| Precedence | Description | Operator |
|
||||
+============+=====================================+============================================+
|
||||
| *1* | Postfix increment and decrement | ``++``, ``--`` |
|
||||
+ +-------------------------------------+--------------------------------------------+
|
||||
| | New expression | ``new <typename>`` |
|
||||
+ +-------------------------------------+--------------------------------------------+
|
||||
| | Array subscripting | ``<array>[<index>]`` |
|
||||
+ +-------------------------------------+--------------------------------------------+
|
||||
| | Member access | ``<object>.<member>`` |
|
||||
+ +-------------------------------------+--------------------------------------------+
|
||||
| | Function-like call | ``<func>(<args...>)`` |
|
||||
+ +-------------------------------------+--------------------------------------------+
|
||||
| | Parentheses | ``(<statement>)`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *2* | Prefix increment and decrement | ``++``, ``--`` |
|
||||
+ +-------------------------------------+--------------------------------------------+
|
||||
| | Unary minus | ``-`` |
|
||||
+ +-------------------------------------+--------------------------------------------+
|
||||
| | Unary operations | ``delete`` |
|
||||
+ +-------------------------------------+--------------------------------------------+
|
||||
| | Logical NOT | ``!`` |
|
||||
+ +-------------------------------------+--------------------------------------------+
|
||||
| | Bitwise NOT | ``~`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *3* | Exponentiation | ``**`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *4* | Multiplication, division and modulo | ``*``, ``/``, ``%`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *5* | Addition and subtraction | ``+``, ``-`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *6* | Bitwise shift operators | ``<<``, ``>>`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *7* | Bitwise AND | ``&`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *8* | Bitwise XOR | ``^`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *9* | Bitwise OR | ``|`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *10* | Inequality operators | ``<``, ``>``, ``<=``, ``>=`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *11* | Equality operators | ``==``, ``!=`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *12* | Logical AND | ``&&`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *13* | Logical OR | ``||`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *14* | Ternary operator | ``<conditional> ? <if-true> : <if-false>`` |
|
||||
+ +-------------------------------------+--------------------------------------------+
|
||||
| | Assignment operators | ``=``, ``|=``, ``^=``, ``&=``, ``<<=``, |
|
||||
| | | ``>>=``, ``+=``, ``-=``, ``*=``, ``/=``, |
|
||||
| | | ``%=`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
| *15* | Comma operator | ``,`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
|
||||
ABI Encoding and Decoding Functions
|
||||
===================================
|
||||
.. index:: assert, block, coinbase, difficulty, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, gas price, origin, revert, require, keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, codehash, send
|
||||
|
||||
Global Variables
|
||||
================
|
||||
|
||||
- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: :ref:`ABI <ABI>`-decodes
|
||||
the provided data. The types are given in parentheses as second argument.
|
||||
@ -25,45 +83,17 @@ ABI Encoding and Decoding Functions
|
||||
- ``abi.encodeCall(function functionPointer, (...)) returns (bytes memory)``: ABI-encodes a call to ``functionPointer`` with the arguments found in the
|
||||
tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, (...))``
|
||||
- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent
|
||||
to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)``
|
||||
|
||||
.. index:: bytes;concat, string;concat
|
||||
|
||||
Members of ``bytes`` and ``string``
|
||||
====================================
|
||||
|
||||
to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)``
|
||||
- ``bytes.concat(...) returns (bytes memory)``: :ref:`Concatenates variable number of
|
||||
arguments to one byte array<bytes-concat>`
|
||||
|
||||
- ``string.concat(...) returns (string memory)``: :ref:`Concatenates variable number of
|
||||
arguments to one string array<string-concat>`
|
||||
|
||||
.. index:: address;balance, address;codehash, address;send, address;code, address;transfer
|
||||
|
||||
Members of ``address``
|
||||
======================
|
||||
|
||||
- ``<address>.balance`` (``uint256``): balance of the :ref:`address` in Wei
|
||||
- ``<address>.code`` (``bytes memory``): code at the :ref:`address` (can be empty)
|
||||
- ``<address>.codehash`` (``bytes32``): the codehash of the :ref:`address`
|
||||
- ``<address payable>.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`,
|
||||
returns ``false`` on failure
|
||||
- ``<address payable>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure
|
||||
|
||||
.. index:: blockhash, block, block;basefree, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp
|
||||
.. index:: gasleft, msg;data, msg;sender, msg;sig, msg;value, tx;gasprice, tx;origin
|
||||
|
||||
Block and Transaction Properties
|
||||
================================
|
||||
|
||||
- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks
|
||||
- ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_)
|
||||
- ``block.chainid`` (``uint``): current chain id
|
||||
- ``block.coinbase`` (``address payable``): current block miner's address
|
||||
- ``block.difficulty`` (``uint``): current block difficulty (``EVM < Paris``). For other EVM versions it behaves as a deprecated alias for ``block.prevrandao`` that will be removed in the next breaking release
|
||||
- ``block.difficulty`` (``uint``): current block difficulty
|
||||
- ``block.gaslimit`` (``uint``): current block gaslimit
|
||||
- ``block.number`` (``uint``): current block number
|
||||
- ``block.prevrandao`` (``uint``): random number provided by the beacon chain (``EVM >= Paris``) (see `EIP-4399 <https://eips.ethereum.org/EIPS/eip-4399>`_ )
|
||||
- ``block.timestamp`` (``uint``): current block timestamp in seconds since Unix epoch
|
||||
- ``gasleft() returns (uint256)``: remaining gas
|
||||
- ``msg.data`` (``bytes``): complete calldata
|
||||
@ -72,12 +102,6 @@ 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)
|
||||
|
||||
.. 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)
|
||||
@ -85,12 +109,7 @@ Validations and Assertions
|
||||
condition is ``false`` (use for malformed input or error in external component). Also provide error message.
|
||||
- ``revert()``: abort execution and revert state changes
|
||||
- ``revert(string memory message)``: abort execution and revert state changes providing an explanatory string
|
||||
|
||||
.. index:: cryptography, keccak256, sha256, ripemd160, ecrecover, addmod, mulmod
|
||||
|
||||
Mathematical and Cryptographic Functions
|
||||
========================================
|
||||
|
||||
- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks
|
||||
- ``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
|
||||
@ -100,21 +119,15 @@ Mathematical and Cryptographic Functions
|
||||
arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
|
||||
- ``mulmod(uint x, uint y, uint k) returns (uint)``: compute ``(x * y) % k`` where the multiplication is performed
|
||||
with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
|
||||
|
||||
.. index:: this, super, selfdestruct
|
||||
|
||||
Contract-related
|
||||
================
|
||||
|
||||
- ``this`` (current contract's type): the current contract, explicitly convertible to ``address`` or ``address payable``
|
||||
- ``super``: a contract one level higher in the inheritance hierarchy
|
||||
- ``super``: the contract one level higher in the inheritance hierarchy
|
||||
- ``selfdestruct(address payable recipient)``: destroy the current contract, sending its funds to the given address
|
||||
|
||||
.. index:: type;name, type;creationCode, type;runtimeCode, type;interfaceId, type;min, type;max
|
||||
|
||||
Type Information
|
||||
================
|
||||
|
||||
- ``<address>.balance`` (``uint256``): balance of the :ref:`address` in Wei
|
||||
- ``<address>.code`` (``bytes memory``): code at the :ref:`address` (can be empty)
|
||||
- ``<address>.codehash`` (``bytes32``): the codehash of the :ref:`address`
|
||||
- ``<address payable>.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`,
|
||||
returns ``false`` on failure
|
||||
- ``<address payable>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure
|
||||
- ``type(C).name`` (``string``): the name of the contract
|
||||
- ``type(C).creationCode`` (``bytes memory``): creation bytecode of the given contract, see :ref:`Type Information<meta-type>`.
|
||||
- ``type(C).runtimeCode`` (``bytes memory``): runtime bytecode of the given contract, see :ref:`Type Information<meta-type>`.
|
||||
@ -122,6 +135,35 @@ Type Information
|
||||
- ``type(T).min`` (``T``): the minimum value representable by the integer type ``T``, see :ref:`Type Information<meta-type>`.
|
||||
- ``type(T).max`` (``T``): the maximum value representable by the integer type ``T``, see :ref:`Type Information<meta-type>`.
|
||||
|
||||
.. note::
|
||||
When contracts are evaluated off-chain rather than in context of a transaction included in a
|
||||
block, you should not assume that ``block.*`` and ``tx.*`` refer to values from any specific
|
||||
block or transaction. These values are provided by the EVM implementation that executes the
|
||||
contract and can be arbitrary.
|
||||
|
||||
.. note::
|
||||
Do not rely on ``block.timestamp`` or ``blockhash`` as a source of randomness,
|
||||
unless you know what you are doing.
|
||||
|
||||
Both the timestamp and the block hash can be influenced by miners to some degree.
|
||||
Bad actors in the mining community can for example run a casino payout function on a chosen hash
|
||||
and just retry a different hash if they did not receive any money.
|
||||
|
||||
The current block timestamp must be strictly larger than the timestamp of the last block,
|
||||
but the only guarantee is that it will be somewhere between the timestamps of two
|
||||
consecutive blocks in the canonical chain.
|
||||
|
||||
.. note::
|
||||
The block hashes are not available for all blocks for scalability reasons.
|
||||
You can only access the hashes of the most recent 256 blocks, all other
|
||||
values will be zero.
|
||||
|
||||
.. note::
|
||||
In version 0.5.0, the following aliases were removed: ``suicide`` as alias for ``selfdestruct``,
|
||||
``msg.gas`` as alias for ``gasleft``, ``block.blockhash`` as alias for ``blockhash`` and
|
||||
``sha3`` as alias for ``keccak256``.
|
||||
.. note::
|
||||
In version 0.7.0, the alias ``now`` (for ``block.timestamp``) was removed.
|
||||
|
||||
.. index:: visibility, public, private, external, internal
|
||||
|
||||
@ -150,11 +192,21 @@ Modifiers
|
||||
- ``view`` for functions: Disallows modification of state.
|
||||
- ``payable`` for functions: Allows them to receive Ether together with a call.
|
||||
- ``constant`` for state variables: Disallows assignment (except initialisation), does not occupy storage slot.
|
||||
- ``immutable`` for state variables: Allows assignment at construction time and is constant when deployed. Is stored in code.
|
||||
- ``immutable`` for state variables: Allows exactly one assignment at construction time and is constant afterwards. Is stored in code.
|
||||
- ``anonymous`` for events: Does not store event signature as topic.
|
||||
- ``indexed`` for event parameters: Stores the parameter as topic.
|
||||
- ``virtual`` for functions and modifiers: Allows the function's or modifier's
|
||||
behavior to be changed in derived contracts.
|
||||
behaviour 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.
|
||||
the behaviour of a function or modifier in a base contract.
|
||||
|
||||
Reserved Keywords
|
||||
=================
|
||||
|
||||
These keywords are reserved in Solidity. They might become part of the syntax in the future:
|
||||
|
||||
``after``, ``alias``, ``apply``, ``auto``, ``byte``, ``case``, ``copyof``, ``default``,
|
||||
``define``, ``final``, ``implements``, ``in``, ``inline``, ``let``, ``macro``, ``match``,
|
||||
``mutable``, ``null``, ``of``, ``partial``, ``promise``, ``reference``, ``relocatable``,
|
||||
``sealed``, ``sizeof``, ``static``, ``supports``, ``switch``, ``typedef``, ``typeof``,
|
||||
``var``.
|
||||
|
@ -18,7 +18,7 @@ introduces a potential security risk. You may read
|
||||
more about this on the :ref:`security_considerations` page.
|
||||
|
||||
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
|
||||
a contract where the goal is to send the most money to the
|
||||
contract in order to become the "richest", inspired by
|
||||
`King of the Ether <https://www.kingoftheether.com/>`_.
|
||||
|
||||
@ -34,7 +34,7 @@ you receive the funds of the person who is now the richest.
|
||||
address public richest;
|
||||
uint public mostSent;
|
||||
|
||||
mapping(address => uint) pendingWithdrawals;
|
||||
mapping (address => uint) pendingWithdrawals;
|
||||
|
||||
/// The amount of Ether sent was not higher than
|
||||
/// the currently highest amount.
|
||||
@ -55,7 +55,7 @@ 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
|
||||
// sending to prevent re-entrancy attacks
|
||||
pendingWithdrawals[msg.sender] = 0;
|
||||
payable(msg.sender).transfer(amount);
|
||||
}
|
||||
@ -163,9 +163,9 @@ restrictions highly readable.
|
||||
// prepend a check that only passes
|
||||
// if the function is called from
|
||||
// a certain address.
|
||||
modifier onlyBy(address account)
|
||||
modifier onlyBy(address _account)
|
||||
{
|
||||
if (msg.sender != account)
|
||||
if (msg.sender != _account)
|
||||
revert Unauthorized();
|
||||
// Do not forget the "_;"! It will
|
||||
// be replaced by the actual function
|
||||
@ -173,17 +173,17 @@ restrictions highly readable.
|
||||
_;
|
||||
}
|
||||
|
||||
/// Make `newOwner` the new owner of this
|
||||
/// Make `_newOwner` the new owner of this
|
||||
/// contract.
|
||||
function changeOwner(address newOwner)
|
||||
function changeOwner(address _newOwner)
|
||||
public
|
||||
onlyBy(owner)
|
||||
{
|
||||
owner = newOwner;
|
||||
owner = _newOwner;
|
||||
}
|
||||
|
||||
modifier onlyAfter(uint time) {
|
||||
if (block.timestamp < time)
|
||||
modifier onlyAfter(uint _time) {
|
||||
if (block.timestamp < _time)
|
||||
revert TooEarly();
|
||||
_;
|
||||
}
|
||||
@ -205,21 +205,21 @@ restrictions highly readable.
|
||||
// refunded, but only after the function body.
|
||||
// This was dangerous before Solidity version 0.4.0,
|
||||
// where it was possible to skip the part after `_;`.
|
||||
modifier costs(uint amount) {
|
||||
if (msg.value < amount)
|
||||
modifier costs(uint _amount) {
|
||||
if (msg.value < _amount)
|
||||
revert NotEnoughEther();
|
||||
|
||||
_;
|
||||
if (msg.value > amount)
|
||||
payable(msg.sender).transfer(msg.value - amount);
|
||||
if (msg.value > _amount)
|
||||
payable(msg.sender).transfer(msg.value - _amount);
|
||||
}
|
||||
|
||||
function forceOwnerChange(address newOwner)
|
||||
function forceOwnerChange(address _newOwner)
|
||||
public
|
||||
payable
|
||||
costs(200 ether)
|
||||
{
|
||||
owner = newOwner;
|
||||
owner = _newOwner;
|
||||
// just some example condition
|
||||
if (uint160(owner) & 0 == 1)
|
||||
// This did not refund for Solidity
|
||||
@ -315,8 +315,8 @@ function finishes.
|
||||
|
||||
uint public creationTime = block.timestamp;
|
||||
|
||||
modifier atStage(Stages stage_) {
|
||||
if (stage != stage_)
|
||||
modifier atStage(Stages _stage) {
|
||||
if (stage != _stage)
|
||||
revert FunctionInvalidAtThisStage();
|
||||
_;
|
||||
}
|
||||
|
15
docs/conf.py
@ -31,10 +31,7 @@ def setup(sphinx):
|
||||
sphinx.add_lexer('Solidity', SolidityLexer)
|
||||
sphinx.add_lexer('Yul', YulLexer)
|
||||
|
||||
sphinx.add_css_file('css/fonts.css')
|
||||
sphinx.add_css_file('css/custom.css')
|
||||
sphinx.add_css_file('css/custom-dark.css')
|
||||
sphinx.add_css_file('css/pygments.css')
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
@ -48,7 +45,6 @@ extensions = [
|
||||
'sphinx_a4doc',
|
||||
'html_extra_template_renderer',
|
||||
'remix_code_links',
|
||||
'sphinx.ext.imgconverter',
|
||||
]
|
||||
|
||||
a4_base_path = os.path.dirname(__file__) + '/grammar'
|
||||
@ -67,7 +63,7 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'Solidity'
|
||||
project_copyright = '2016-2023, The Solidity Authors'
|
||||
project_copyright = '2016-2021, Ethereum'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@ -135,6 +131,7 @@ html_theme = 'sphinx_rtd_theme'
|
||||
# documentation.
|
||||
html_theme_options = {
|
||||
'logo_only': True,
|
||||
'style_nav_header_background': '#65afff',
|
||||
'display_version': True,
|
||||
}
|
||||
|
||||
@ -150,12 +147,12 @@ html_theme_options = {
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
# html_logo = "logo.svg"
|
||||
html_logo = "logo.svg"
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
html_favicon = "_static/img/favicon.ico"
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
@ -164,7 +161,7 @@ html_static_path = ['_static']
|
||||
|
||||
html_css_files = ["css/toggle.css"]
|
||||
|
||||
html_js_files = ["js/constants.js", "js/initialize.js", "js/toggle.js"]
|
||||
html_js_files = ["js/toggle.js"]
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
@ -212,7 +209,7 @@ html_extra_templates = {
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
html_show_sphinx = False
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
@ -6,15 +6,12 @@
|
||||
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.
|
||||
Contracts need to be marked as abstract when at least one of their functions is not implemented.
|
||||
Contracts may be marked as abstract even though all functions are implemented.
|
||||
|
||||
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).
|
||||
This can be done by using the ``abstract`` keyword as shown in the following example. Note that this contract needs to be
|
||||
defined as abstract, because the function ``utterance()`` was defined, but no implementation was
|
||||
provided (no implementation body ``{ }`` was given).
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
|
@ -30,29 +30,25 @@ Not all types for constants and immutables are implemented at this time. The onl
|
||||
.. code-block:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity ^0.8.21;
|
||||
pragma solidity >=0.7.4;
|
||||
|
||||
uint constant X = 32**22 + 8;
|
||||
|
||||
contract C {
|
||||
string constant TEXT = "abc";
|
||||
bytes32 constant MY_HASH = keccak256("abc");
|
||||
uint immutable decimals = 18;
|
||||
uint immutable decimals;
|
||||
uint immutable maxBalance;
|
||||
address immutable owner = msg.sender;
|
||||
|
||||
constructor(uint decimals_, address ref) {
|
||||
if (decimals_ != 0)
|
||||
// Immutables are only immutable when deployed.
|
||||
// At construction time they can be assigned to any number of times.
|
||||
decimals = decimals_;
|
||||
|
||||
constructor(uint _decimals, address _reference) {
|
||||
decimals = _decimals;
|
||||
// Assignments to immutables can even access the environment.
|
||||
maxBalance = ref.balance;
|
||||
maxBalance = _reference.balance;
|
||||
}
|
||||
|
||||
function isBalanceTooHigh(address other) public view returns (bool) {
|
||||
return other.balance > maxBalance;
|
||||
function isBalanceTooHigh(address _other) public view returns (bool) {
|
||||
return _other.balance > maxBalance;
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,34 +74,25 @@ Immutable
|
||||
=========
|
||||
|
||||
Variables declared as ``immutable`` are a bit less restricted than those
|
||||
declared as ``constant``: Immutable variables can be assigned a
|
||||
value at construction time.
|
||||
The value can be changed at any time before deployment and then it becomes permanent.
|
||||
|
||||
One additional restriction is that immutables can only be assigned to inside expressions for which
|
||||
there is no possibility of being executed after creation.
|
||||
This excludes all modifier definitions and functions other than constructors.
|
||||
|
||||
There are no restrictions on reading immutable variables.
|
||||
The read is even allowed to happen before the variable is written to for the first time because variables in
|
||||
Solidity always have a well-defined initial value.
|
||||
For this reason it is also allowed to never explicitly assign a value to an immutable.
|
||||
|
||||
.. warning::
|
||||
When accessing immutables at construction time, please keep the :ref:`initialization order
|
||||
<state-variable-initialization-order>` in mind.
|
||||
Even if you provide an explicit initializer, some expressions may end up being evaluated before
|
||||
that initializer, especially when they are at a different level in inheritance hierarchy.
|
||||
|
||||
.. note::
|
||||
Before Solidity 0.8.21 initialization of immutable variables was more restrictive.
|
||||
Such variables had to be initialized exactly once at construction time and could not be read
|
||||
before then.
|
||||
declared as ``constant``: Immutable variables can be assigned an arbitrary
|
||||
value in the constructor of the contract or at the point of their declaration.
|
||||
They can be assigned only once and can, from that point on, be read even during
|
||||
construction time.
|
||||
|
||||
The contract creation code generated by the compiler will modify the
|
||||
contract's runtime code before it is returned by replacing all references
|
||||
to immutables with the values assigned to them. This is important if
|
||||
to immutables by the values assigned to the them. This is important if
|
||||
you are comparing the
|
||||
runtime code generated by the compiler with the one actually stored in the
|
||||
blockchain. The compiler outputs where these immutables are located in the deployed bytecode
|
||||
in the ``immutableReferences`` field of the :ref:`compiler JSON standard output <compiler-api>`.
|
||||
blockchain.
|
||||
|
||||
.. note::
|
||||
Immutables that are assigned at their declaration are only considered
|
||||
initialized once the constructor of the contract is executing.
|
||||
This means you cannot initialize immutables inline with a value
|
||||
that depends on another immutable. You can do this, however,
|
||||
inside the constructor of the contract.
|
||||
|
||||
This is a safeguard against different interpretations about the order
|
||||
of state variable initialization and constructor execution, especially
|
||||
with regards to inheritance.
|
@ -8,7 +8,7 @@ Contracts can be created "from outside" via Ethereum transactions or from within
|
||||
|
||||
IDEs, such as `Remix <https://remix.ethereum.org/>`_, make the creation process seamless using UI elements.
|
||||
|
||||
One way to create contracts programmatically on Ethereum is via the JavaScript API `web3.js <https://github.com/web3/web3.js>`_.
|
||||
One way to create contracts programmatically on Ethereum is via the JavaScript API `web3.js <https://github.com/ethereum/web3.js>`_.
|
||||
It has a function called `web3.eth.Contract <https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html#new-contract>`_
|
||||
to facilitate contract creation.
|
||||
|
||||
@ -48,7 +48,7 @@ This means that cyclic creation dependencies are impossible.
|
||||
|
||||
// This is the constructor which registers the
|
||||
// creator and the assigned name.
|
||||
constructor(bytes32 name_) {
|
||||
constructor(bytes32 _name) {
|
||||
// State variables are accessed via their name
|
||||
// and not via e.g. `this.owner`. Functions can
|
||||
// be accessed directly or through `this.f`,
|
||||
@ -65,7 +65,7 @@ This means that cyclic creation dependencies are impossible.
|
||||
// no real way to verify that.
|
||||
// This does not create a new contract.
|
||||
creator = TokenCreator(msg.sender);
|
||||
name = name_;
|
||||
name = _name;
|
||||
}
|
||||
|
||||
function changeName(bytes32 newName) public {
|
||||
|
@ -1,4 +1,5 @@
|
||||
.. index:: ! error, revert, ! selector; of an error
|
||||
.. index:: ! error, revert
|
||||
|
||||
.. _errors:
|
||||
|
||||
*******************************
|
||||
@ -79,8 +80,3 @@ of the built-in type ``Panic(uint256)``.
|
||||
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.
|
||||
|
@ -1,4 +1,4 @@
|
||||
.. index:: ! event, ! event; anonymous, ! event; indexed, ! event; topic
|
||||
.. index:: ! event
|
||||
|
||||
.. _events:
|
||||
|
||||
@ -9,10 +9,9 @@ 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.
|
||||
|
||||
Events can be defined at file level or as inheritable members of contracts (including interfaces and libraries).
|
||||
When you call them, they cause the
|
||||
Events are inheritable members of contracts. When you call them, they cause the
|
||||
arguments to be stored in the transaction's log - a special data structure
|
||||
in the blockchain. These logs are associated with the address of the contract that emitted them,
|
||||
in the blockchain. These logs are associated with the address of the contract,
|
||||
are incorporated into the blockchain, and stay there as long as a block is
|
||||
accessible (forever as of now, but this might
|
||||
change with Serenity). The Log and its event data is not accessible from within
|
||||
@ -74,18 +73,6 @@ four indexed arguments rather than three.
|
||||
In particular, it is possible to "fake" the signature of another event
|
||||
using an anonymous event.
|
||||
|
||||
.. index:: ! selector; of an event
|
||||
|
||||
Members of Events
|
||||
=================
|
||||
|
||||
- ``event.selector``: For non-anonymous events, this is a ``bytes32`` value
|
||||
containing the ``keccak256`` hash of the event signature, as used in the default topic.
|
||||
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
@ -93,18 +80,18 @@ Example
|
||||
|
||||
contract ClientReceipt {
|
||||
event Deposit(
|
||||
address indexed from,
|
||||
bytes32 indexed id,
|
||||
uint value
|
||||
address indexed _from,
|
||||
bytes32 indexed _id,
|
||||
uint _value
|
||||
);
|
||||
|
||||
function deposit(bytes32 id) public payable {
|
||||
function deposit(bytes32 _id) public payable {
|
||||
// Events are emitted using `emit`, followed by
|
||||
// the name of the event and the arguments
|
||||
// (if any) in parentheses. Any such invocation
|
||||
// (even deeply nested) can be detected from
|
||||
// the JavaScript API by filtering for `Deposit`.
|
||||
emit Deposit(msg.sender, id, msg.value);
|
||||
emit Deposit(msg.sender, _id, msg.value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,9 +126,9 @@ The output of the above looks like the following (trimmed):
|
||||
|
||||
{
|
||||
"returnValues": {
|
||||
"from": "0x1111…FFFFCCCC",
|
||||
"id": "0x50…sd5adb20",
|
||||
"value": "0x420042"
|
||||
"_from": "0x1111…FFFFCCCC",
|
||||
"_id": "0x50…sd5adb20",
|
||||
"_value": "0x420042"
|
||||
},
|
||||
"raw": {
|
||||
"data": "0x7f…91385",
|
||||
@ -150,8 +137,8 @@ The output of the above looks like the following (trimmed):
|
||||
}
|
||||
|
||||
Additional Resources for Understanding Events
|
||||
=============================================
|
||||
==============================================
|
||||
|
||||
- `JavaScript documentation <https://github.com/web3/web3.js/blob/1.x/docs/web3-eth-contract.rst#events>`_
|
||||
- `Javascript documentation <https://github.com/ethereum/web3.js/blob/1.x/docs/web3-eth-contract.rst#events>`_
|
||||
- `Example usage of events <https://github.com/ethchange/smart-exchange/blob/master/lib/contracts/SmartExchange.sol>`_
|
||||
- `How to access them in js <https://github.com/ethchange/smart-exchange/blob/master/lib/exchange_transactions.js>`_
|
||||
|
@ -6,7 +6,7 @@
|
||||
Function Modifiers
|
||||
******************
|
||||
|
||||
Modifiers can be used to change the behavior of functions in a declarative way.
|
||||
Modifiers can be used to change the behaviour of functions in a declarative way.
|
||||
For example,
|
||||
you can use a modifier to automatically check a condition prior to executing the function.
|
||||
|
||||
@ -19,7 +19,6 @@ if they are marked ``virtual``. For details, please see
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.1 <0.9.0;
|
||||
// This will report a warning due to deprecated selfdestruct
|
||||
|
||||
contract owned {
|
||||
constructor() { owner = payable(msg.sender); }
|
||||
@ -61,7 +60,7 @@ if they are marked ``virtual``. For details, please see
|
||||
}
|
||||
|
||||
contract Register is priced, destructible {
|
||||
mapping(address => bool) registeredAddresses;
|
||||
mapping (address => bool) registeredAddresses;
|
||||
uint price;
|
||||
|
||||
constructor(uint initialPrice) { price = initialPrice; }
|
||||
@ -73,8 +72,8 @@ if they are marked ``virtual``. For details, please see
|
||||
registeredAddresses[msg.sender] = true;
|
||||
}
|
||||
|
||||
function changePrice(uint price_) public onlyOwner {
|
||||
price = price_;
|
||||
function changePrice(uint _price) public onlyOwner {
|
||||
price = _price;
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,12 +111,6 @@ 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.
|
||||
@ -132,7 +125,7 @@ variables are set to their :ref:`default values<default-value>` just as if the f
|
||||
body.
|
||||
|
||||
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.
|
||||
the function body.
|
||||
|
||||
Arbitrary expressions are allowed for modifier arguments and in this context,
|
||||
all symbols visible from the function are visible in the modifier. Symbols
|
||||
|
@ -1,4 +1,4 @@
|
||||
.. index:: ! functions, ! function;free
|
||||
.. index:: ! functions
|
||||
|
||||
.. _functions:
|
||||
|
||||
@ -17,17 +17,17 @@ that call them, similar to internal library functions.
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.1 <0.9.0;
|
||||
|
||||
function sum(uint[] memory arr) pure returns (uint s) {
|
||||
for (uint i = 0; i < arr.length; i++)
|
||||
s += arr[i];
|
||||
function sum(uint[] memory _arr) pure returns (uint s) {
|
||||
for (uint i = 0; i < _arr.length; i++)
|
||||
s += _arr[i];
|
||||
}
|
||||
|
||||
contract ArrayExample {
|
||||
bool found;
|
||||
function f(uint[] memory arr) public {
|
||||
function f(uint[] memory _arr) public {
|
||||
// This calls the free function internally.
|
||||
// The compiler will add its code to the contract.
|
||||
uint s = sum(arr);
|
||||
uint s = sum(_arr);
|
||||
require(s >= 10);
|
||||
found = true;
|
||||
}
|
||||
@ -35,10 +35,10 @@ 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,
|
||||
in the context of a contract. They still have access to the variable ``this``,
|
||||
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
|
||||
is that free functions do not have direct access to storage variables and functions
|
||||
not in their scope.
|
||||
|
||||
.. _function-parameters-return-variables:
|
||||
@ -65,13 +65,23 @@ with two integers, you would use something like the following:
|
||||
|
||||
contract Simple {
|
||||
uint sum;
|
||||
function taker(uint a, uint b) public {
|
||||
sum = a + b;
|
||||
function taker(uint _a, uint _b) public {
|
||||
sum = _a + _b;
|
||||
}
|
||||
}
|
||||
|
||||
Function parameters can be used as any other local variable and they can also be assigned to.
|
||||
|
||||
.. note::
|
||||
|
||||
An :ref:`external function<external-function-calls>` cannot accept a
|
||||
multi-dimensional array as an input
|
||||
parameter. This functionality is possible if you enable the ABI coder v2
|
||||
by adding ``pragma abicoder v2;`` to your source file.
|
||||
|
||||
An :ref:`internal function<external-function-calls>` can accept a
|
||||
multi-dimensional array without enabling the feature.
|
||||
|
||||
.. index:: return array, return string, array, string, array of strings, dynamic array, variably sized array, return struct, struct
|
||||
|
||||
Return Variables
|
||||
@ -89,13 +99,13 @@ two integers passed as function parameters, then you use something like:
|
||||
pragma solidity >=0.4.16 <0.9.0;
|
||||
|
||||
contract Simple {
|
||||
function arithmetic(uint a, uint b)
|
||||
function arithmetic(uint _a, uint _b)
|
||||
public
|
||||
pure
|
||||
returns (uint sum, uint product)
|
||||
returns (uint o_sum, uint o_product)
|
||||
{
|
||||
sum = a + b;
|
||||
product = a * b;
|
||||
o_sum = _a + _b;
|
||||
o_product = _a * _b;
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,12 +126,12 @@ statement:
|
||||
pragma solidity >=0.4.16 <0.9.0;
|
||||
|
||||
contract Simple {
|
||||
function arithmetic(uint a, uint b)
|
||||
function arithmetic(uint _a, uint _b)
|
||||
public
|
||||
pure
|
||||
returns (uint sum, uint product)
|
||||
returns (uint o_sum, uint o_product)
|
||||
{
|
||||
return (a + b, a * b);
|
||||
return (_a + _b, _a * _b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,16 +139,12 @@ If you use an early ``return`` to leave a function that has return variables,
|
||||
you must provide return values together with the return statement.
|
||||
|
||||
.. 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 <abi_coder>`),
|
||||
- structs (applies only to :ref:`ABI coder v1 <abi_coder>`).
|
||||
|
||||
This restriction does not apply to library functions because of their different :ref:`internal ABI <library-selectors>`.
|
||||
You cannot return some types from non-internal functions, notably
|
||||
multi-dimensional dynamic arrays and structs. If you enable the
|
||||
ABI coder v2 by adding ``pragma abicoder v2;``
|
||||
to your source file then more types are available, but
|
||||
``mapping`` types are still limited to inside a single contract and you
|
||||
cannot transfer them.
|
||||
|
||||
.. _multi-return:
|
||||
|
||||
@ -250,7 +256,7 @@ Reverting a state change is not considered a "state modification", as only chang
|
||||
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.
|
||||
|
||||
This behavior is also in line with the ``STATICCALL`` opcode.
|
||||
This behaviour is also in line with the ``STATICCALL`` opcode.
|
||||
|
||||
.. warning::
|
||||
It is not possible to prevent functions from reading the state at the level
|
||||
@ -277,7 +283,7 @@ This behavior is also in line with the ``STATICCALL`` opcode.
|
||||
Special Functions
|
||||
=================
|
||||
|
||||
.. index:: ! receive ether function, function;receive, ! receive
|
||||
.. index:: ! receive ether function, function;receive ! receive
|
||||
|
||||
.. _receive-ether-function:
|
||||
|
||||
@ -297,7 +303,7 @@ on plain Ether transfers (e.g. via ``.send()`` or ``.transfer()``). If no such
|
||||
function exists, but a payable :ref:`fallback function <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
|
||||
contract cannot receive Ether through regular transactions and throws an
|
||||
exception.
|
||||
|
||||
In the worst case, the ``receive`` function can only rely on 2300 gas being
|
||||
@ -311,13 +317,12 @@ will consume more gas than the 2300 gas stipend:
|
||||
- Sending Ether
|
||||
|
||||
.. 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,
|
||||
Contracts that receive Ether directly (without a function call, i.e. using ``send`` or ``transfer``)
|
||||
but do not define a receive Ether function or a payable fallback function
|
||||
throw an exception, sending back the Ether (this was different
|
||||
before Solidity v0.4.0). So 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).
|
||||
not recommended, since it would not fail on interface confusions).
|
||||
|
||||
|
||||
.. warning::
|
||||
@ -357,7 +362,7 @@ Fallback Function
|
||||
-----------------
|
||||
|
||||
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)``
|
||||
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.
|
||||
@ -368,8 +373,8 @@ all and there is no :ref:`receive Ether function <receive-ether-function>`.
|
||||
The fallback function always receives data, but in order to also receive Ether
|
||||
it must be marked ``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
|
||||
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).
|
||||
|
||||
In the worst case, if a payable fallback function is also used in
|
||||
@ -392,7 +397,7 @@ operations as long as there is enough gas passed on to it.
|
||||
for the function selector and then
|
||||
you can use ``abi.decode`` together with the array slice syntax to
|
||||
decode ABI-encoded data:
|
||||
``(c, d) = abi.decode(input[4:], (uint256, uint256));``
|
||||
``(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.
|
||||
|
||||
@ -481,13 +486,13 @@ The following example shows overloading of the function
|
||||
pragma solidity >=0.4.16 <0.9.0;
|
||||
|
||||
contract A {
|
||||
function f(uint value) public pure returns (uint out) {
|
||||
out = value;
|
||||
function f(uint _in) public pure returns (uint out) {
|
||||
out = _in;
|
||||
}
|
||||
|
||||
function f(uint value, bool really) public pure returns (uint out) {
|
||||
if (really)
|
||||
out = value;
|
||||
function f(uint _in, bool _really) public pure returns (uint out) {
|
||||
if (_really)
|
||||
out = _in;
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,12 +506,12 @@ externally visible functions differ by their Solidity types but not by their ext
|
||||
|
||||
// This will not compile
|
||||
contract A {
|
||||
function f(B value) public pure returns (B out) {
|
||||
out = value;
|
||||
function f(B _in) public pure returns (B out) {
|
||||
out = _in;
|
||||
}
|
||||
|
||||
function f(address value) public pure returns (address out) {
|
||||
out = value;
|
||||
function f(address _in) public pure returns (address out) {
|
||||
out = _in;
|
||||
}
|
||||
}
|
||||
|
||||
@ -534,12 +539,12 @@ candidate, resolution fails.
|
||||
pragma solidity >=0.4.16 <0.9.0;
|
||||
|
||||
contract A {
|
||||
function f(uint8 val) public pure returns (uint8 out) {
|
||||
out = val;
|
||||
function f(uint8 _in) public pure returns (uint8 out) {
|
||||
out = _in;
|
||||
}
|
||||
|
||||
function f(uint256 val) public pure returns (uint256 out) {
|
||||
out = val;
|
||||
function f(uint256 _in) public pure returns (uint256 out) {
|
||||
out = _in;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ Details are given in the following example.
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.0 <0.9.0;
|
||||
// This will report a warning due to deprecated selfdestruct
|
||||
|
||||
|
||||
contract Owned {
|
||||
constructor() { owner = payable(msg.sender); }
|
||||
@ -54,7 +54,7 @@ Details are given in the following example.
|
||||
// accessed externally via `this`, though.
|
||||
contract Destructible is Owned {
|
||||
// The keyword `virtual` means that the function can change
|
||||
// its behavior in derived classes ("overriding").
|
||||
// its behaviour in derived classes ("overriding").
|
||||
function destroy() virtual public {
|
||||
if (msg.sender == owner) selfdestruct(owner);
|
||||
}
|
||||
@ -76,9 +76,9 @@ Details are given in the following example.
|
||||
}
|
||||
|
||||
|
||||
// Multiple inheritance is possible. Note that `Owned` is
|
||||
// Multiple inheritance is possible. Note that `owned` is
|
||||
// also a base class of `Destructible`, yet there is only a single
|
||||
// instance of `Owned` (as for virtual inheritance in C++).
|
||||
// instance of `owned` (as for virtual inheritance in C++).
|
||||
contract Named is Owned, Destructible {
|
||||
constructor(bytes32 name) {
|
||||
Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);
|
||||
@ -115,7 +115,7 @@ Details are given in the following example.
|
||||
|
||||
// Here, we only specify `override` and not `virtual`.
|
||||
// This means that contracts deriving from `PriceFeed`
|
||||
// cannot change the behavior of `destroy` anymore.
|
||||
// cannot change the behaviour of `destroy` anymore.
|
||||
function destroy() public override(Destructible, Named) { Named.destroy(); }
|
||||
function get() public view returns(uint r) { return info; }
|
||||
|
||||
@ -130,7 +130,6 @@ seen in the following example:
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.0 <0.9.0;
|
||||
// This will report a warning due to deprecated selfdestruct
|
||||
|
||||
contract owned {
|
||||
constructor() { owner = payable(msg.sender); }
|
||||
@ -163,7 +162,6 @@ explicitly in the final override, but this function will bypass
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.0 <0.9.0;
|
||||
// This will report a warning due to deprecated selfdestruct
|
||||
|
||||
contract owned {
|
||||
constructor() { owner = payable(msg.sender); }
|
||||
@ -293,7 +291,7 @@ and ends at a contract mentioning a function with that signature
|
||||
that does not override.
|
||||
|
||||
If you do not mark a function that overrides as ``virtual``, derived
|
||||
contracts can no longer change the behavior of that function.
|
||||
contracts can no longer change the behaviour of that function.
|
||||
|
||||
.. note::
|
||||
|
||||
@ -423,8 +421,8 @@ equivalent to ``constructor() {}``. For example:
|
||||
abstract contract A {
|
||||
uint public a;
|
||||
|
||||
constructor(uint a_) {
|
||||
a = a_;
|
||||
constructor(uint _a) {
|
||||
a = _a;
|
||||
}
|
||||
}
|
||||
|
||||
@ -436,16 +434,16 @@ You can use internal parameters in a constructor (for example storage pointers).
|
||||
the contract has to be marked :ref:`abstract <abstract-contract>`, because these parameters
|
||||
cannot be assigned valid values from outside but only through the constructors of derived contracts.
|
||||
|
||||
.. warning::
|
||||
.. warning ::
|
||||
Prior to version 0.4.22, constructors were defined as functions with the same name as the contract.
|
||||
This syntax was deprecated and is not allowed anymore in version 0.5.0.
|
||||
|
||||
.. warning::
|
||||
.. warning ::
|
||||
Prior to version 0.7.0, you had to specify the visibility of constructors as either
|
||||
``internal`` or ``public``.
|
||||
|
||||
|
||||
.. index:: ! base;constructor, inheritance list, contract;abstract, abstract contract
|
||||
.. index:: ! base;constructor
|
||||
|
||||
Arguments for Base Constructors
|
||||
===============================
|
||||
@ -461,7 +459,7 @@ derived contracts need to specify all of them. This can be done in two ways:
|
||||
|
||||
contract Base {
|
||||
uint x;
|
||||
constructor(uint x_) { x = x_; }
|
||||
constructor(uint _x) { x = _x; }
|
||||
}
|
||||
|
||||
// Either directly specify in the inheritance list...
|
||||
@ -469,25 +467,16 @@ derived contracts need to specify all of them. This can be done in two ways:
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
// or through a "modifier" of the derived constructor...
|
||||
// or through a "modifier" of the derived constructor.
|
||||
contract Derived2 is Base {
|
||||
constructor(uint y) Base(y * y) {}
|
||||
}
|
||||
|
||||
// or declare abstract...
|
||||
abstract contract Derived3 is Base {
|
||||
}
|
||||
|
||||
// and have the next concrete derived contract initialize it.
|
||||
contract DerivedFromDerived is Derived3 {
|
||||
constructor() Base(10 + 10) {}
|
||||
constructor(uint _y) 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
|
||||
the derived constructor (``Base(_y * _y)``). The first way to
|
||||
do it is more convenient if the constructor argument is a
|
||||
constant and defines the behavior of the contract or
|
||||
constant and defines the behaviour of the contract or
|
||||
describes it. The second way has to be used if the
|
||||
constructor arguments of the base depend on those of the
|
||||
derived contract. Arguments have to be given either in the
|
||||
@ -495,12 +484,7 @@ inheritance list or in modifier-style in the derived constructor.
|
||||
Specifying arguments in both places is an error.
|
||||
|
||||
If a derived contract does not specify the arguments to all of its base
|
||||
contracts' constructors, it must be declared abstract. In that case, when
|
||||
another contract derives from it, that other contract's inheritance list
|
||||
or constructor must provide the necessary parameters
|
||||
for all base classes that haven't had their parameters specified (otherwise,
|
||||
that other contract must be declared abstract as well). For example, in the above
|
||||
code snippet, see ``Derived3`` and ``DerivedFromDerived``.
|
||||
contracts' constructors, it will be abstract.
|
||||
|
||||
.. index:: ! inheritance;multiple, ! linearization, ! C3 linearization
|
||||
|
||||
|
@ -10,7 +10,7 @@ Interfaces are similar to abstract contracts, but they cannot have any functions
|
||||
There are further restrictions:
|
||||
|
||||
- They cannot inherit from other contracts, but they can inherit from other interfaces.
|
||||
- All declared functions must be external in the interface, even if they are public in the contract.
|
||||
- All declared functions must be external.
|
||||
- They cannot declare a constructor.
|
||||
- They cannot declare state variables.
|
||||
- They cannot declare modifiers.
|
||||
@ -65,7 +65,7 @@ inheritance.
|
||||
Types defined inside interfaces and other contract-like structures
|
||||
can be accessed from other contracts: ``Token.TokenType`` or ``Token.Coin``.
|
||||
|
||||
.. warning::
|
||||
.. warning:
|
||||
|
||||
Interfaces have supported ``enum`` types since :doc:`Solidity version 0.5.0 <050-breaking-changes>`, make
|
||||
sure the pragma version specifies this version as a minimum.
|
||||
|
@ -146,16 +146,16 @@ custom types without the overhead of external function calls:
|
||||
r.limbs[0] = x;
|
||||
}
|
||||
|
||||
function add(bigint memory a, bigint memory b) internal pure returns (bigint memory r) {
|
||||
r.limbs = new uint[](max(a.limbs.length, b.limbs.length));
|
||||
function add(bigint memory _a, bigint memory _b) internal pure returns (bigint memory r) {
|
||||
r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length));
|
||||
uint carry = 0;
|
||||
for (uint i = 0; i < r.limbs.length; ++i) {
|
||||
uint limbA = limb(a, i);
|
||||
uint limbB = limb(b, i);
|
||||
uint a = limb(_a, i);
|
||||
uint b = limb(_b, i);
|
||||
unchecked {
|
||||
r.limbs[i] = limbA + limbB + carry;
|
||||
r.limbs[i] = a + b + carry;
|
||||
|
||||
if (limbA + limbB < limbA || (limbA + limbB == type(uint).max && carry > 0))
|
||||
if (a + b < a || (a + b == type(uint).max && carry > 0))
|
||||
carry = 1;
|
||||
else
|
||||
carry = 0;
|
||||
@ -172,8 +172,8 @@ custom types without the overhead of external function calls:
|
||||
}
|
||||
}
|
||||
|
||||
function limb(bigint memory a, uint index) internal pure returns (uint) {
|
||||
return index < a.limbs.length ? a.limbs[index] : 0;
|
||||
function limb(bigint memory _a, uint _limb) internal pure returns (uint) {
|
||||
return _limb < _a.limbs.length ? _a.limbs[_limb] : 0;
|
||||
}
|
||||
|
||||
function max(uint a, uint b) private pure returns (uint) {
|
||||
@ -215,7 +215,7 @@ In comparison to contracts, libraries are restricted in the following ways:
|
||||
(These might be lifted at a later point.)
|
||||
|
||||
.. _library-selectors:
|
||||
.. index:: ! selector; of a library function
|
||||
.. index:: selector
|
||||
|
||||
Function Signatures and Selectors in Libraries
|
||||
==============================================
|
||||
|
@ -1,4 +1,4 @@
|
||||
.. index:: ! using for, library, ! operator;user-defined, function;free
|
||||
.. index:: ! using for, library
|
||||
|
||||
.. _using-for:
|
||||
|
||||
@ -6,146 +6,71 @@
|
||||
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
|
||||
The directive ``using A for B;`` can be used to attach library
|
||||
functions (from the library ``A``) to any type (``B``)
|
||||
in the context of a contract.
|
||||
These functions will receive the object they are called on
|
||||
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 effect of ``using A for *;`` is that the functions from
|
||||
the library ``A`` are attached to *any* type.
|
||||
|
||||
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,
|
||||
In both situations, *all* functions in the library are 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 <user-defined-value-types>` and the definition must be a ``pure`` function.
|
||||
Operator definitions must be global.
|
||||
The following operators can be defined this way:
|
||||
|
||||
+------------+----------+---------------------------------------------+
|
||||
| Category | Operator | Possible signatures |
|
||||
+============+==========+=============================================+
|
||||
| Bitwise | ``&`` | ``function (T, T) pure returns (T)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``|`` | ``function (T, T) pure returns (T)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``^`` | ``function (T, T) pure returns (T)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``~`` | ``function (T) pure returns (T)`` |
|
||||
+------------+----------+---------------------------------------------+
|
||||
| Arithmetic | ``+`` | ``function (T, T) pure returns (T)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``-`` | ``function (T, T) pure returns (T)`` |
|
||||
| + +---------------------------------------------+
|
||||
| | | ``function (T) pure returns (T)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``*`` | ``function (T, T) pure returns (T)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``/`` | ``function (T, T) pure returns (T)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``%`` | ``function (T, T) pure returns (T)`` |
|
||||
+------------+----------+---------------------------------------------+
|
||||
| Comparison | ``==`` | ``function (T, T) pure returns (bool)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``!=`` | ``function (T, T) pure returns (bool)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``<`` | ``function (T, T) pure returns (bool)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``<=`` | ``function (T, T) pure returns (bool)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``>`` | ``function (T, T) pure returns (bool)`` |
|
||||
| +----------+---------------------------------------------+
|
||||
| | ``>=`` | ``function (T, T) pure returns (bool)`` |
|
||||
+------------+----------+---------------------------------------------+
|
||||
|
||||
Note that unary and binary ``-`` need separate definitions.
|
||||
The compiler will choose the right definition based on how the operator is invoked.
|
||||
|
||||
The ``using A for B;`` directive is active only within the current
|
||||
scope (either the contract or the current module/source unit),
|
||||
including within all of its functions, and has no effect
|
||||
outside of the contract or module in which it is used.
|
||||
|
||||
When the directive is used at file level and applied to a
|
||||
user-defined type which was defined at file level in the same file,
|
||||
the word ``global`` can be added at the end. This will have the
|
||||
effect that the functions and operators are attached to the type everywhere
|
||||
the type is available (including other files), not only in the
|
||||
scope of the using statement.
|
||||
contract, including within all of its functions, and has no effect
|
||||
outside of the contract in which it is used. The directive
|
||||
may only be used inside a contract, not inside any of its functions.
|
||||
|
||||
Let us rewrite the set example from the
|
||||
:ref:`libraries` section in this way, using file-level functions
|
||||
instead of library functions.
|
||||
:ref:`libraries` in this way:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity ^0.8.13;
|
||||
pragma solidity >=0.6.0 <0.9.0;
|
||||
|
||||
|
||||
// This is the same code as before, just without comments
|
||||
struct Data { mapping(uint => bool) flags; }
|
||||
// Now we attach functions to the type.
|
||||
// The attached functions can be used throughout the rest of the module.
|
||||
// If you import the module, you have to
|
||||
// repeat the using directive there, for example as
|
||||
// import "flags.sol" as Flags;
|
||||
// using {Flags.insert, Flags.remove, Flags.contains}
|
||||
// for Flags.Data;
|
||||
using {insert, remove, contains} for Data;
|
||||
|
||||
function insert(Data storage self, uint value)
|
||||
returns (bool)
|
||||
{
|
||||
if (self.flags[value])
|
||||
return false; // already there
|
||||
self.flags[value] = true;
|
||||
return true;
|
||||
}
|
||||
library Set {
|
||||
function insert(Data storage self, uint value)
|
||||
public
|
||||
returns (bool)
|
||||
{
|
||||
if (self.flags[value])
|
||||
return false; // already there
|
||||
self.flags[value] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
function remove(Data storage self, uint value)
|
||||
returns (bool)
|
||||
{
|
||||
if (!self.flags[value])
|
||||
return false; // not there
|
||||
self.flags[value] = false;
|
||||
return true;
|
||||
}
|
||||
function remove(Data storage self, uint value)
|
||||
public
|
||||
returns (bool)
|
||||
{
|
||||
if (!self.flags[value])
|
||||
return false; // not there
|
||||
self.flags[value] = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function contains(Data storage self, uint value)
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return self.flags[value];
|
||||
function contains(Data storage self, uint value)
|
||||
public
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return self.flags[value];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contract C {
|
||||
using Set for Data; // this is the crucial change
|
||||
Data knownValues;
|
||||
|
||||
function register(uint value) public {
|
||||
@ -157,13 +82,12 @@ instead of library functions.
|
||||
}
|
||||
}
|
||||
|
||||
It is also possible to extend built-in types in that way.
|
||||
In this example, we will use a library.
|
||||
It is also possible to extend elementary types in that way:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity ^0.8.13;
|
||||
pragma solidity >=0.6.8 <0.9.0;
|
||||
|
||||
library Search {
|
||||
function indexOf(uint[] storage self, uint value)
|
||||
@ -176,61 +100,27 @@ In this example, we will use a library.
|
||||
return type(uint).max;
|
||||
}
|
||||
}
|
||||
using Search for uint[];
|
||||
|
||||
contract C {
|
||||
using Search for uint[];
|
||||
uint[] data;
|
||||
|
||||
function append(uint value) public {
|
||||
data.push(value);
|
||||
}
|
||||
|
||||
function replace(uint from, uint to) public {
|
||||
function replace(uint _old, uint _new) public {
|
||||
// This performs the library function call
|
||||
uint index = data.indexOf(from);
|
||||
uint index = data.indexOf(_old);
|
||||
if (index == type(uint).max)
|
||||
data.push(to);
|
||||
data.push(_new);
|
||||
else
|
||||
data[index] = to;
|
||||
data[index] = _new;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
if you pass memory or value types, a copy will be performed, even of the
|
||||
``self`` variable. The only situation where no copy will be performed
|
||||
is when storage reference variables are used or when internal library
|
||||
functions are called.
|
||||
|
||||
Another example shows how to define a custom operator for a user-defined type:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
type UFixed16x2 is uint16;
|
||||
|
||||
using {
|
||||
add as +,
|
||||
div as /
|
||||
} for UFixed16x2 global;
|
||||
|
||||
uint32 constant SCALE = 100;
|
||||
|
||||
function add(UFixed16x2 a, UFixed16x2 b) pure returns (UFixed16x2) {
|
||||
return UFixed16x2.wrap(UFixed16x2.unwrap(a) + UFixed16x2.unwrap(b));
|
||||
}
|
||||
|
||||
function div(UFixed16x2 a, UFixed16x2 b) pure returns (UFixed16x2) {
|
||||
uint32 a32 = UFixed16x2.unwrap(a);
|
||||
uint32 b32 = UFixed16x2.unwrap(b);
|
||||
uint32 result32 = a32 * SCALE / b32;
|
||||
require(result32 <= type(uint16).max, "Divide overflow");
|
||||
return UFixed16x2.wrap(uint16(a32 * SCALE / b32));
|
||||
}
|
||||
|
||||
contract Math {
|
||||
function avg(UFixed16x2 a, UFixed16x2 b) public pure returns (UFixed16x2) {
|
||||
return (a + b) / UFixed16x2.wrap(200);
|
||||
}
|
||||
}
|
||||
|
@ -200,12 +200,12 @@ The next example is more complex:
|
||||
struct Data {
|
||||
uint a;
|
||||
bytes3 b;
|
||||
mapping(uint => uint) map;
|
||||
mapping (uint => uint) map;
|
||||
uint[3] c;
|
||||
uint[] d;
|
||||
bytes e;
|
||||
}
|
||||
mapping(uint => mapping(bool => Data[])) public data;
|
||||
mapping (uint => mapping(bool => Data[])) public data;
|
||||
}
|
||||
|
||||
It generates a function of the following form. The mapping and arrays (with the
|
||||
|
@ -2,7 +2,7 @@
|
||||
Contributing
|
||||
############
|
||||
|
||||
Help is always welcome and there are plenty of options to contribute to Solidity.
|
||||
Help is always welcome and there are plenty of options how you can contribute to Solidity.
|
||||
|
||||
In particular, we appreciate support in the following areas:
|
||||
|
||||
@ -12,7 +12,7 @@ In particular, we appreciate support in the following areas:
|
||||
`"good first issue" <https://github.com/ethereum/solidity/labels/good%20first%20issue>`_ which are
|
||||
meant as introductory issues for external contributors.
|
||||
* Improving the documentation.
|
||||
* `Translating <https://github.com/solidity-docs>`_ the documentation into more languages.
|
||||
* Translating the documentation into more languages.
|
||||
* Responding to questions from other users on `StackExchange
|
||||
<https://ethereum.stackexchange.com>`_ and the `Solidity Gitter Chat
|
||||
<https://gitter.im/ethereum/solidity>`_.
|
||||
@ -22,17 +22,18 @@ 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.
|
||||
|
||||
Please note that this project is released with a `Contributor Code of Conduct <https://raw.githubusercontent.com/ethereum/solidity/develop/CODE_OF_CONDUCT.md>`_. By participating in this project — in the issues, pull requests, or Gitter channels — you agree to abide by its terms.
|
||||
Please note that this project is released with a `Contributor Code of Conduct <https://raw.githubusercontent.com/ethereum/solidity/develop/CODE_OF_CONDUCT.md>`_. By participating in this project - in the issues, pull requests, or Gitter channels - you agree to abide by its terms.
|
||||
|
||||
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:
|
||||
the team and contributors are working on, you can join our public team calls:
|
||||
|
||||
- Wednesdays at 3PM CET/CEST.
|
||||
- Mondays at 3pm CET/CEST.
|
||||
- Wednesdays at 2pm CET/CEST.
|
||||
|
||||
The call takes place on `Jitsi <https://meet.soliditylang.org/>`_.
|
||||
Both calls take place on `Jitsi <https://meet.ethereum.org/solidity>`_.
|
||||
|
||||
How to Report Issues
|
||||
====================
|
||||
@ -45,13 +46,10 @@ reporting issues, please mention the following details:
|
||||
* Source code (if applicable).
|
||||
* Operating system.
|
||||
* Steps to reproduce the issue.
|
||||
* Actual vs. expected behavior.
|
||||
* Actual vs. expected behaviour.
|
||||
|
||||
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 <https://forum.soliditylang.org/>`_ is the correct place (see :ref:`solidity_language_design`).
|
||||
very helpful and sometimes even clarifies a misunderstanding.
|
||||
|
||||
Workflow for Pull Requests
|
||||
==========================
|
||||
@ -69,7 +67,7 @@ Additionally, if you are writing a new feature, please ensure you add appropriat
|
||||
test cases under ``test/`` (see below).
|
||||
|
||||
However, if you are making a larger change, please consult with the `Solidity Development Gitter channel
|
||||
<https://gitter.im/ethereum/solidity-dev>`_ (different from the one mentioned above — this one is
|
||||
<https://gitter.im/ethereum/solidity-dev>`_ (different from the one mentioned above, this one is
|
||||
focused on compiler and language development instead of language usage) first.
|
||||
|
||||
New features and bugfixes should be added to the ``Changelog.md`` file: please
|
||||
@ -80,9 +78,6 @@ 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.
|
||||
|
||||
We highly recommend going through our `review checklist <https://github.com/ethereum/solidity/blob/develop/ReviewChecklist.md>`_ before submitting the pull request.
|
||||
We thoroughly review every PR and will help you get it right, but there are many common problems that can be easily avoided, making the review much smoother.
|
||||
|
||||
Thank you for your help!
|
||||
|
||||
Running the Compiler Tests
|
||||
@ -93,17 +88,18 @@ Prerequisites
|
||||
|
||||
For running all compiler tests you may want to optionally install a few
|
||||
dependencies (`evmone <https://github.com/ethereum/evmone/releases>`_,
|
||||
`libz3 <https://github.com/Z3Prover/z3>`_).
|
||||
`libz3 <https://github.com/Z3Prover/z3>`_, and
|
||||
`libhera <https://github.com/ewasm/hera>`_).
|
||||
|
||||
On macOS systems, some of the testing scripts expect GNU coreutils to be installed.
|
||||
On macOS some of the testing scripts expect GNU coreutils to be installed.
|
||||
This can be easiest accomplished using Homebrew: ``brew install coreutils``.
|
||||
|
||||
On Windows systems, make sure that you have a privilege to create symlinks,
|
||||
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 <https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/create-symbolic-links#policy-management>`_
|
||||
`grant it to other users <https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/create-symbolic-links#policy-management>`_
|
||||
or
|
||||
`enable Developer Mode <https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development>`_.
|
||||
`enable Developer Mode <https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development>`_.
|
||||
|
||||
Running the Tests
|
||||
-----------------
|
||||
@ -114,21 +110,27 @@ Running ``build/test/soltest`` or its wrapper ``scripts/soltest.sh`` is sufficie
|
||||
|
||||
The ``./scripts/tests.sh`` script executes most Solidity tests automatically,
|
||||
including those bundled into the `Boost C++ Test Framework <https://www.boost.org/doc/libs/release/libs/test/doc/html/index.html>`_
|
||||
application ``soltest`` (or its wrapper ``scripts/soltest.sh``), as well as command-line tests and
|
||||
application ``soltest`` (or its wrapper ``scripts/soltest.sh``), as well as command line tests and
|
||||
compilation tests.
|
||||
|
||||
The test system automatically tries to discover the location of
|
||||
the `evmone <https://github.com/ethereum/evmone/releases>`_ for running the semantic tests.
|
||||
|
||||
The ``evmone`` library must be located in the ``deps`` or ``deps/lib`` directory relative to the
|
||||
current working directory, to its parent or its parent's parent. Alternatively, an explicit location
|
||||
current working directory, to its parent or its parent's parent. Alternatively an explicit location
|
||||
for the ``evmone`` shared object can be specified via the ``ETH_EVMONE`` environment variable.
|
||||
|
||||
``evmone`` is needed mainly for running semantic and gas tests.
|
||||
If you do not have it installed, you can skip these tests by passing the ``--no-semantic-tests``
|
||||
flag to ``scripts/soltest.sh``.
|
||||
|
||||
The ``evmone`` library should both end with the file name
|
||||
Running Ewasm tests is disabled by default and can be explicitly enabled
|
||||
via ``./scripts/soltest.sh --ewasm`` and requires `hera <https://github.com/ewasm/hera>`_
|
||||
to be found by ``soltest``.
|
||||
The mechanism for locating the ``hera`` library is the same as for ``evmone``, except that the
|
||||
variable for specifying an explicit location is called ``ETH_HERA``.
|
||||
|
||||
The ``evmone`` and ``hera`` libraries should both end with the file name
|
||||
extension ``.so`` on Linux, ``.dll`` on Windows systems and ``.dylib`` on macOS.
|
||||
|
||||
For running SMT tests, the ``libz3`` library must be installed and locatable
|
||||
@ -139,7 +141,7 @@ SMT tests by exporting ``SMT_FLAGS=--no-smt`` before running ``./scripts/tests.s
|
||||
running ``./scripts/soltest.sh --no-smt``.
|
||||
These tests are ``libsolidity/smtCheckerTests`` and ``libsolidity/smtCheckerTestsJSON``.
|
||||
|
||||
.. note::
|
||||
.. note ::
|
||||
|
||||
To get a list of all unit tests run by Soltest, run ``./build/test/soltest --list_content=HRF``.
|
||||
|
||||
@ -160,7 +162,7 @@ See especially:
|
||||
- `run_test (-t) <https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/run_test.html>`_ to run specific tests cases, and
|
||||
- `report-level (-r) <https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/report_level.html>`_ give a more detailed report.
|
||||
|
||||
.. note::
|
||||
.. 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``.
|
||||
@ -168,7 +170,6 @@ See especially:
|
||||
|
||||
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:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||
@ -239,12 +240,12 @@ provides a way to edit, update or skip the current contract file, or quit the ap
|
||||
|
||||
It offers several options for failing tests:
|
||||
|
||||
- ``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).
|
||||
- ``edit``: ``isoltest`` tries to open the contract in an editor so you can adjust it. It either uses the editor given on the command line (as ``isoltest --editor /path/to/editor``), in the environment variable ``EDITOR`` or just ``/usr/bin/editor`` (in that order).
|
||||
- ``update``: Updates the expectations for contract under test. This updates the annotations by removing unmet expectations and adding missing expectations. The test is then run again.
|
||||
- ``skip``: Skips the execution of this particular test.
|
||||
- ``quit``: Quits ``isoltest``.
|
||||
|
||||
All of these options apply to the current contract, except ``quit`` which stops the entire testing process.
|
||||
All of these options apply to the current contract, expect ``quit`` which stops the entire testing process.
|
||||
|
||||
Automatically updating the test above changes it to
|
||||
|
||||
@ -269,62 +270,6 @@ and re-run the test. It now passes again:
|
||||
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.
|
||||
|
||||
Command-line Tests
|
||||
------------------
|
||||
|
||||
Our suite of end-to-end command-line tests checks the behaviour of the compiler binary as a whole
|
||||
in various scenarios.
|
||||
These tests are located in `test/cmdlineTests/ <https://github.com/ethereum/solidity/tree/develop/test/cmdlineTests>`_,
|
||||
one per subdirectory, and can be executed using the ``cmdlineTests.sh`` script.
|
||||
|
||||
By default the script runs all available tests.
|
||||
You can also provide one or more `file name patterns <https://www.gnu.org/software/bash/manual/bash.html#Filename-Expansion>`_,
|
||||
in which case only the tests matching at least one pattern will be executed.
|
||||
It is also possible to exclude files matching a specific pattern by prefixing it with ``--exclude``.
|
||||
|
||||
By default the script assumes that a ``solc`` binary is available inside the ``build/`` subdirectory
|
||||
inside the working copy.
|
||||
If you build the compiler outside of the source tree, you can use the ``SOLIDITY_BUILD_DIR`` environment
|
||||
variable to specify a different location for the build directory.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
export SOLIDITY_BUILD_DIR=~/solidity/build/
|
||||
test/cmdlineTests.sh "standard_*" "*_yul_*" --exclude "standard_yul_*"
|
||||
|
||||
The commands above will run tests from directories starting with ``test/cmdlineTests/standard_`` and
|
||||
subdirectories of ``test/cmdlineTests/`` that have ``_yul_`` somewhere in the name,
|
||||
but no test whose name starts with ``standard_yul_`` will be executed.
|
||||
It will also assume that the file ``solidity/build/solc/solc`` inside your home directory is the
|
||||
compiler binary (unless you are on Windows -- then ``solidity/build/solc/Release/solc.exe``).
|
||||
|
||||
There are several kinds of command-line tests:
|
||||
|
||||
- *Standard JSON test*: contains at least an ``input.json`` file.
|
||||
In general may contain:
|
||||
|
||||
- ``input.json``: input file to be passed to the ``--standard-json`` option on the command line.
|
||||
- ``output.json``: expected Standard JSON output.
|
||||
- ``args``: extra command-line arguments passed to ``solc``.
|
||||
|
||||
- *CLI test*: contains at least an ``input.*`` file (other than ``input.json``).
|
||||
In general may contain:
|
||||
|
||||
- ``input.*``: a single input file, whose name will be supplied to ``solc`` on the command line.
|
||||
Usually ``input.sol`` or ``input.yul``.
|
||||
- ``args``: extra command-line arguments passed to ``solc``.
|
||||
- ``stdin``: content to be passed to ``solc`` via standard input.
|
||||
- ``output``: expected content of the standard output.
|
||||
- ``err``: expected content of the standard error output.
|
||||
- ``exit``: expected exit code. If not provided, zero is expected.
|
||||
|
||||
- *Script test*: contains a ``test.*`` file.
|
||||
In general may contain:
|
||||
|
||||
- ``test.*``: a single script to run, usually ``test.sh`` or ``test.py``.
|
||||
The script must be executable.
|
||||
|
||||
Running the Fuzzer via AFL
|
||||
==========================
|
||||
@ -347,7 +292,7 @@ Next, build Solidity (or just the ``solfuzzer`` binary) with AFL as your compile
|
||||
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:
|
||||
At this stage you should be able to see a message similar to the following:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
@ -406,7 +351,7 @@ The AFL documentation states that the corpus (the initial input files) should no
|
||||
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.
|
||||
that result in similar behaviour of the binary.
|
||||
|
||||
Now run the fuzzer (the ``-m`` extends the size of memory to 60 MB):
|
||||
|
||||
@ -453,17 +398,18 @@ contributions to 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:
|
||||
Use English, with British English spelling preferred, 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 <https://en.wikipedia.org/wiki/Simplified_Technical_English>`_
|
||||
* `International English <https://en.wikipedia.org/wiki/International_English>`_
|
||||
* `British English spelling <https://en.oxforddictionaries.com/spelling/british-and-spelling>`_
|
||||
|
||||
|
||||
.. 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 <https://github.com/solidity-docs#solidity-documentation-translation-guide>`_
|
||||
in other languages available. Please refer to the `translation guide <https://github.com/solidity-docs/translation-guide>`_
|
||||
for information on how to contribute to the community translations.
|
||||
|
||||
Title Case for Headings
|
||||
@ -529,15 +475,13 @@ For example ``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
|
||||
Make sure your contributions pass our documentation tests by running ``./scripts/docs.sh`` that installs dependencies
|
||||
needed for documentation and checks for any problems such as broken links or syntax issues.
|
||||
|
||||
.. _solidity_language_design:
|
||||
|
||||
Solidity Language Design
|
||||
========================
|
||||
|
||||
To actively get involved in the language design process and to share your ideas concerning the future of Solidity,
|
||||
To actively get involved in the language design process and share your ideas concerning the future of Solidity,
|
||||
please join the `Solidity forum <https://forum.soliditylang.org/>`_.
|
||||
|
||||
The Solidity forum serves as the place to propose and discuss new language features and their implementation in
|
||||
@ -556,7 +500,7 @@ If you want to know where the team is standing in terms or implementing new feat
|
||||
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 <https://github.com/ethereum/solidity/tree/breaking>`_.
|
||||
|
||||
For ad-hoc cases and questions, you can reach out to us via the `Solidity-dev Gitter channel <https://gitter.im/ethereum/solidity-dev>`_ — a
|
||||
For ad-hoc cases and questions you can reach out to us via the `Solidity-dev Gitter channel <https://gitter.im/ethereum/solidity-dev>`_, a
|
||||
dedicated chatroom for conversations around the Solidity compiler and language development.
|
||||
|
||||
We are happy to hear your thoughts on how we can improve the language design process to be even more collaborative and transparent.
|
||||
|
@ -150,8 +150,8 @@ throws an exception or goes out of gas.
|
||||
use ``f.value(x).gas(g)()``. This was deprecated in Solidity 0.6.2 and is no
|
||||
longer possible since Solidity 0.7.0.
|
||||
|
||||
Function Calls with Named Parameters
|
||||
------------------------------------
|
||||
Named Calls and Anonymous Function Parameters
|
||||
---------------------------------------------
|
||||
|
||||
Function call arguments can be given by name, in any order,
|
||||
if they are enclosed in ``{ }`` as can be seen in the following
|
||||
@ -173,15 +173,14 @@ parameters from the function declaration, but can be in arbitrary order.
|
||||
function set(uint key, uint value) public {
|
||||
data[key] = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Omitted Names in Function Definitions
|
||||
-------------------------------------
|
||||
Omitted Function Parameter Names
|
||||
--------------------------------
|
||||
|
||||
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.
|
||||
The names of unused parameters (especially return parameters) can be omitted.
|
||||
Those parameters will still be present on the stack, but they are inaccessible.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
@ -284,7 +283,7 @@ which only need to be created if there is a dispute.
|
||||
salt,
|
||||
keccak256(abi.encodePacked(
|
||||
type(D).creationCode,
|
||||
abi.encode(arg)
|
||||
arg
|
||||
))
|
||||
)))));
|
||||
|
||||
@ -365,13 +364,13 @@ i.e. the following is not valid: ``(x, uint y) = (1, 2);``
|
||||
.. warning::
|
||||
Be careful when assigning to multiple variables at the same time when
|
||||
reference types are involved, because it could lead to unexpected
|
||||
copying behavior.
|
||||
copying behaviour.
|
||||
|
||||
Complications for Arrays and Structs
|
||||
------------------------------------
|
||||
|
||||
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 <data-location-assignment>` for details.
|
||||
including ``bytes`` and ``string``, see :ref:`Data location and assignment behaviour <data-location-assignment>` for details.
|
||||
|
||||
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``
|
||||
@ -510,7 +509,7 @@ additional checks.
|
||||
Since Solidity 0.8.0, all arithmetic operations revert on over- and underflow by default,
|
||||
thus making the use of these libraries unnecessary.
|
||||
|
||||
To obtain the previous behavior, an ``unchecked`` block can be used:
|
||||
To obtain the previous behaviour, an ``unchecked`` block can be used:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
@ -650,7 +649,7 @@ in the following situations:
|
||||
|
||||
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):
|
||||
an `Error` or a `Panic` (or whatever else was given):
|
||||
|
||||
#. If a ``.transfer()`` fails.
|
||||
#. If you call a function via a message call but it does not finish
|
||||
@ -685,7 +684,7 @@ and ``assert`` for internal error checking.
|
||||
addr.transfer(msg.value / 2);
|
||||
// Since transfer throws an exception on failure and
|
||||
// cannot call back here, there should be no way for us to
|
||||
// still have half of the Ether.
|
||||
// still have half of the money.
|
||||
assert(address(this).balance == balanceBeforeTransfer - msg.value / 2);
|
||||
return address(this).balance;
|
||||
}
|
||||
@ -719,7 +718,7 @@ The ``revert`` statement takes a custom error as direct argument without parenth
|
||||
|
||||
revert CustomError(arg1, arg2);
|
||||
|
||||
For backward-compatibility reasons, there is also the ``revert()`` function, which uses parentheses
|
||||
For backwards-compatibility reasons, there is also the ``revert()`` function, which uses parentheses
|
||||
and accepts a string:
|
||||
|
||||
revert();
|
||||
|
@ -16,11 +16,11 @@ Simple Open Auction
|
||||
===================
|
||||
|
||||
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
|
||||
send their bids during a bidding period. The bids already include sending money
|
||||
/ Ether in order to bind the bidders to their bid. If the highest bid is
|
||||
raised, the previous highest bidder gets their money 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.
|
||||
to receive their money - contracts cannot activate themselves.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
@ -92,19 +92,19 @@ to receive their Ether - contracts cannot activate themselves.
|
||||
revert AuctionAlreadyEnded();
|
||||
|
||||
// If the bid is not higher, send the
|
||||
// Ether back (the revert statement
|
||||
// money back (the revert statement
|
||||
// will revert all changes in this
|
||||
// function execution including
|
||||
// it having received the Ether).
|
||||
// it having received the money).
|
||||
if (msg.value <= highestBid)
|
||||
revert BidNotHighEnough(highestBid);
|
||||
|
||||
if (highestBid != 0) {
|
||||
// Sending back the Ether by simply using
|
||||
// Sending back the money 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.
|
||||
// withdraw their money themselves.
|
||||
pendingReturns[highestBidder] += highestBid;
|
||||
}
|
||||
highestBidder = msg.sender;
|
||||
@ -177,19 +177,19 @@ 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 bidders have to reveal their bids: They send their values unencrypted and
|
||||
the contract checks that the hash value is the same as the one provided during
|
||||
the bidding period.
|
||||
|
||||
Another challenge is how to make the auction **binding and blind** at the same
|
||||
time: The only way to prevent the bidder from just not sending the Ether after
|
||||
time: The only way to prevent the bidder from just not sending the money after
|
||||
they won the auction is to make them send it together with the bid. Since value
|
||||
transfers cannot be blinded in Ethereum, anyone can see the value.
|
||||
|
||||
The following contract solves this problem by accepting any value that is
|
||||
larger than the highest bid. Since this can of course only be checked during
|
||||
the reveal phase, some bids might be **invalid**, and this is on purpose (it
|
||||
even provides an explicit flag to place invalid bids with high-value
|
||||
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.
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
Micropayment Channel
|
||||
********************
|
||||
|
||||
In this section, we will learn how to build an example implementation
|
||||
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
|
||||
@ -17,14 +17,14 @@ Alice is the sender and Bob is the recipient.
|
||||
Alice only needs to send cryptographically signed messages off-chain
|
||||
(e.g. via email) to Bob and it is similar to writing checks.
|
||||
|
||||
Alice and Bob use signatures to authorize transactions, which is possible with smart contracts on Ethereum.
|
||||
Alice and Bob use signatures to authorise 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.
|
||||
|
||||
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.
|
||||
2. Alice authorises 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
|
||||
@ -36,7 +36,7 @@ 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 <https://github.com/web3/web3.js>`_ and
|
||||
using `web3.js <https://github.com/ethereum/web3.js>`_ and
|
||||
`MetaMask <https://metamask.io>`_, using the method described in `EIP-712 <https://github.com/ethereum/EIPs/pull/712>`_,
|
||||
as it provides a number of other security benefits.
|
||||
|
||||
@ -86,7 +86,7 @@ Packing arguments
|
||||
Now that we have identified what information to include in the signed message,
|
||||
we are ready to put the message together, hash it, and sign it. For simplicity,
|
||||
we concatenate the data. The `ethereumjs-abi <https://github.com/ethereumjs/ethereumjs-abi>`_
|
||||
library provides a function called ``soliditySHA3`` that mimics the behavior of
|
||||
library provides a function called ``soliditySHA3`` that mimics the behaviour of
|
||||
Solidity's ``keccak256`` function applied to arguments encoded using ``abi.encodePacked``.
|
||||
Here is a JavaScript function that creates the proper signature for the ``ReceiverPays`` example:
|
||||
|
||||
@ -144,7 +144,6 @@ 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
|
||||
contract ReceiverPays {
|
||||
address owner = msg.sender;
|
||||
|
||||
@ -260,7 +259,7 @@ Messages are cryptographically signed by the sender and then transmitted directl
|
||||
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.
|
||||
* The total amount of Ether that is owed the recipient so far.
|
||||
|
||||
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
|
||||
@ -342,7 +341,6 @@ 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
|
||||
contract SimplePaymentChannel {
|
||||
address payable public sender; // The account sending payments.
|
||||
address payable public recipient; // The account receiving the payments.
|
||||
|
@ -7,7 +7,7 @@ Modular Contracts
|
||||
A modular approach to building your contracts helps you reduce the complexity
|
||||
and improve the readability which will help to identify bugs and vulnerabilities
|
||||
during development and code review.
|
||||
If you specify and control the behavior of each module in isolation, the
|
||||
If you specify and control the behaviour or each module in isolation, the
|
||||
interactions you have to consider are only those between the module specifications
|
||||
and not every other moving part of the contract.
|
||||
In the example below, the contract uses the ``move`` method
|
||||
@ -34,7 +34,7 @@ and the sum of all balances is an invariant across the lifetime of the contract.
|
||||
contract Token {
|
||||
mapping(address => uint256) balances;
|
||||
using Balances for *;
|
||||
mapping(address => mapping(address => uint256)) allowed;
|
||||
mapping(address => mapping (address => uint256)) allowed;
|
||||
|
||||
event Transfer(address from, address to, uint amount);
|
||||
event Approval(address owner, address spender, uint amount);
|
||||
|
@ -6,18 +6,18 @@ Safe Remote Purchase
|
||||
|
||||
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,
|
||||
an item from the seller and the seller would like to get money (or an equivalent)
|
||||
in return. The problematic part is the shipment here: There is no way to determine for
|
||||
sure that the item arrived at the buyer.
|
||||
|
||||
There are multiple ways to solve this problem, but all fall short in one or the other way.
|
||||
In the following example, both parties have to put twice the value of the item into the
|
||||
contract as escrow. As soon as this happened, the Ether will stay locked inside
|
||||
contract as escrow. As soon as this happened, the money will stay locked inside
|
||||
the contract until the buyer confirms that they received the item. After that,
|
||||
the buyer is returned the value (half of their deposit) and the seller gets three
|
||||
times the value (their deposit plus the value). The idea behind
|
||||
this is that both parties have an incentive to resolve the situation or otherwise
|
||||
their Ether is locked forever.
|
||||
their money is locked forever.
|
||||
|
||||
This contract of course does not solve the problem, but gives an overview of how
|
||||
you can use state machine-like constructs inside a contract.
|
||||
|
@ -109,7 +109,6 @@ of votes.
|
||||
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.");
|
||||
@ -129,16 +128,14 @@ of votes.
|
||||
require(to != msg.sender, "Found loop in delegation.");
|
||||
}
|
||||
|
||||
// Since `sender` is a reference, this
|
||||
// modifies `voters[msg.sender].voted`
|
||||
Voter storage delegate_ = voters[to];
|
||||
|
||||
// Voters cannot delegate to accounts that cannot vote.
|
||||
// Voters cannot delegate to wallets that cannot vote.
|
||||
require(delegate_.weight >= 1);
|
||||
|
||||
// Since `sender` is a reference, this
|
||||
// modifies `voters[msg.sender]`.
|
||||
sender.voted = true;
|
||||
sender.delegate = to;
|
||||
|
||||
if (delegate_.voted) {
|
||||
// If the delegate already voted,
|
||||
// directly add to the number of votes
|
||||
@ -193,8 +190,5 @@ 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?
|
||||
Currently, many transactions are needed to assign the rights
|
||||
to vote to all participants. Can you think of a better way?
|
||||
|
@ -22,16 +22,23 @@ def remix_code_url(source_code, language, solidity_version):
|
||||
# NOTE: base64 encoded data may contain +, = and / characters. Remix seems to handle them just
|
||||
# fine without any escaping.
|
||||
base64_encoded_source = base64.b64encode(source_code.encode('utf-8')).decode('ascii')
|
||||
return f"https://remix.ethereum.org/?#language={language}&version={solidity_version}&code={base64_encoded_source}"
|
||||
return f"https://remix.ethereum.org/?language={language}&version={solidity_version}&code={base64_encoded_source}"
|
||||
|
||||
|
||||
def build_remix_link_node(url):
|
||||
reference_node = docutils.nodes.reference('', 'open in Remix', internal=False, refuri=url, target='_blank')
|
||||
link_icon_node = docutils.nodes.inline()
|
||||
link_icon_node.set_class('link-icon')
|
||||
|
||||
link_text_node = docutils.nodes.inline(text="open in Remix")
|
||||
link_text_node.set_class('link-text')
|
||||
|
||||
reference_node = docutils.nodes.reference('', '', internal=False, refuri=url)
|
||||
reference_node.set_class('remix-link')
|
||||
reference_node += [link_icon_node, link_text_node]
|
||||
|
||||
paragraph_node = docutils.nodes.paragraph()
|
||||
paragraph_node.set_class('remix-link-container')
|
||||
paragraph_node.append(reference_node)
|
||||
paragraph_node += reference_node
|
||||
return paragraph_node
|
||||
|
||||
|
||||
@ -42,24 +49,22 @@ def insert_remix_link(app, doctree, solidity_version):
|
||||
for literal_block_node in doctree.traverse(docutils.nodes.literal_block):
|
||||
assert 'language' in literal_block_node.attributes
|
||||
language = literal_block_node.attributes['language'].lower()
|
||||
if language not in ['solidity', 'yul']:
|
||||
continue
|
||||
if language in ['solidity', 'yul']:
|
||||
text_nodes = list(literal_block_node.traverse(docutils.nodes.Text))
|
||||
assert len(text_nodes) == 1
|
||||
|
||||
text_nodes = list(literal_block_node.traverse(docutils.nodes.Text))
|
||||
assert len(text_nodes) == 1
|
||||
remix_url = remix_code_url(text_nodes[0], language, solidity_version)
|
||||
url_length = len(remix_url.encode('utf-8'))
|
||||
if url_length > MAX_SAFE_URL_LENGTH:
|
||||
logger.warning(
|
||||
"Remix URL generated from the code snippet exceeds the maximum safe URL length "
|
||||
" (%d > %d bytes).",
|
||||
url_length,
|
||||
MAX_SAFE_URL_LENGTH,
|
||||
location=(literal_block_node.source, literal_block_node.line),
|
||||
)
|
||||
|
||||
remix_url = remix_code_url(text_nodes[0], language, solidity_version)
|
||||
url_length = len(remix_url.encode('utf-8'))
|
||||
if url_length > MAX_SAFE_URL_LENGTH:
|
||||
logger.warning(
|
||||
"Remix URL generated from the code snippet exceeds the maximum safe URL length "
|
||||
" (%d > %d bytes).",
|
||||
url_length,
|
||||
MAX_SAFE_URL_LENGTH,
|
||||
location=(literal_block_node.source, literal_block_node.line),
|
||||
)
|
||||
|
||||
insert_node_before(literal_block_node, build_remix_link_node(remix_url))
|
||||
insert_node_before(literal_block_node, build_remix_link_node(remix_url))
|
||||
|
||||
|
||||
def setup(app):
|
||||
|
@ -9,9 +9,10 @@ ReservedKeywords:
|
||||
| 'partial' | 'promise' | 'reference' | 'relocatable' | 'sealed' | 'sizeof' | 'static'
|
||||
| 'supports' | 'switch' | 'typedef' | 'typeof' | 'var';
|
||||
|
||||
Pragma: 'pragma' -> pushMode(PragmaMode);
|
||||
Abstract: 'abstract';
|
||||
Address: 'address';
|
||||
Anonymous: 'anonymous';
|
||||
Address: 'address';
|
||||
As: 'as';
|
||||
Assembly: 'assembly' -> pushMode(AssemblyBlockMode);
|
||||
Bool: 'bool';
|
||||
@ -29,11 +30,13 @@ Else: 'else';
|
||||
Emit: 'emit';
|
||||
Enum: 'enum';
|
||||
Error: 'error'; // not a real keyword
|
||||
Revert: 'revert'; // not a real keyword
|
||||
Event: 'event';
|
||||
External: 'external';
|
||||
Fallback: 'fallback';
|
||||
False: 'false';
|
||||
Fixed: 'fixed' | ('fixed' [1-9][0-9]* 'x' [1-9][0-9]*);
|
||||
From: 'from'; // not a real keyword
|
||||
/**
|
||||
* Bytes types of fixed length.
|
||||
*/
|
||||
@ -43,9 +46,7 @@ FixedBytes:
|
||||
'bytes17' | 'bytes18' | 'bytes19' | 'bytes20' | 'bytes21' | 'bytes22' | 'bytes23' | 'bytes24' |
|
||||
'bytes25' | 'bytes26' | 'bytes27' | 'bytes28' | 'bytes29' | 'bytes30' | 'bytes31' | 'bytes32';
|
||||
For: 'for';
|
||||
From: 'from'; // not a real keyword
|
||||
Function: 'function';
|
||||
Global: 'global'; // not a real keyword
|
||||
Hex: 'hex';
|
||||
If: 'if';
|
||||
Immutable: 'immutable';
|
||||
@ -62,17 +63,15 @@ New: 'new';
|
||||
/**
|
||||
* Unit denomination for numbers.
|
||||
*/
|
||||
SubDenomination: 'wei' | 'gwei' | 'ether' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years';
|
||||
NumberUnit: 'wei' | 'gwei' | 'ether' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years';
|
||||
Override: 'override';
|
||||
Payable: 'payable';
|
||||
Pragma: 'pragma' -> pushMode(PragmaMode);
|
||||
Private: 'private';
|
||||
Public: 'public';
|
||||
Pure: 'pure';
|
||||
Receive: 'receive';
|
||||
Return: 'return';
|
||||
Returns: 'returns';
|
||||
Revert: 'revert'; // not a real keyword
|
||||
/**
|
||||
* Sized signed integer types.
|
||||
* int is an alias of int256.
|
||||
@ -90,7 +89,6 @@ Try: 'try';
|
||||
Type: 'type';
|
||||
Ufixed: 'ufixed' | ('ufixed' [1-9][0-9]+ 'x' [1-9][0-9]+);
|
||||
Unchecked: 'unchecked';
|
||||
Unicode: 'unicode';
|
||||
/**
|
||||
* Sized unsigned integer types.
|
||||
* uint is an alias of uint256.
|
||||
@ -199,7 +197,9 @@ fragment EscapeSequence:
|
||||
/**
|
||||
* A single quoted string literal allowing arbitrary unicode characters.
|
||||
*/
|
||||
UnicodeStringLiteral: 'unicode' (('"' DoubleQuotedUnicodeStringCharacter* '"') | ('\'' SingleQuotedUnicodeStringCharacter* '\''));
|
||||
UnicodeStringLiteral:
|
||||
'unicode"' DoubleQuotedUnicodeStringCharacter* '"'
|
||||
| 'unicode\'' SingleQuotedUnicodeStringCharacter* '\'';
|
||||
//@doc:inline
|
||||
fragment DoubleQuotedUnicodeStringCharacter: ~["\r\n\\] | EscapeSequence;
|
||||
//@doc:inline
|
||||
@ -221,14 +221,6 @@ fragment EvenHexDigits: HexCharacter HexCharacter ('_'? HexCharacter HexCharacte
|
||||
//@doc:inline
|
||||
fragment HexCharacter: [0-9A-Fa-f];
|
||||
|
||||
/**
|
||||
* Scanned but not used by any rule, i.e, disallowed.
|
||||
* solc parser considers number starting with '0', not immediately followed by '.' or 'x' as
|
||||
* octal, even if non octal digits '8' and '9' are present.
|
||||
*/
|
||||
OctalNumber: '0' DecimalDigits ('.' DecimalDigits)?;
|
||||
|
||||
|
||||
/**
|
||||
* A decimal number literal consists of decimal digits that may be delimited by underscores and
|
||||
* an optional positive or negative exponent.
|
||||
@ -239,12 +231,6 @@ DecimalNumber: (DecimalDigits | (DecimalDigits? '.' DecimalDigits)) ([eE] '-'? D
|
||||
fragment DecimalDigits: [0-9] ('_'? [0-9])* ;
|
||||
|
||||
|
||||
/**
|
||||
* This is needed to avoid successfully parsing a number followed by a string with no whitespace between.
|
||||
*/
|
||||
DecimalNumberFollowedByIdentifier: DecimalNumber Identifier;
|
||||
|
||||
|
||||
/**
|
||||
* An identifier in solidity has to start with a letter, a dollar-sign or an underscore and
|
||||
* may additionally contain numbers after the first symbol.
|
||||
@ -265,12 +251,6 @@ mode AssemblyBlockMode;
|
||||
AssemblyDialect: '"evmasm"';
|
||||
AssemblyLBrace: '{' -> popMode, pushMode(YulMode);
|
||||
|
||||
AssemblyFlagString: '"' DoubleQuotedStringCharacter+ '"';
|
||||
|
||||
AssemblyBlockLParen: '(';
|
||||
AssemblyBlockRParen: ')';
|
||||
AssemblyBlockComma: ',';
|
||||
|
||||
AssemblyBlockWS: [ \t\r\n\u000C]+ -> skip ;
|
||||
AssemblyBlockCOMMENT: '/*' .*? '*/' -> channel(HIDDEN) ;
|
||||
AssemblyBlockLINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN) ;
|
||||
@ -304,8 +284,8 @@ YulEVMBuiltin:
|
||||
| 'returndatacopy' | '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' | 'coinbase' | 'timestamp' | 'number' | 'difficulty' | 'gaslimit'
|
||||
| 'basefee';
|
||||
|
||||
YulLBrace: '{' -> pushMode(YulMode);
|
||||
YulRBrace: '}' -> popMode;
|
||||
|
@ -12,7 +12,6 @@ options { tokenVocab=SolidityLexer; }
|
||||
sourceUnit: (
|
||||
pragmaDirective
|
||||
| importDirective
|
||||
| usingDirective
|
||||
| contractDefinition
|
||||
| interfaceDefinition
|
||||
| libraryDefinition
|
||||
@ -22,7 +21,6 @@ sourceUnit: (
|
||||
| enumDefinition
|
||||
| userDefinedValueTypeDefinition
|
||||
| errorDefinition
|
||||
| eventDefinition
|
||||
)* EOF;
|
||||
|
||||
//@doc: inline
|
||||
@ -153,7 +151,7 @@ stateMutability: Pure | View | Payable;
|
||||
*/
|
||||
overrideSpecifier: Override (LParen overrides+=identifierPath (Comma overrides+=identifierPath)* RParen)?;
|
||||
/**
|
||||
* The definition of contract, library, interface or free functions.
|
||||
* The definition of contract, library and interface 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.
|
||||
*/
|
||||
@ -162,7 +160,7 @@ locals[
|
||||
boolean visibilitySet = false,
|
||||
boolean mutabilitySet = false,
|
||||
boolean virtualSet = false,
|
||||
boolean overrideSpecifierSet = false,
|
||||
boolean overrideSpecifierSet = false
|
||||
]
|
||||
:
|
||||
Function (identifier | Fallback | Receive)
|
||||
@ -176,7 +174,6 @@ locals[
|
||||
)*
|
||||
(Returns LParen returnParameters=parameterList RParen)?
|
||||
(Semicolon | body=block);
|
||||
|
||||
/**
|
||||
* The definition of a modifier.
|
||||
* Note that within the body block of a modifier, the underscore cannot be used as identifier,
|
||||
@ -314,30 +311,10 @@ errorDefinition:
|
||||
Semicolon;
|
||||
|
||||
/**
|
||||
* Operators that users are allowed to implement for some types with `using for`.
|
||||
* Using directive to bind library functions to types.
|
||||
* Can occur within contracts and libraries.
|
||||
*/
|
||||
userDefinableOperator:
|
||||
BitAnd
|
||||
| BitNot
|
||||
| BitOr
|
||||
| BitXor
|
||||
| Add
|
||||
| Div
|
||||
| Mod
|
||||
| Mul
|
||||
| Sub
|
||||
| Equal
|
||||
| GreaterThan
|
||||
| GreaterThanOrEqual
|
||||
| LessThan
|
||||
| LessThanOrEqual
|
||||
| NotEqual;
|
||||
|
||||
/**
|
||||
* Using directive to attach library functions and free functions to types.
|
||||
* Can occur within contracts and libraries and at the file level.
|
||||
*/
|
||||
usingDirective: Using (identifierPath | (LBrace identifierPath (As userDefinableOperator)? (Comma identifierPath (As userDefinableOperator)?)* RBrace)) For (Mul | typeName) Global? Semicolon;
|
||||
usingDirective: Using identifierPath For (Mul | typeName) Semicolon;
|
||||
/**
|
||||
* 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.
|
||||
@ -369,7 +346,7 @@ dataLocation: Memory | Storage | Calldata;
|
||||
*/
|
||||
expression:
|
||||
expression LBrack index=expression? RBrack # IndexAccess
|
||||
| expression LBrack startIndex=expression? Colon endIndex=expression? RBrack # IndexRangeAccess
|
||||
| expression LBrack start=expression? Colon end=expression? RBrack # IndexRangeAccess
|
||||
| expression Period (identifier | Address) # MemberAccess
|
||||
| expression LBrace (namedArgument (Comma namedArgument)*)? RBrace # FunctionCallOptions
|
||||
| expression callArgumentList # FunctionCall
|
||||
@ -390,13 +367,12 @@ expression:
|
||||
| expression Or expression # OrOperation
|
||||
|<assoc=right> expression Conditional expression Colon expression # Conditional
|
||||
|<assoc=right> expression assignOp expression # Assignment
|
||||
| New typeName # NewExpr
|
||||
| New typeName # NewExpression
|
||||
| tupleExpression # Tuple
|
||||
| inlineArrayExpression # InlineArray
|
||||
| (
|
||||
identifier
|
||||
| literal
|
||||
| literalWithSubDenomination
|
||||
| elementaryTypeName[false]
|
||||
) # PrimaryExpression
|
||||
;
|
||||
@ -412,12 +388,9 @@ inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack;
|
||||
/**
|
||||
* Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers.
|
||||
*/
|
||||
identifier: Identifier | From | Error | Revert | Global;
|
||||
identifier: Identifier | From | Error | Revert;
|
||||
|
||||
literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral;
|
||||
|
||||
literalWithSubDenomination: numberLiteral SubDenomination;
|
||||
|
||||
booleanLiteral: True | False;
|
||||
/**
|
||||
* A full string literal consists of either one or several consecutive quoted strings.
|
||||
@ -435,8 +408,7 @@ unicodeStringLiteral: UnicodeStringLiteral+;
|
||||
/**
|
||||
* Number literals can be decimal or hexadecimal numbers with an optional unit.
|
||||
*/
|
||||
numberLiteral: DecimalNumber | HexNumber;
|
||||
|
||||
numberLiteral: (DecimalNumber | HexNumber) NumberUnit?;
|
||||
/**
|
||||
* A curly-braced block of statements. Opens its own scope.
|
||||
*/
|
||||
@ -504,13 +476,7 @@ revertStatement: Revert expression callArgumentList Semicolon;
|
||||
* The contents of an inline assembly block use a separate scanner/lexer, i.e. the set of keywords and
|
||||
* allowed identifiers is different inside an inline assembly block.
|
||||
*/
|
||||
assemblyStatement: Assembly AssemblyDialect? assemblyFlags? AssemblyLBrace yulStatement* YulRBrace;
|
||||
|
||||
/**
|
||||
* Assembly flags.
|
||||
* Comma-separated list of double-quoted strings as flags.
|
||||
*/
|
||||
assemblyFlags: AssemblyBlockLParen AssemblyFlagString (AssemblyBlockComma AssemblyFlagString)* AssemblyBlockRParen;
|
||||
assemblyStatement: Assembly AssemblyDialect? AssemblyLBrace yulStatement* YulRBrace;
|
||||
|
||||
//@doc:inline
|
||||
variableDeclarationList: variableDeclarations+=variableDeclaration (Comma variableDeclarations+=variableDeclaration)*;
|
||||
@ -531,7 +497,7 @@ variableDeclarationTuple:
|
||||
variableDeclarationStatement: ((variableDeclaration (Assign expression)?) | (variableDeclarationTuple Assign expression)) Semicolon;
|
||||
expressionStatement: expression Semicolon;
|
||||
|
||||
mappingType: Mapping LParen key=mappingKeyType name=identifier? DoubleArrow value=typeName name=identifier? RParen;
|
||||
mappingType: Mapping LParen key=mappingKeyType DoubleArrow value=typeName RParen;
|
||||
/**
|
||||
* Only elementary types or user defined types are viable as mapping keys.
|
||||
*/
|
||||
|
126
docs/index.rst
@ -1,35 +1,40 @@
|
||||
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.
|
||||
Solidity is an object-oriented, high-level language for implementing smart
|
||||
contracts. Smart contracts are programs which govern the behaviour of accounts
|
||||
within the Ethereum state.
|
||||
|
||||
Solidity is a `curly-bracket language <https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Curly-bracket_languages>`_ 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 <language-influences>` section.
|
||||
Solidity is a `curly-bracket language <https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Curly-bracket_languages>`_.
|
||||
It is influenced by C++, Python and JavaScript, and is designed to target the Ethereum Virtual Machine (EVM).
|
||||
You can find more details about which languages Solidity has been inspired by in
|
||||
the :doc:`language influences <language-influences>` section.
|
||||
|
||||
Solidity is statically typed, supports inheritance, libraries, and complex user-defined types, among other features.
|
||||
Solidity is statically typed, supports inheritance, libraries and complex
|
||||
user-defined types among other features.
|
||||
|
||||
With Solidity, you can create contracts for uses such as voting, crowdfunding, blind auctions, and multi-signature wallets.
|
||||
With Solidity you can create contracts for uses such as voting, crowdfunding, blind auctions,
|
||||
and multi-signature wallets.
|
||||
|
||||
When deploying contracts, you should use the latest released version of Solidity.
|
||||
Apart from exceptional cases, only the latest version receives
|
||||
When deploying contracts, you should use the latest released
|
||||
version of Solidity. Apart from exceptional cases, only the latest version receives
|
||||
`security fixes <https://github.com/ethereum/solidity/security/policy#supported-versions>`_.
|
||||
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 <https://semver.org/#spec-item-4>`_.
|
||||
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 <https://semver.org/#spec-item-4>`_.
|
||||
|
||||
.. 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 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>`.
|
||||
|
||||
Ideas for improving Solidity or this documentation are always welcome,
|
||||
read our :doc:`contributors guide <contributing>` for more details.
|
||||
|
||||
.. 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.
|
||||
You can download this documentation as PDF, HTML or Epub by clicking on the versions
|
||||
flyout menu in the bottom-left corner and selecting the preferred download format.
|
||||
|
||||
|
||||
Getting Started
|
||||
@ -37,7 +42,8 @@ Getting Started
|
||||
|
||||
**1. Understand the Smart Contract Basics**
|
||||
|
||||
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:
|
||||
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:
|
||||
|
||||
* :ref:`A simple example smart contract <simple-smart-contract>` written in Solidity.
|
||||
* :ref:`Blockchain Basics <blockchain-basics>`.
|
||||
@ -55,55 +61,53 @@ simply choose your preferred option and follow the steps outlined on the :ref:`i
|
||||
|
||||
.. hint::
|
||||
You can try out code examples directly in your browser with the
|
||||
`Remix IDE <https://remix.ethereum.org>`_.
|
||||
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 <https://remix.ethereum.org>`_. Remix is a web browser based IDE
|
||||
that allows you to write, deploy and administer Solidity smart contracts, without
|
||||
the need to install Solidity locally.
|
||||
|
||||
.. warning::
|
||||
As humans write software, it can have bugs.
|
||||
Therefore, you should follow established software development best practices when writing your smart contracts.
|
||||
This includes code review, testing, audits, and correctness proofs.
|
||||
Smart contract users are sometimes more confident with code than their authors,
|
||||
and blockchains and smart contracts have their own unique issues to watch out for,
|
||||
so before working on production code, make sure you read the :ref:`security_considerations` section.
|
||||
As humans write software, it can have bugs. 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 <https://ethereum.org/en/developers/>`_ can help you with further general documentation around Ethereum,
|
||||
and a wide selection of tutorials, tools, and development frameworks.
|
||||
If you want to learn more about building decentralized applications on Ethereum, the
|
||||
`Ethereum Developer Resources <https://ethereum.org/en/developers/>`_
|
||||
can help you with further general documentation around Ethereum, and a wide selection of tutorials,
|
||||
tools and development frameworks.
|
||||
|
||||
If you have any questions, you can try searching for answers or asking on the
|
||||
`Ethereum StackExchange <https://ethereum.stackexchange.com/>`_,
|
||||
or our `Gitter channel <https://gitter.im/ethereum/solidity>`_.
|
||||
`Ethereum StackExchange <https://ethereum.stackexchange.com/>`_, or
|
||||
our `Gitter channel <https://gitter.im/ethereum/solidity/>`_.
|
||||
|
||||
.. _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 <https://docs.soliditylang.org/zh/latest/>`_
|
||||
* `French <https://docs.soliditylang.org/fr/latest/>`_
|
||||
* `Indonesian <https://github.com/solidity-docs/id-indonesian>`_
|
||||
* `Japanese <https://github.com/solidity-docs/ja-japanese>`_
|
||||
* `Korean <https://github.com/solidity-docs/ko-korean>`_
|
||||
* `Persian <https://github.com/solidity-docs/fa-persian>`_
|
||||
* `Russian <https://github.com/solidity-docs/ru-russian>`_
|
||||
* `Spanish <https://github.com/solidity-docs/es-spanish>`_
|
||||
* `Turkish <https://docs.soliditylang.org/tr/latest/>`_
|
||||
Community volunteers help translate this documentation into several languages.
|
||||
They have varying degrees of completeness and up-to-dateness. The English
|
||||
version stands as a reference.
|
||||
|
||||
.. 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 <https://github.com/solidity-docs>`_
|
||||
for information on how to start a new language or contribute to the community translations.
|
||||
We recently set up a new GitHub organization and translation workflow to help streamline the
|
||||
community efforts. Please refer to the `translation guide <https://github.com/solidity-docs/translation-guide>`_
|
||||
for information on how to contribute to the community translations moving forward.
|
||||
|
||||
* `French <https://solidity-fr.readthedocs.io>`_ (in progress)
|
||||
* `Italian <https://github.com/damianoazzolini/solidity>`_ (in progress)
|
||||
* `Japanese <https://solidity-jp.readthedocs.io>`_
|
||||
* `Korean <https://solidity-kr.readthedocs.io>`_ (in progress)
|
||||
* `Russian <https://github.com/ethereum/wiki/wiki/%5BRussian%5D-%D0%A0%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE-%D0%BF%D0%BE-Solidity>`_ (rather outdated)
|
||||
* `Simplified Chinese <https://learnblockchain.cn/docs/solidity/>`_ (in progress)
|
||||
* `Spanish <https://solidity-es.readthedocs.io>`_
|
||||
* `Turkish <https://github.com/denizozzgur/Solidity_TR/blob/master/README.md>`_ (partial)
|
||||
|
||||
Contents
|
||||
========
|
||||
@ -115,8 +119,8 @@ Contents
|
||||
:caption: Basics
|
||||
|
||||
introduction-to-smart-contracts.rst
|
||||
solidity-by-example.rst
|
||||
installing-solidity.rst
|
||||
solidity-by-example.rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
@ -155,31 +159,21 @@ Contents
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Advisory content
|
||||
:caption: Additional Material
|
||||
|
||||
security-considerations.rst
|
||||
bugs.rst
|
||||
050-breaking-changes.rst
|
||||
060-breaking-changes.rst
|
||||
070-breaking-changes.rst
|
||||
080-breaking-changes.rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Additional Material
|
||||
|
||||
natspec-format.rst
|
||||
security-considerations.rst
|
||||
smtchecker.rst
|
||||
yul.rst
|
||||
resources.rst
|
||||
path-resolution.rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Resources
|
||||
|
||||
yul.rst
|
||||
style-guide.rst
|
||||
common-patterns.rst
|
||||
resources.rst
|
||||
bugs.rst
|
||||
contributing.rst
|
||||
language-influences.rst
|
||||
brand-guide.rst
|
||||
language-influences.rst
|
||||
|
@ -10,12 +10,12 @@ Versioning
|
||||
==========
|
||||
|
||||
Solidity versions follow `Semantic Versioning <https://semver.org>`_. In
|
||||
addition, patch-level releases with major release 0 (i.e. 0.x.y) will not
|
||||
addition, patch level releases with major release 0 (i.e. 0.x.y) will not
|
||||
contain breaking changes. That means code that compiles with version 0.x.y
|
||||
can be expected to compile with 0.x.z where z > y.
|
||||
|
||||
In addition to releases, we provide **nightly development builds** to make
|
||||
it easy for developers to try out upcoming features and
|
||||
In addition to releases, we provide **nightly development builds** with the
|
||||
intention of making it easy for developers to try out upcoming features and
|
||||
provide early feedback. Note, however, that while the nightly builds are usually
|
||||
very stable, they contain bleeding-edge code from the development branch and are
|
||||
not guaranteed to be always working. Despite our best efforts, they might
|
||||
@ -33,12 +33,12 @@ Remix
|
||||
|
||||
`Access Remix online <https://remix.ethereum.org/>`_, you do not need to install anything.
|
||||
If you want to use it without connection to the Internet, go to
|
||||
https://github.com/ethereum/remix-live/tree/gh-pages#readme and follow the instructions on that page.
|
||||
Remix is also a convenient option for testing nightly builds
|
||||
https://github.com/ethereum/remix-live/tree/gh-pages and download the ``.zip`` file as
|
||||
explained on that page. Remix is also a convenient option for testing nightly builds
|
||||
without installing multiple Solidity versions.
|
||||
|
||||
Further options on this page detail installing command-line Solidity compiler software
|
||||
on your computer. Choose a command-line compiler if you are working on a larger contract
|
||||
Further options on this page detail installing commandline Solidity compiler software
|
||||
on your computer. Choose a commandline compiler if you are working on a larger contract
|
||||
or if you require more compilation options.
|
||||
|
||||
.. _solcjs:
|
||||
@ -54,7 +54,7 @@ the full-featured compiler, ``solc``. The usage of ``solcjs`` is documented insi
|
||||
`repository <https://github.com/ethereum/solc-js>`_.
|
||||
|
||||
Note: The solc-js project is derived from the C++
|
||||
`solc` by using Emscripten, which means that both use the same compiler source code.
|
||||
`solc` 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.
|
||||
|
||||
@ -64,18 +64,18 @@ Please refer to the solc-js repository for instructions.
|
||||
|
||||
.. note::
|
||||
|
||||
The command-line executable is named ``solcjs``.
|
||||
The commandline 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``.
|
||||
The commandline options of ``solcjs`` are not compatible with ``solc`` and tools (such as ``geth``)
|
||||
expecting the behaviour of ``solc`` will not work with ``solcjs``.
|
||||
|
||||
Docker
|
||||
======
|
||||
|
||||
Docker images of Solidity builds are available using the ``solc`` image from the ``ethereum`` organization.
|
||||
Docker images of Solidity builds are available using the ``solc`` image from the ``ethereum`` organisation.
|
||||
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.
|
||||
The Docker image runs the compiler executable, so 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.
|
||||
|
||||
@ -83,13 +83,13 @@ and runs it in a new container, passing the ``--help`` argument.
|
||||
|
||||
docker run ethereum/solc:stable --help
|
||||
|
||||
For example, You can specify release build versions in the tag for the 0.5.4 release.
|
||||
You can also specify release build versions in the tag, for example, for the 0.5.4 release.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker run ethereum/solc:0.5.4 --help
|
||||
|
||||
To use the Docker image to compile Solidity files on the host machine, mount a
|
||||
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.
|
||||
|
||||
.. code-block:: bash
|
||||
@ -97,7 +97,7 @@ local folder for input and output, and specify the contract to compile. For exam
|
||||
docker run -v /local/path:/sources ethereum/solc:stable -o /sources/output --abi --bin /sources/Contract.sol
|
||||
|
||||
You can also use the standard JSON interface (which is recommended when using the compiler with tooling).
|
||||
When using this interface, it is not necessary to mount any directories as long as the JSON input is
|
||||
When using this interface it is not necessary to mount any directories as long as the JSON input is
|
||||
self-contained (i.e. it does not refer to any external files that would have to be
|
||||
:ref:`loaded by the import callback <initial-vfs-content-standard-json-with-import-callback>`).
|
||||
|
||||
@ -130,15 +130,13 @@ The nightly version can be installed using these commands:
|
||||
sudo apt-get install solc
|
||||
|
||||
Furthermore, some Linux distributions provide their own packages. These packages are not directly
|
||||
maintained by us but usually kept up-to-date by the respective package maintainers.
|
||||
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 <https://aur.archlinux.org/packages/solidity>`_
|
||||
and `solidity-bin <https://aur.archlinux.org/packages/solidity-bin>`_.
|
||||
For example, Arch Linux has packages for the latest development version:
|
||||
|
||||
.. note::
|
||||
.. code-block:: bash
|
||||
|
||||
Please be aware that `AUR <https://wiki.archlinux.org/title/Arch_User_Repository>`_ packages
|
||||
are user-produced content and unofficial packages. Exercise caution when using them.
|
||||
pacman -S solidity
|
||||
|
||||
There is also a `snap package <https://snapcraft.io/solc>`_, however, it is **currently unmaintained**.
|
||||
It is installable in all the `supported Linux distros <https://snapcraft.io/docs/core/install>`_. To
|
||||
@ -214,12 +212,12 @@ out-of-the-box but it is also meant to be friendly to third-party tools:
|
||||
HTTPS without any authentication, rate limiting or the need to use git.
|
||||
- Content is served with correct `Content-Type` headers and lenient CORS configuration so that it
|
||||
can be directly loaded by tools running in the browser.
|
||||
- Binaries do not require installation or unpacking (exception for older Windows builds
|
||||
- Binaries do not require installation or unpacking (with the exception of older Windows builds
|
||||
bundled with necessary DLLs).
|
||||
- We strive for a high level of backward-compatibility. Files, once added, are not removed or moved
|
||||
- We strive for a high level of backwards-compatibility. Files, once added, are not removed or moved
|
||||
without providing a symlink/redirect at the old location. They are also never modified
|
||||
in place and should always match the original checksum. The only exception would be broken or
|
||||
unusable files with the potential to cause more harm than good if left as is.
|
||||
unusable files with a potential to cause more harm than good if left as is.
|
||||
- Files are served over both HTTP and HTTPS. As long as you obtain the file list in a secure way
|
||||
(via git, HTTPS, IPFS or just have it cached locally) and verify hashes of the binaries
|
||||
after downloading them, you do not have to use HTTPS for the binaries themselves.
|
||||
@ -230,7 +228,7 @@ that we do not rename them if the naming convention changes and we do not add bu
|
||||
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
|
||||
Each one contains 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:
|
||||
|
||||
.. code-block:: json
|
||||
@ -261,7 +259,7 @@ This means that:
|
||||
- The file might in future be available on Swarm at `16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1`_.
|
||||
- You can verify the integrity of the binary by comparing its keccak256 hash to
|
||||
``0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3``. The hash can be computed
|
||||
on the command-line using ``keccak256sum`` utility provided by `sha3sum`_ or `keccak256() function
|
||||
on the command line using ``keccak256sum`` utility provided by `sha3sum`_ or `keccak256() function
|
||||
from ethereumjs-util`_ in JavaScript.
|
||||
- You can also verify the integrity of the binary by comparing its sha256 hash to
|
||||
``0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2``.
|
||||
@ -312,6 +310,7 @@ This means that:
|
||||
|
||||
Building from Source
|
||||
====================
|
||||
|
||||
Prerequisites - All Operating Systems
|
||||
-------------------------------------
|
||||
|
||||
@ -320,15 +319,14 @@ The following are dependencies for all builds of Solidity:
|
||||
+-----------------------------------+-------------------------------------------------------+
|
||||
| Software | Notes |
|
||||
+===================================+=======================================================+
|
||||
| `CMake`_ (version 3.21.3+ on | Cross-platform build file generator. |
|
||||
| Windows, 3.13+ otherwise) | |
|
||||
| `CMake`_ (version 3.13+) | Cross-platform build file generator. |
|
||||
+-----------------------------------+-------------------------------------------------------+
|
||||
| `Boost`_ (version 1.77+ on | C++ libraries. |
|
||||
| Windows, 1.65+ otherwise) | |
|
||||
+-----------------------------------+-------------------------------------------------------+
|
||||
| `Git`_ | Command-line tool for retrieving source code. |
|
||||
+-----------------------------------+-------------------------------------------------------+
|
||||
| `z3`_ (version 4.8.16+, Optional) | For use with SMT checker. |
|
||||
| `z3`_ (version 4.8+, Optional) | For use with SMT checker. |
|
||||
+-----------------------------------+-------------------------------------------------------+
|
||||
| `cvc4`_ (Optional) | For use with SMT checker. |
|
||||
+-----------------------------------+-------------------------------------------------------+
|
||||
@ -342,7 +340,7 @@ The following are dependencies for all builds of Solidity:
|
||||
.. note::
|
||||
Solidity versions prior to 0.5.10 can fail to correctly link against Boost versions 1.70+.
|
||||
A possible workaround is to temporarily rename ``<Boost install path>/lib/cmake/Boost-1.70.0``
|
||||
prior to running the cmake command to configure Solidity.
|
||||
prior to running the cmake command to configure solidity.
|
||||
|
||||
Starting from 0.5.10 linking against Boost 1.70+ should work without manual intervention.
|
||||
|
||||
@ -356,17 +354,6 @@ The following are dependencies for all builds of Solidity:
|
||||
If you do this, however, please remember to pass the ``--no-smt`` option to ``scripts/tests.sh``
|
||||
to skip the SMT tests.
|
||||
|
||||
.. 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 <https://github.com/ethereum/solidity/issues/new>`_.
|
||||
|
||||
Minimum Compiler Versions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -380,7 +367,7 @@ Prerequisites - macOS
|
||||
---------------------
|
||||
|
||||
For macOS builds, ensure that you have the latest version of
|
||||
`Xcode installed <https://developer.apple.com/xcode/resources/>`_.
|
||||
`Xcode installed <https://developer.apple.com/xcode/download/>`_.
|
||||
This contains the `Clang C++ compiler <https://en.wikipedia.org/wiki/Clang>`_, the
|
||||
`Xcode IDE <https://en.wikipedia.org/wiki/Xcode>`_ and other Apple development
|
||||
tools that are required for building C++ applications on OS X.
|
||||
@ -430,7 +417,7 @@ in Visual Studio 2019 Build Tools or Visual Studio 2019:
|
||||
* C++/CLI support
|
||||
|
||||
.. _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
|
||||
.. _Visual Studio 2019 Build Tools: https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2019
|
||||
|
||||
We have a helper script which you can use to install all required external dependencies:
|
||||
|
||||
@ -450,7 +437,7 @@ To clone the source code, execute the following command:
|
||||
git clone --recursive https://github.com/ethereum/solidity.git
|
||||
cd solidity
|
||||
|
||||
If you want to help develop Solidity,
|
||||
If you want to help developing Solidity,
|
||||
you should fork Solidity and add your personal fork as a second remote:
|
||||
|
||||
.. code-block:: bash
|
||||
@ -458,7 +445,7 @@ you should fork Solidity and add your personal fork as a second remote:
|
||||
git remote add personal git@github.com:[username]/solidity.git
|
||||
|
||||
.. note::
|
||||
This method will result in a pre-release build leading to e.g. a flag
|
||||
This method will result in a prerelease 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:
|
||||
@ -528,7 +515,7 @@ If you are interested what CMake options are available run ``cmake .. -LH``.
|
||||
SMT Solvers
|
||||
-----------
|
||||
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.
|
||||
they are found in the system. Each solver can be disabled by a `cmake` option.
|
||||
|
||||
*Note: In some cases, this can also be a potential workaround for build failures.*
|
||||
|
||||
@ -581,4 +568,4 @@ Example:
|
||||
4. A breaking change is introduced --> version is bumped to 0.5.0.
|
||||
5. The 0.5.0 release is made.
|
||||
|
||||
This behavior works well with the :ref:`version pragma <version_pragma>`.
|
||||
This behaviour works well with the :ref:`version pragma <version_pragma>`.
|
||||
|
@ -140,7 +140,8 @@ by checking if the lowest bit is set: short (not set) and long (set).
|
||||
|
||||
.. note::
|
||||
Handling invalidly encoded slots is currently not supported but may be added in the future.
|
||||
If you are compiling via IR, reading an invalidly encoded slot results in a ``Panic(0x22)`` error.
|
||||
If you are compiling via the experimental IR-based compiler pipeline, reading an invalidly encoded
|
||||
slot results in a ``Panic(0x22)`` error.
|
||||
|
||||
JSON Output
|
||||
===========
|
||||
@ -153,7 +154,7 @@ the :ref:`standard JSON interface <compiler-api>`. The output is a JSON object
|
||||
element has the following form:
|
||||
|
||||
|
||||
.. code-block:: json
|
||||
.. code::
|
||||
|
||||
|
||||
{
|
||||
@ -181,7 +182,7 @@ The given ``type``, in this case ``t_uint256`` represents an element in
|
||||
``types``, which has the form:
|
||||
|
||||
|
||||
.. code-block:: json
|
||||
.. code::
|
||||
|
||||
{
|
||||
"encoding": "inplace",
|
||||
@ -208,7 +209,7 @@ of types), arrays have its ``base`` type, and structs list their ``members`` in
|
||||
the same format as the top-level ``storage`` (see :ref:`above
|
||||
<storage-layout-top-level>`).
|
||||
|
||||
.. note::
|
||||
.. note ::
|
||||
The JSON output format of a contract's storage layout is still considered experimental
|
||||
and is subject to change in non-breaking releases of Solidity.
|
||||
|
||||
@ -232,13 +233,13 @@ value and reference types, types that are encoded packed, and nested types.
|
||||
uint y;
|
||||
S s;
|
||||
address addr;
|
||||
mapping(uint => mapping(address => bool)) map;
|
||||
mapping (uint => mapping (address => bool)) map;
|
||||
uint[] array;
|
||||
string s1;
|
||||
bytes b1;
|
||||
}
|
||||
|
||||
.. code-block:: json
|
||||
.. code:: json
|
||||
|
||||
{
|
||||
"storage": [
|
||||
|
@ -23,13 +23,9 @@ call completely.
|
||||
Currently, the parameter ``--optimize`` activates the opcode-based optimizer for the
|
||||
generated bytecode and the Yul optimizer for the Yul code generated internally, for example for ABI coder v2.
|
||||
One can use ``solc --ir-optimized --optimize`` to produce an
|
||||
optimized Yul IR for a Solidity source. Similarly, one can use ``solc --strict-assembly --optimize``
|
||||
optimized experimental Yul IR for a Solidity source. Similarly, one can use ``solc --strict-assembly --optimize``
|
||||
for a stand-alone Yul mode.
|
||||
|
||||
.. note::
|
||||
The `peephole optimizer <https://en.wikipedia.org/wiki/Peephole_optimization>`_ is always
|
||||
enabled by default and can only be turned off via the :ref:`Standard JSON <compiler-api>`.
|
||||
|
||||
You can find more details on both optimizer modules and their optimization steps below.
|
||||
|
||||
Benefits of Optimizing Solidity Code
|
||||
@ -281,81 +277,60 @@ The following transformation steps are the main components:
|
||||
- Redundant Assign Eliminator
|
||||
- Full Inliner
|
||||
|
||||
.. _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.
|
||||
|
||||
============ ===============================
|
||||
Abbreviation Full name
|
||||
============ ===============================
|
||||
``f`` :ref:`block-flattener`
|
||||
``l`` :ref:`circular-reference-pruner`
|
||||
``c`` :ref:`common-subexpression-eliminator`
|
||||
``C`` :ref:`conditional-simplifier`
|
||||
``U`` :ref:`conditional-unsimplifier`
|
||||
``n`` :ref:`control-flow-simplifier`
|
||||
``D`` :ref:`dead-code-eliminator`
|
||||
``E`` :ref:`equal-store-eliminator`
|
||||
``v`` :ref:`equivalent-function-combiner`
|
||||
``e`` :ref:`expression-inliner`
|
||||
``j`` :ref:`expression-joiner`
|
||||
``s`` :ref:`expression-simplifier`
|
||||
``x`` :ref:`expression-splitter`
|
||||
``I`` :ref:`for-loop-condition-into-body`
|
||||
``O`` :ref:`for-loop-condition-out-of-body`
|
||||
``o`` :ref:`for-loop-init-rewriter`
|
||||
``i`` :ref:`full-inliner`
|
||||
``g`` :ref:`function-grouper`
|
||||
``h`` :ref:`function-hoister`
|
||||
``F`` :ref:`function-specializer`
|
||||
``T`` :ref:`literal-rematerialiser`
|
||||
``L`` :ref:`load-resolver`
|
||||
``M`` :ref:`loop-invariant-code-motion`
|
||||
``r`` :ref:`redundant-assign-eliminator`
|
||||
``m`` :ref:`rematerialiser`
|
||||
``V`` :ref:`SSA-reverser`
|
||||
``a`` :ref:`SSA-transform`
|
||||
``t`` :ref:`structural-simplifier`
|
||||
``p`` :ref:`unused-function-parameter-pruner`
|
||||
``S`` :ref:`unused-store-eliminator`
|
||||
``u`` :ref:`unused-pruner`
|
||||
``d`` :ref:`var-decl-initializer`
|
||||
============ ===============================
|
||||
|
||||
Some steps depend on properties ensured by ``BlockFlattener``, ``FunctionGrouper``, ``ForLoopInitRewriter``.
|
||||
For this reason the Yul optimizer always applies them before applying any steps supplied by the user.
|
||||
|
||||
- :ref:`block-flattener`.
|
||||
- :ref:`circular-reference-pruner`.
|
||||
- :ref:`common-subexpression-eliminator`.
|
||||
- :ref:`conditional-simplifier`.
|
||||
- :ref:`conditional-unsimplifier`.
|
||||
- :ref:`control-flow-simplifier`.
|
||||
- :ref:`dead-code-eliminator`.
|
||||
- :ref:`equal-store-eliminator`.
|
||||
- :ref:`equivalent-function-combiner`.
|
||||
- :ref:`expression-joiner`.
|
||||
- :ref:`expression-simplifier`.
|
||||
- :ref:`expression-splitter`.
|
||||
- :ref:`for-loop-condition-into-body`.
|
||||
- :ref:`for-loop-condition-out-of-body`.
|
||||
- :ref:`for-loop-init-rewriter`.
|
||||
- :ref:`expression-inliner`.
|
||||
- :ref:`full-inliner`.
|
||||
- :ref:`function-grouper`.
|
||||
- :ref:`function-hoister`.
|
||||
- :ref:`function-specializer`.
|
||||
- :ref:`literal-rematerialiser`.
|
||||
- :ref:`load-resolver`.
|
||||
- :ref:`loop-invariant-code-motion`.
|
||||
- :ref:`redundant-assign-eliminator`.
|
||||
- :ref:`reasoning-based-simplifier`.
|
||||
- :ref:`rematerialiser`.
|
||||
- :ref:`SSA-reverser`.
|
||||
- :ref:`SSA-transform`.
|
||||
- :ref:`structural-simplifier`.
|
||||
- :ref:`unused-function-parameter-pruner`.
|
||||
- :ref:`unused-pruner`.
|
||||
- :ref:`var-decl-initializer`.
|
||||
|
||||
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:
|
||||
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:
|
||||
|
||||
.. 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.
|
||||
solc --optimize --ir-optimized --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul'
|
||||
|
||||
The sequence inside ``[...]`` will be applied multiple times in a loop until the Yul code
|
||||
remains unchanged or until the maximum number of rounds (currently 12) has been reached.
|
||||
Brackets (``[]``) may be used multiple times in a sequence, but can not be nested.
|
||||
|
||||
An important thing to note, is that there are some hardcoded steps that are always run before and after the
|
||||
user-supplied sequence, or the default sequence if one was not supplied by the user.
|
||||
|
||||
The cleanup sequence delimiter ``:`` is optional, and is used to supply a custom cleanup sequence
|
||||
in order to replace the default one. If omitted, the optimizer will simply apply the default cleanup
|
||||
sequence. In addition, the delimiter may be placed at the beginning of the user-supplied sequence,
|
||||
which will result in the optimization sequence being empty, whereas conversely, if placed at the end of
|
||||
the sequence, will be treated as an empty cleanup sequence.
|
||||
Available abbreviations are listed in the `Yul optimizer docs <yul.rst#optimization-step-sequence>`_.
|
||||
|
||||
Preprocessing
|
||||
-------------
|
||||
@ -570,7 +545,7 @@ It is not applied to loop iteration-condition, because the loop control flow doe
|
||||
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.
|
||||
|
||||
The final program should be in an *expression-split form*, where (with the exception of loop conditions)
|
||||
The final program should be in a form such that (with the exception of loop conditions)
|
||||
function calls cannot appear nested inside expressions
|
||||
and all function call arguments have to be variables.
|
||||
|
||||
@ -708,7 +683,7 @@ Conflicting values are resolved in the following way:
|
||||
|
||||
- "unused", "undecided" -> "undecided"
|
||||
- "unused", "used" -> "used"
|
||||
- "undecided", "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.
|
||||
@ -821,10 +796,10 @@ if the common subexpression eliminator was run right before it.
|
||||
|
||||
.. _expression-simplifier:
|
||||
|
||||
ExpressionSimplifier
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
Expression Simplifier
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ExpressionSimplifier uses the Dataflow Analyzer and makes use
|
||||
The Expression Simplifier uses the Dataflow Analyzer and makes use
|
||||
of a list of equivalence transforms on expressions like ``X + 0 -> X``
|
||||
to simplify the code.
|
||||
|
||||
@ -858,6 +833,22 @@ Works best if the code is in SSA form.
|
||||
|
||||
Prerequisite: Disambiguator, ForLoopInitRewriter.
|
||||
|
||||
.. _reasoning-based-simplifier:
|
||||
|
||||
ReasoningBasedSimplifier
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This optimizer uses SMT solvers to check whether ``if`` conditions are constant.
|
||||
|
||||
- If ``constraints AND condition`` is UNSAT, the condition is never true and the whole body can be removed.
|
||||
- If ``constraints AND NOT condition`` is UNSAT, the condition is always true and can be replaced by ``1``.
|
||||
|
||||
The simplifications above can only be applied if the condition is movable.
|
||||
|
||||
It is only effective on the EVM dialect, but safe to use on other dialects.
|
||||
|
||||
Prerequisite: Disambiguator, SSATransform.
|
||||
|
||||
Statement-Scale Simplifications
|
||||
-------------------------------
|
||||
|
||||
@ -938,7 +929,7 @@ 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 or revert.
|
||||
|
||||
Function definitions are retained as they might be called by earlier
|
||||
code and thus are considered reachable.
|
||||
@ -1101,52 +1092,6 @@ The step LiteralRematerialiser is not required for correctness. It helps deal wi
|
||||
``function f(x) -> y { revert(y, y} }`` where the literal ``y`` will be replaced by its value ``0``,
|
||||
allowing us to rewrite the function.
|
||||
|
||||
.. index:: ! unused store eliminator
|
||||
.. _unused-store-eliminator:
|
||||
|
||||
UnusedStoreEliminator
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Optimizer component that removes redundant ``sstore`` and memory store statements.
|
||||
In case of an ``sstore``, if all outgoing code paths revert (due to an explicit ``revert()``, ``invalid()``, or infinite recursion) or
|
||||
lead to another ``sstore`` for which the optimizer can tell that it will overwrite the first store, the statement will be removed.
|
||||
However, if there is a read operation between the initial ``sstore`` and the revert, or the overwriting ``sstore``, the statement
|
||||
will not be removed.
|
||||
Such read operations include: external calls, user-defined functions with any storage access, and ``sload`` of a slot that cannot be
|
||||
proven to differ from the slot written by the initial ``sstore``.
|
||||
|
||||
For example, the following code
|
||||
|
||||
.. code-block:: yul
|
||||
|
||||
{
|
||||
let c := calldataload(0)
|
||||
sstore(c, 1)
|
||||
if c {
|
||||
sstore(c, 2)
|
||||
}
|
||||
sstore(c, 3)
|
||||
}
|
||||
|
||||
will be transformed into the code below after the Unused Store Eliminator step is run
|
||||
|
||||
.. code-block:: yul
|
||||
|
||||
{
|
||||
let c := calldataload(0)
|
||||
if c { }
|
||||
sstore(c, 3)
|
||||
}
|
||||
|
||||
For memory store operations, things are generally simpler, at least in the outermost yul block as all such
|
||||
statements will be removed if they are never read from in any code path.
|
||||
At function analysis level, however, the approach is similar to ``sstore``, as we do not know whether the memory location will
|
||||
be read once we leave the function's scope, so the statement will be removed only if all code paths lead to a memory overwrite.
|
||||
|
||||
Best run in SSA form.
|
||||
|
||||
Prerequisites: Disambiguator, ForLoopInitRewriter.
|
||||
|
||||
.. _equivalent-function-combiner:
|
||||
|
||||
EquivalentFunctionCombiner
|
||||
@ -1192,7 +1137,7 @@ This component can only be used on sources with unique names.
|
||||
FullInliner
|
||||
^^^^^^^^^^^
|
||||
|
||||
The FullInliner replaces certain calls of certain functions
|
||||
The Full Inliner 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
|
||||
@ -1216,11 +1161,6 @@ 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.
|
||||
|
||||
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
|
||||
-------
|
||||
|
||||
@ -1263,8 +1203,8 @@ 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.
|
||||
|
||||
The SSA form we generate is detrimental to code generation
|
||||
because it produces many local variables. It would
|
||||
The SSA form we generate is detrimental to code generation on the EVM and
|
||||
WebAssembly alike because it generates many local variables. It would
|
||||
be better to just re-use existing variables with assignments instead of
|
||||
fresh variable declarations.
|
||||
|
||||
@ -1382,3 +1322,15 @@ into
|
||||
}
|
||||
|
||||
The LiteralRematerialiser should be run before this step.
|
||||
|
||||
|
||||
WebAssembly specific
|
||||
--------------------
|
||||
|
||||
MainFunction
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Changes the topmost block to be a function with a specific name ("main") which has no
|
||||
inputs nor outputs.
|
||||
|
||||
Depends on the Function Grouper.
|
||||
|
@ -26,7 +26,7 @@ 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']``.
|
||||
|
||||
.. note::
|
||||
.. note ::
|
||||
In the case of instructions that are not associated with any particular source file,
|
||||
the source mapping assigns an integer identifier of ``-1``. This may happen for
|
||||
bytecode sections stemming from compiler-generated inline assembly statements.
|
||||
|
@ -4,10 +4,9 @@
|
||||
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
|
||||
When a value is shorter than 256 bit, in some cases the remaining bits
|
||||
must be cleaned.
|
||||
The Solidity compiler is designed to clean such remaining bits 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
|
||||
@ -29,83 +28,25 @@ the boolean values before they are used as the condition for
|
||||
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.
|
||||
Different types have different rules for cleaning up invalid values:
|
||||
|
||||
+---------------+---------------+-------------------------+
|
||||
|Type |Valid Values |Cleanup of Invalid Values|
|
||||
+===============+===============+=========================+
|
||||
|enum of n |0 until n - 1 |throws exception |
|
||||
|members | | |
|
||||
+---------------+---------------+-------------------------+
|
||||
|bool |0 or 1 |results in 1 |
|
||||
+---------------+---------------+-------------------------+
|
||||
|signed integers|higher bits |currently silently |
|
||||
| |set to the |signextends to a valid |
|
||||
| |sign bit |value, i.e. all higher |
|
||||
| | |bits are set to the sign |
|
||||
| | |bit; may throw an |
|
||||
| | |exception in the future |
|
||||
+---------------+---------------+-------------------------+
|
||||
|unsigned |higher bits |currently silently masks |
|
||||
|integers |zeroed |to a valid value, i.e. |
|
||||
| | |all higher bits are set |
|
||||
| | |to zero; may throw an |
|
||||
| | |exception in the future |
|
||||
+---------------+---------------+-------------------------+
|
||||
|
||||
Note that valid and invalid values are dependent on their type size.
|
||||
Consider ``uint8``, the unsigned 8-bit type, which has the following valid values:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
0000...0000 0000 0000
|
||||
0000...0000 0000 0001
|
||||
0000...0000 0000 0010
|
||||
....
|
||||
0000...0000 1111 1111
|
||||
|
||||
Any invalid value will have the higher bits set to zero:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
0101...1101 0010 1010 invalid value
|
||||
0000...0000 0010 1010 cleaned value
|
||||
|
||||
For ``int8``, the signed 8-bit type, the valid values are:
|
||||
|
||||
Negative
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
1111...1111 1111 1111
|
||||
1111...1111 1111 1110
|
||||
....
|
||||
1111...1111 1000 0000
|
||||
|
||||
Positive
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
0000...0000 0000 0000
|
||||
0000...0000 0000 0001
|
||||
0000...0000 0000 0010
|
||||
....
|
||||
0000...0000 1111 1111
|
||||
|
||||
The compiler will ``signextend`` the sign bit, which is 1 for negative and 0 for
|
||||
positive values, overwriting the higher bits:
|
||||
|
||||
Negative
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
0010...1010 1111 1111 invalid value
|
||||
1111...1111 1111 1111 cleaned value
|
||||
|
||||
Positive
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
1101...0101 0000 0100 invalid value
|
||||
0000...0000 0000 0100 cleaned value
|
||||
+---------------+---------------+-------------------+
|
||||
|Type |Valid Values |Invalid Values Mean|
|
||||
+===============+===============+===================+
|
||||
|enum of n |0 until n - 1 |exception |
|
||||
|members | | |
|
||||
+---------------+---------------+-------------------+
|
||||
|bool |0 or 1 |1 |
|
||||
+---------------+---------------+-------------------+
|
||||
|signed integers|sign-extended |currently silently |
|
||||
| |word |wraps; in the |
|
||||
| | |future exceptions |
|
||||
| | |will be thrown |
|
||||
| | | |
|
||||
| | | |
|
||||
+---------------+---------------+-------------------+
|
||||
|unsigned |higher bits |currently silently |
|
||||
|integers |zeroed |wraps; in the |
|
||||
| | |future exceptions |
|
||||
| | |will be thrown |
|
||||
+---------------+---------------+-------------------+
|
||||
|
@ -10,7 +10,7 @@ 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.
|
||||
everything right now, we will go into more detail later.
|
||||
|
||||
Storage Example
|
||||
===============
|
||||
@ -91,7 +91,7 @@ registering with a username and password, all you need is an Ethereum keypair.
|
||||
// The keyword "public" makes variables
|
||||
// accessible from other contracts
|
||||
address public minter;
|
||||
mapping(address => uint) public balances;
|
||||
mapping (address => uint) public balances;
|
||||
|
||||
// Events allow clients to react to specific
|
||||
// contract changes you declare
|
||||
@ -151,7 +151,7 @@ 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
|
||||
The next line, ``mapping (address => uint) public balances;`` also
|
||||
creates a public state variable, but it is a more complex datatype.
|
||||
The :ref:`mapping <mapping-types>` type maps addresses to :ref:`unsigned integers <integers>`.
|
||||
|
||||
@ -168,8 +168,8 @@ following:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function balances(address account) external view returns (uint) {
|
||||
return balances[account];
|
||||
function balances(address _account) external view returns (uint) {
|
||||
return balances[_account];
|
||||
}
|
||||
|
||||
You can use this function to query the balance of a single account.
|
||||
@ -185,10 +185,8 @@ arguments ``from``, ``to`` and ``amount``, which makes it possible to track
|
||||
transactions.
|
||||
|
||||
To listen for this event, you could use the following
|
||||
JavaScript code, which uses `web3.js <https://github.com/web3/web3.js/>`_ to create the ``Coin`` contract object,
|
||||
and any user interface calls the automatically generated ``balances`` function from above:
|
||||
|
||||
.. code-block:: javascript
|
||||
JavaScript code, which uses `web3.js <https://github.com/ethereum/web3.js/>`_ to create the ``Coin`` contract object,
|
||||
and any user interface calls the automatically generated ``balances`` function from above::
|
||||
|
||||
Coin.Sent().watch({}, '', function(error, result) {
|
||||
if (!error) {
|
||||
@ -282,7 +280,7 @@ the source account is also not modified.
|
||||
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.
|
||||
only the person holding the keys to the account can transfer money from it.
|
||||
|
||||
.. index:: ! block
|
||||
|
||||
@ -300,9 +298,9 @@ 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 <https://etherscan.io/chart/blocktime>`_.
|
||||
These blocks form a linear sequence in time and that is where the word "blockchain"
|
||||
derives from. Blocks are added to the chain in rather regular intervals - for
|
||||
Ethereum this is roughly every 17 seconds.
|
||||
|
||||
As part of the "order selection mechanism" (which is called "mining") it may happen that
|
||||
blocks are reverted from time to time, but only at the "tip" of the chain. The more
|
||||
@ -398,34 +396,27 @@ returns that code when executed.
|
||||
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
|
||||
Upon creation, each transaction is charged with a certain amount of **gas**,
|
||||
whose purpose is to limit the amount of work that is needed to execute
|
||||
the transaction and to pay for this execution at the same time. While the EVM executes the
|
||||
transaction, the gas is gradually depleted according to specific rules.
|
||||
|
||||
The **gas price** is a value set by the creator of the transaction, who
|
||||
has to pay ``gas_price * gas`` up front from the sending account.
|
||||
If some gas is left after the execution, it is refunded to the creator in the same way.
|
||||
|
||||
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
|
||||
an out-of-gas exception is triggered, which reverts all modifications
|
||||
made to the state in the current call frame.
|
||||
|
||||
This mechanism incentivizes economical use of EVM execution time
|
||||
and also compensates EVM executors (i.e. miners / stakers) for their work.
|
||||
Since each block has a maximum amount of gas, it also limits the amount
|
||||
of work needed to validate a block.
|
||||
|
||||
The **gas price** is a value set by the originator of the transaction, who
|
||||
has to pay ``gas_price * gas`` up front to the EVM executor.
|
||||
If some gas is left after execution, it is refunded to the transaction originator.
|
||||
In case of an exception that reverts changes, already used up gas is not refunded.
|
||||
|
||||
Since EVM executors can choose to include a transaction or not,
|
||||
transaction senders cannot abuse the system by setting a low gas price.
|
||||
|
||||
.. index:: ! storage, ! memory, ! stack
|
||||
|
||||
Storage, Memory and the Stack
|
||||
=============================
|
||||
|
||||
The Ethereum Virtual Machine has three areas where it can store data:
|
||||
storage, memory and the stack.
|
||||
The Ethereum Virtual Machine has three areas where it can store data-
|
||||
storage, memory and the stack, which are explained in the following
|
||||
paragraphs.
|
||||
|
||||
Each account has a data area called **storage**, which is persistent between function calls
|
||||
and transactions.
|
||||
@ -506,14 +497,14 @@ 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.
|
||||
|
||||
.. index:: delegatecall, library
|
||||
.. index:: delegatecall, callcode, library
|
||||
|
||||
Delegatecall and Libraries
|
||||
==========================
|
||||
Delegatecall / Callcode 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
|
||||
the code at the target address is executed in the context of the calling
|
||||
contract and ``msg.sender`` and ``msg.value`` do not change their values.
|
||||
|
||||
This means that a contract can dynamically load code from a different
|
||||
@ -550,7 +541,7 @@ 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.
|
||||
|
||||
.. index:: ! selfdestruct, deactivate
|
||||
.. index:: selfdestruct, self-destruct, deactivate
|
||||
|
||||
Deactivate and Self-destruct
|
||||
============================
|
||||
@ -562,11 +553,6 @@ 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.
|
||||
|
||||
.. 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 <https://eips.ethereum.org/EIPS/eip-6049>`_.
|
||||
|
||||
.. warning::
|
||||
Even if a contract is removed by ``selfdestruct``, it is still part of the
|
||||
history of the blockchain and probably retained by most Ethereum nodes.
|
||||
@ -591,7 +577,7 @@ Precompiled Contracts
|
||||
There is a small set of contract addresses that are special:
|
||||
The address range between ``1`` and (including) ``8`` contains
|
||||
"precompiled contracts" that can be called as any other contract
|
||||
but their behavior (and their gas consumption) is not defined
|
||||
but their behaviour (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.
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
|
||||
.. index: ir breaking changes
|
||||
|
||||
.. _ir-breaking-changes:
|
||||
|
||||
*********************************
|
||||
Solidity IR-based Codegen Changes
|
||||
*********************************
|
||||
@ -15,13 +13,17 @@ The IR-based code generator was introduced with an aim to not only allow
|
||||
code generation to be more transparent and auditable but also
|
||||
to enable more powerful optimization passes that span across functions.
|
||||
|
||||
You can enable it on the command-line using ``--via-ir``
|
||||
Currently, the IR-based code generator is still marked experimental,
|
||||
but it supports all language features and has received a lot of testing,
|
||||
so we consider it almost ready for production use.
|
||||
|
||||
You can enable it on the command line using ``--experimental-via-ir``
|
||||
or with the option ``{"viaIR": true}`` in standard-json and we
|
||||
encourage everyone to try it out!
|
||||
|
||||
For several reasons, there are tiny semantic differences between the old
|
||||
and the IR-based code generator, mostly in areas where we would not
|
||||
expect people to rely on this behavior anyway.
|
||||
expect people to rely on this behaviour anyway.
|
||||
This section highlights the main differences between the old and the IR-based codegen.
|
||||
|
||||
Semantic Only Changes
|
||||
@ -30,50 +32,6 @@ Semantic Only Changes
|
||||
This section lists the changes that are semantic-only, thus potentially
|
||||
hiding new and different behavior in existing code.
|
||||
|
||||
.. _state-variable-initialization-order:
|
||||
|
||||
- The order of state variable initialization has changed in case of inheritance.
|
||||
|
||||
The order used to be:
|
||||
|
||||
- All state variables are zero-initialized at the beginning.
|
||||
- Evaluate base constructor arguments from most derived to most base contract.
|
||||
- Initialize all state variables in the whole inheritance hierarchy from most base to most derived.
|
||||
- Run the constructor, if present, for all contracts in the linearized hierarchy from most base to most derived.
|
||||
|
||||
New order:
|
||||
|
||||
- All state variables are zero-initialized at the beginning.
|
||||
- Evaluate base constructor arguments from most derived to most base contract.
|
||||
- For every contract in order from most base to most derived in the linearized hierarchy:
|
||||
|
||||
1. Initialize state variables.
|
||||
2. Run the constructor (if present).
|
||||
|
||||
This causes differences in contracts where the initial value of a state
|
||||
variable relies on the result of the constructor in another contract:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.1;
|
||||
|
||||
contract A {
|
||||
uint x;
|
||||
constructor() {
|
||||
x = 42;
|
||||
}
|
||||
function f() public view returns(uint256) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
contract B is A {
|
||||
uint public y = f();
|
||||
}
|
||||
|
||||
Previously, ``y`` would be set to 0. This is due to the fact that we would first initialize state variables: First, ``x`` is set to 0, and when initializing ``y``, ``f()`` would return 0 causing ``y`` to be 0 as well.
|
||||
With the new rules, ``y`` will be set to 42. We first initialize ``x`` to 0, then call A's constructor which sets ``x`` to 42. Finally, when initializing ``y``, ``f()`` returns 42 causing ``y`` to be 42.
|
||||
|
||||
- When storage structs are deleted, every storage slot that contains
|
||||
a member of the struct is set to zero entirely. Formerly, padding space
|
||||
was left untouched.
|
||||
@ -118,14 +76,14 @@ hiding new and different behavior in existing code.
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.0;
|
||||
contract C {
|
||||
function f(uint a) public pure mod() returns (uint r) {
|
||||
r = a++;
|
||||
function f(uint _a) public pure mod() returns (uint _r) {
|
||||
_r = _a++;
|
||||
}
|
||||
modifier mod() { _; _; }
|
||||
}
|
||||
|
||||
If you execute ``f(0)`` in the old code generator, it will return ``1``, while
|
||||
it will return ``0`` when using the new code generator.
|
||||
If you execute ``f(0)`` in the old code generator, it will return ``2``, while
|
||||
it will return ``1`` when using the new code generator.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
@ -156,6 +114,78 @@ hiding new and different behavior in existing code.
|
||||
- New code generator: ``0`` as all parameters, including return parameters, will be re-initialized before
|
||||
each ``_;`` evaluation.
|
||||
|
||||
- The order of contract initialization has changed in case of inheritance.
|
||||
|
||||
The order used to be:
|
||||
|
||||
- All state variables are zero-initialized at the beginning.
|
||||
- Evaluate base constructor arguments from most derived to most base contract.
|
||||
- Initialize all state variables in the whole inheritance hierarchy from most base to most derived.
|
||||
- Run the constructor, if present, for all contracts in the linearized hierarchy from most base to most derived.
|
||||
|
||||
New order:
|
||||
|
||||
- All state variables are zero-initialized at the beginning.
|
||||
- Evaluate base constructor arguments from most derived to most base contract.
|
||||
- For every contract in order from most base to most derived in the linearized hierarchy execute:
|
||||
|
||||
1. If present at declaration, initial values are assigned to state variables.
|
||||
2. Constructor, if present.
|
||||
|
||||
This causes differences in some contracts, for example:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.1;
|
||||
|
||||
contract A {
|
||||
uint x;
|
||||
constructor() {
|
||||
x = 42;
|
||||
}
|
||||
function f() public view returns(uint256) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
contract B is A {
|
||||
uint public y = f();
|
||||
}
|
||||
|
||||
Previously, ``y`` would be set to 0. This is due to the fact that we would first initialize state variables: First, ``x`` is set to 0, and when initializing ``y``, ``f()`` would return 0 causing ``y`` to be 0 as well.
|
||||
With the new rules, ``y`` will be set to 42. We first initialize ``x`` to 0, then call A's constructor which sets ``x`` to 42. Finally, when initializing ``y``, ``f()`` returns 42 causing ``y`` to be 42.
|
||||
|
||||
- Copying ``bytes`` arrays from memory to storage is implemented in a different way.
|
||||
The old code generator always copies full words, while the new one cuts the byte
|
||||
array after its end. The old behaviour can lead to dirty data being copied after
|
||||
the end of the array (but still in the same storage slot).
|
||||
This causes differences in some contracts, for example:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.8.1;
|
||||
|
||||
contract C {
|
||||
bytes x;
|
||||
function f() public returns (uint _r) {
|
||||
bytes memory m = "tmp";
|
||||
assembly {
|
||||
mstore(m, 8)
|
||||
mstore(add(m, 32), "deadbeef15dead")
|
||||
}
|
||||
x = m;
|
||||
assembly {
|
||||
_r := sload(x.slot)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Previously ``f()`` would return ``0x6465616462656566313564656164000000000000000000000000000000000010``
|
||||
(it has correct length, and correct first 8 elements, but then it contains dirty data which was set via assembly).
|
||||
Now it is returning ``0x6465616462656566000000000000000000000000000000000000000000000010`` (it has
|
||||
correct length, and correct elements, but does not contain superfluous data).
|
||||
|
||||
.. index:: ! evaluation order; expression
|
||||
|
||||
- For the old code generator, the evaluation order of expressions is unspecified.
|
||||
@ -169,15 +199,15 @@ hiding new and different behavior in existing code.
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.8.1;
|
||||
contract C {
|
||||
function preincr_u8(uint8 a) public pure returns (uint8) {
|
||||
return ++a + a;
|
||||
function preincr_u8(uint8 _a) public pure returns (uint8) {
|
||||
return ++_a + _a;
|
||||
}
|
||||
}
|
||||
|
||||
The function ``preincr_u8(1)`` returns the following values:
|
||||
|
||||
- Old code generator: ``3`` (``1 + 2``) but the return value is unspecified in general
|
||||
- New code generator: ``4`` (``2 + 2``) but the return value is not guaranteed
|
||||
- Old code generator: 3 (``1 + 2``) but the return value is unspecified in general
|
||||
- New code generator: 4 (``2 + 2``) but the return value is not guaranteed
|
||||
|
||||
.. index:: ! evaluation order; function arguments
|
||||
|
||||
@ -190,11 +220,11 @@ hiding new and different behavior in existing code.
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.8.1;
|
||||
contract C {
|
||||
function add(uint8 a, uint8 b) public pure returns (uint8) {
|
||||
return a + b;
|
||||
function add(uint8 _a, uint8 _b) public pure returns (uint8) {
|
||||
return _a + _b;
|
||||
}
|
||||
function g(uint8 a, uint8 b) public pure returns (uint8) {
|
||||
return add(++a + ++b, a + b);
|
||||
function g(uint8 _a, uint8 _b) public pure returns (uint8) {
|
||||
return add(++_a + ++_b, _a + _b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,7 +279,7 @@ hiding new and different behavior in existing code.
|
||||
}
|
||||
}
|
||||
|
||||
The function ``f()`` behaves as follows:
|
||||
The function `f()` behaves as follows:
|
||||
|
||||
- Old code generator: runs out of gas while zeroing the array contents after the large memory allocation
|
||||
- New code generator: reverts due to free memory pointer overflow (does not run out of gas)
|
||||
@ -293,13 +323,13 @@ For example:
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.8.1;
|
||||
contract C {
|
||||
function f(uint8 a) public pure returns (uint r1, uint r2)
|
||||
function f(uint8 _a) public pure returns (uint _r1, uint _r2)
|
||||
{
|
||||
a = ~a;
|
||||
_a = ~_a;
|
||||
assembly {
|
||||
r1 := a
|
||||
_r1 := _a
|
||||
}
|
||||
r2 = a;
|
||||
_r2 = _a;
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,6 +338,6 @@ The function ``f(1)`` returns the following values:
|
||||
- Old code generator: (``fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe``, ``00000000000000000000000000000000000000000000000000000000000000fe``)
|
||||
- New code generator: (``00000000000000000000000000000000000000000000000000000000000000fe``, ``00000000000000000000000000000000000000000000000000000000000000fe``)
|
||||
|
||||
Note that, unlike the new code generator, the old code generator does not perform a cleanup after the bit-not assignment (``a = ~a``).
|
||||
This results in different values being assigned (within the inline assembly block) to return value ``r1`` between the old and new code generators.
|
||||
However, both code generators perform a cleanup before the new value of ``a`` is assigned to ``r2``.
|
||||
Note that, unlike the new code generator, the old code generator does not perform a cleanup after the bit-not assignment (``_a = ~_a``).
|
||||
This results in different values being assigned (within the inline assembly block) to return value ``_r1`` between the old and new code generators.
|
||||
However, both code generators perform a cleanup before the new value of ``_a`` is assigned to ``_r2``.
|
||||
|
@ -3,8 +3,8 @@ Layout of a Solidity Source File
|
||||
********************************
|
||||
|
||||
Source files can contain an arbitrary number of
|
||||
:ref:`contract definitions<contract_structure>`, import_ ,
|
||||
:ref:`pragma<pragma>` and :ref:`using for<using-for>` directives and
|
||||
:ref:`contract definitions<contract_structure>`, import_ directives,
|
||||
:ref:`pragma directives<pragma>` and
|
||||
:ref:`struct<structs>`, :ref:`enum<enums>`, :ref:`function<functions>`, :ref:`error<errors>`
|
||||
and :ref:`constant variable<constants>` definitions.
|
||||
|
||||
@ -56,7 +56,7 @@ you have to add the pragma to all your files if you want to enable it
|
||||
in your whole project. If you :ref:`import<import>` another file, the pragma
|
||||
from that file does *not* automatically apply to the importing file.
|
||||
|
||||
.. index:: ! pragma;version
|
||||
.. index:: ! pragma, version
|
||||
|
||||
.. _version_pragma:
|
||||
|
||||
@ -91,9 +91,6 @@ these follow the same syntax used by `npm <https://docs.npmjs.com/cli/v6/using-n
|
||||
required by the pragma. If it does not match, the compiler issues
|
||||
an error.
|
||||
|
||||
.. index:: ! ABI coder, ! pragma; abicoder, pragma; ABIEncoderV2
|
||||
.. _abi_coder:
|
||||
|
||||
ABI Coder Pragma
|
||||
----------------
|
||||
|
||||
@ -101,11 +98,12 @@ By using ``pragma abicoder v1`` or ``pragma abicoder v2`` you can
|
||||
select between the two implementations of the ABI encoder and decoder.
|
||||
|
||||
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;``.
|
||||
arrays and structs. It might produce less optimal code and has not
|
||||
received as much testing as the old encoder, but is considered
|
||||
non-experimental as of Solidity 0.6.0. You still have to explicitly
|
||||
activate it using ``pragma abicoder v2;``. Since it will be
|
||||
activated by default starting from Solidity 0.8.0, there is the option to select
|
||||
the old coder using ``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
|
||||
@ -128,7 +126,8 @@ enough to make the error go away.
|
||||
by using ``pragma experimental ABIEncoderV2``, but it was not possible
|
||||
to explicitly select coder v1 because it was the default.
|
||||
|
||||
.. index:: ! pragma; experimental
|
||||
.. index:: ! pragma, experimental
|
||||
|
||||
.. _experimental_pragma:
|
||||
|
||||
Experimental Pragma
|
||||
@ -138,7 +137,6 @@ 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
|
||||
~~~~~~~~~~~~
|
||||
@ -147,7 +145,6 @@ 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.
|
||||
|
||||
.. index:: ! pragma; SMTChecker
|
||||
.. _smt_checker:
|
||||
|
||||
SMTChecker
|
||||
@ -182,7 +179,7 @@ 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 <https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export#description>`_.
|
||||
a `default export <https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export#Description>`_.
|
||||
|
||||
At a global level, you can use import statements of the following form:
|
||||
|
||||
|
@ -1,8 +1,27 @@
|
||||
<svg width="100" height="160" viewBox="0 0 100 160" fill="#2B247C" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.8" d="M50 44.3013L25 1L0 44.3013L25 87.6025L50 44.3013Z" />
|
||||
<path opacity="0.45" d="M50 44.3091L75 1.00781L25 1.00781L0 44.3091H50Z" />
|
||||
<path opacity="0.6" d="M75 1.00781L25 1.00781L50 44.3091H100L75 1.00781Z" />
|
||||
<path opacity="0.8" d="M50 115.699L75 159L100 115.699L75 72.3975L50 115.699Z" />
|
||||
<path opacity="0.45" d="M50 115.691L25 158.993H75L100 115.691L50 115.691Z" />
|
||||
<path opacity="0.6" d="M25 158.993H75L50 115.691L0 115.691L25 158.993Z" />
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1300px" height="1300px"
|
||||
viewBox="0 0 1300 1300" enable-background="new 0 0 1300 1300" xml:space="preserve">
|
||||
<title>Vector 1</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" sketch:type="MSPage">
|
||||
<g id="solidity" transform="translate(402.000000, 118.000000)" sketch:type="MSLayerGroup">
|
||||
<g id="Group" sketch:type="MSShapeGroup">
|
||||
<path id="Shape" opacity="0.45" enable-background="new " d="M371.772,135.308L241.068,367.61H-20.158l130.614-232.302
|
||||
H371.772"/>
|
||||
<path id="Shape_1_" opacity="0.6" enable-background="new " d="M241.068,367.61h261.318L371.772,135.308H110.456
|
||||
L241.068,367.61z"/>
|
||||
<path id="Shape_2_" opacity="0.8" enable-background="new " d="M110.456,599.822L241.068,367.61L110.456,135.308
|
||||
L-20.158,367.61L110.456,599.822z"/>
|
||||
<path id="Shape_3_" opacity="0.45" enable-background="new " d="M111.721,948.275l130.704-232.303h261.318L373.038,948.275
|
||||
H111.721"/>
|
||||
<path id="Shape_4_" opacity="0.6" enable-background="new " d="M242.424,715.973H-18.893l130.613,232.303h261.317
|
||||
L242.424,715.973z"/>
|
||||
<path id="Shape_5_" opacity="0.8" enable-background="new " d="M373.038,483.761L242.424,715.973l130.614,232.303
|
||||
l130.704-232.303L373.038,483.761z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 574 B After Width: | Height: | Size: 1.6 KiB |
@ -28,7 +28,6 @@ if "%1" == "help" (
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. latexpdf to make LaTeX files and run them through pdflatex
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
@ -156,6 +155,16 @@ if "%1" == "latexpdf" (
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdfja" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf-ja
|
||||
cd %BUILDDIR%/..
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
|