Contributing
Help is always welcome and there are plenty of options to contribute to Solidity.
In particular, we appreciate support in the following areas:
Reporting issues.
Fixing and responding toSolidity’s GitHub issues, especially those tagged as“good first issue” which aremeant as introductory issues for external contributors.
Improving the documentation.
Translating the documentation into more languages.
Responding to questions from other users onStackExchange and theSolidity Gitter Chat.
Getting involved in the language design process by proposing language changes or new features in theSolidity forum and providing feedback.
To get started, you can tryBuilding from Source in order to familiarizeyourself with the components of Solidity and the build process. Also, it may beuseful to become well-versed at writing smart-contracts in Solidity.
Please note that this project is released with aContributor Code of Conduct. 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 whatthe team and contributors are working on, you can join our public team call:
Wednesdays at 3PM CET/CEST.
The call takes place onJitsi.
New topics can be freely added to theagendaand will be scheduled for discussion on the nearest call.
How to Report Issues
To report an issue, please use theGitHub issues tracker. Whenreporting issues, please mention the following details:
Solidity version.
Source code (if applicable).
Operating system.
Steps to reproduce the issue.
Actual vs. expected behavior.
Reducing the source code that caused the issue to a bare minimum is alwaysvery helpful, and sometimes even clarifies a misunderstanding.
For technical discussions about language design, a post in theSolidity forum is the correct place (seeSolidity Language Design).
Workflow for Pull Requests
In order to contribute, please fork off of thedevelop branch and make yourchanges there. Your commit messages should detailwhy you made your changein addition towhat you did (unless it is a tiny change).
If you need to pull in any changes fromdevelop after making your fork (forexample, to resolve potential merge conflicts), please avoid usinggitmergeand instead,gitrebase your branch. This will help us review your changemore easily.
Additionally, if you are writing a new feature, please ensure you add appropriatetest cases undertest/ (see below).
However, if you are making a larger change, please consult with theSolidity Development Gitter channel (different from the one mentioned above — this one isfocused on compiler and language development instead of language usage) first.
New features and bugfixes should be added to theChangelog.md file: pleasefollow the style of previous entries, when applicable.
Finally, please make sure you respect thecoding stylefor this project. Also, even though we do CI testing, please test your code andensure that it builds locally before submitting a pull request.
We highly recommend going through ourreview checklist before submitting the pull request.We thoroughly review every PR and will help you get it right, but there are many common problems that can be easily avoided, making the review much smoother.
Thank you for your help!
Running the Compiler Tests
Prerequisites
For running all compiler tests you may want to optionally install a fewdependencies (evmone,z3,Eldarica,cvc5 <https://github.com/cvc5/cvc5>).
On macOS systems, some of the testing scripts expect GNU coreutils to be installed.This can be easiest accomplished using Homebrew:brewinstallcoreutils.
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 alsogrant it to other usersorenable Developer Mode.
Running the Tests
Solidity includes different types of tests, most of them bundled into theBoost C++ Test Framework applicationsoltest.Runningbuild/test/soltest or its wrapperscripts/soltest.sh is sufficient for most changes.
The./scripts/tests.sh script executes most Solidity tests automatically,including those bundled into theBoost C++ Test Frameworkapplicationsoltest (or its wrapperscripts/soltest.sh), as well as command-line tests andcompilation tests.
The test system automatically tries to discover the location oftheevmone for running the semantic tests.
Theevmone library must be located in thedeps ordeps/lib directory relative to thecurrent working directory, to its parent or its parent’s parent. Alternatively, an explicit locationfor theevmone shared object can be specified via theETH_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-testsflag toscripts/soltest.sh.
Theevmone library should end with the file nameextension.so on Linux,.dll on Windows systems and.dylib on macOS.
For running SMT tests, thez3 executable must be present inPATH.A few SMT tests useEldarica instead ofz3.These require its executable (eld) to be present inPATH for the tests to pass.However, ifEldarica is not found, these tests will be automatically skipped.
Ifz3 is not present on your system, you should disable theSMT tests by exportingSMT_FLAGS=--no-smt before running./scripts/tests.sh orrunning./scripts/soltest.sh--no-smt.These tests arelibsolidity/smtCheckerTests.
Note
To get a list of all unit tests run by Soltest, run./build/test/soltest--list_content=HRF.
For quicker results you can run a subset of, or specific tests.
To run a subset of tests, you can use filters:./scripts/soltest.sh-tTestSuite/TestName,whereTestName can be a wildcard*.
Or, for example, to run all the tests for the yul disambiguator:./scripts/soltest.sh-t"yulOptimizerTests/disambiguator/*"--no-smt.
./build/test/soltest--help has extensive help on all of the options available.
See especially:
show_progress (-p) to show test completion,
run_test (-t) to run specific tests cases, and
report-level (-r) give a more detailed report.
Note
Those working in a Windows environment wanting to run the above basic setswithout z3. Using Git Bash, you use:./build/test/Release/soltest.exe----no-smt.If you are running this in plain Command Prompt, use.\build\test\Release\soltest.exe----no-smt.
If you want to debug using GDB, make sure you build differently than the “usual”.For example, you could run the following command in yourbuild folder:
cmake-DCMAKE_BUILD_TYPE=Debug..makeThis creates symbols so that when you debug a test using the--debug flag,you have access to functions and variables in which you can break or print with.
The CI runs additional tests (includingsolc-js and testing third party Solidityframeworks) that require compiling the Emscripten target.
Writing and Running Syntax Tests
Syntax tests check that the compiler generates the correct error messages for invalid codeand properly accepts valid code.They are stored in individual files inside thetests/libsolidity/syntaxTests folder.These files must contain annotations, stating the expected result(s) of the respective test.The test suite compiles and checks them against the given expectations.
For example:./test/libsolidity/syntaxTests/double_stateVariable_declaration.sol
contracttest{uint256variable;uint128variable;}// ----// DeclarationError: (36-52): Identifier already declared.
A syntax test must contain at least the contract under test itself, followed by the separator//----. The comments that follow the separator are used to describe theexpected compiler errors or warnings. The number range denotes the location in the source where the error occurred.If you want the contract to compile without any errors or warning you can leaveout the separator and the comments that follow it.
In the above example, the state variablevariable was declared twice, which is not allowed. This results in aDeclarationError stating that the identifier was already declared.
Theisoltest tool is used for these tests and you can find it under./build/test/tools/. It is an interactive tool which allowsediting of failing contracts using your preferred text editor. Let’s try to break this test by removing the second declaration ofvariable:
contracttest{uint256variable;}// ----// DeclarationError: (36-52): Identifier already declared.
Running./build/test/tools/isoltest again results in a test failure:
syntaxTests/double_stateVariable_declaration.sol: FAIL Contract: contract test { uint256 variable; } Expected result: DeclarationError: (36-52): Identifier already declared. Obtained result: Successisoltest prints the expected result next to the obtained result, and alsoprovides a way to edit, update or skip the current contract file, or quit the application.
It offers several options for failing tests:
edit:isoltesttries to open the contract in an editor so you can adjust it. It either uses the editor given on the command-line (asisoltest--editor/path/to/editor), in the environment variableEDITORor 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: Quitsisoltest.
All of these options apply to the current contract, exceptquit which stops the entire testing process.
Automatically updating the test above changes it to
contracttest{uint256variable;}// ----
and re-run the test. It now passes again:
Re-running test case...syntaxTests/double_stateVariable_declaration.sol: OK
Note
Choose a name for the contract file that explains what it tests, e.g.double_variable_declaration.sol.Do not put more than one contract into a single file, unless you are testing inheritance or cross-contract calls.Each file should test one aspect of your new feature.
Command-line Tests
Our suite of end-to-end command-line tests checks the behaviour of the compiler binary as a wholein various scenarios.These tests are located intest/cmdlineTests/,one per subdirectory, and can be executed using thecmdlineTests.sh script.
By default the script runs all available tests.You can also provide one or morefile name patterns,in which case only the tests matching at least one pattern will be executed.It is also possible to exclude files matching a specific pattern by prefixing it with--exclude.
By default the script assumes that asolc binary is available inside thebuild/ subdirectoryinside the working copy.If you build the compiler outside of the source tree, you can use theSOLIDITY_BUILD_DIR environmentvariable to specify a different location for the build directory.
Example:
exportSOLIDITY_BUILD_DIR=~/solidity/build/test/cmdlineTests.sh"standard_*""*_yul_*"--exclude"standard_yul_*"
The commands above will run tests from directories starting withtest/cmdlineTests/standard_ andsubdirectories oftest/cmdlineTests/ that have_yul_ somewhere in the name,but no test whose name starts withstandard_yul_ will be executed.It will also assume that the filesolidity/build/solc/solc inside your home directory is thecompiler binary (unless you are on Windows – thensolidity/build/solc/Release/solc.exe).
There are several kinds of command-line tests:
Standard JSON test: contains at least an
input.jsonfile.In general may contain:input.json: input file to be passed to the--standard-jsonoption on the command line.output.json: expected Standard JSON output.args: extra command-line arguments passed tosolc.
CLI test: contains at least an
input.*file (other thaninput.json).In general may contain:input.*: a single input file, whose name will be supplied tosolcon the command line.Usuallyinput.solorinput.yul.args: extra command-line arguments passed tosolc.stdin: content to be passed tosolcvia 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, usuallytest.shortest.py.The script must be executable.
Running the Fuzzer via AFL
Fuzzing is a technique that runs programs on more or less random inputs to find exceptional executionstates (segmentation faults, exceptions, etc). Modern fuzzers are clever and run a directed searchinside the input. We have a specialized binary calledsolfuzzer which takes source code as inputand fails whenever it encounters an internal compiler error, segmentation fault or similar, butdoes not fail if e.g., the code contains an error. This way, fuzzing tools can find internal problems in the compiler.
We mainly useAFL for fuzzing. You need to download andinstall the AFL packages from your repositories (afl, afl-clang) or build them manually.Next, build Solidity (or just thesolfuzzer binary) with AFL as your compiler:
cdbuild# if neededmakecleancmake..-DCMAKE_C_COMPILER=path/to/afl-gcc-DCMAKE_CXX_COMPILER=path/to/afl-g++makesolfuzzer
At this stage, you should be able to see a message similar to the following:
Scanning dependencies of target solfuzzer[ 98%] Building CXX object test/tools/CMakeFiles/solfuzzer.dir/fuzzer.cpp.oafl-cc 2.52b by <[email protected]>afl-as 2.52b by <[email protected]>[+] Instrumented 1949 locations (64-bit, non-hardened mode, ratio 100%).[100%] Linking CXX executable solfuzzer
If the instrumentation messages did not appear, try switching the cmake flags pointing to AFL’s clang binaries:
# if previously failedmakecleancmake..-DCMAKE_C_COMPILER=path/to/afl-clang-DCMAKE_CXX_COMPILER=path/to/afl-clang++makesolfuzzer
Otherwise, upon execution the fuzzer halts with an error saying binary is not instrumented:
afl-fuzz 2.52b by <[email protected]>... (truncated messages)[*] Validating target binary...[-] Looks like the target binary is not instrumented! The fuzzer depends on compile-time instrumentation to isolate interesting test cases while mutating the input data. For more information, and for tips on how to instrument binaries, please see /usr/share/doc/afl-doc/docs/README. When source code is not available, you may be able to leverage QEMU mode support. Consult the README for tips on how to enable this. (It is also possible to use afl-fuzz as a traditional, "dumb" fuzzer. For that, you can use the -n option - but expect much worse results.)[-] PROGRAM ABORT : No instrumentation detected Location : check_binary(), afl-fuzz.c:6920
Next, you need some example source files. This makes it much easier for the fuzzerto find errors. You can either copy some files from the syntax tests or extract test filesfrom the documentation or the other tests:
mkdir/tmp/test_casescd/tmp/test_cases# extract from tests:path/to/solidity/scripts/isolate_tests.pypath/to/solidity/test/libsolidity/SolidityEndToEndTest.cpp# extract from documentation:path/to/solidity/scripts/isolate_tests.pypath/to/solidity/docs
The AFL documentation states that the corpus (the initial input files) should not betoo large. The files themselves should not be larger than 1 kB and there should beat most one input file per functionality, so better start with a small number of.There is also a tool calledafl-cmin that can trim input filesthat result in similar behavior of the binary.
Now run the fuzzer (the-m extends the size of memory to 60 MB):
afl-fuzz-m60-i/tmp/test_cases-o/tmp/fuzzer_reports--/path/to/solfuzzerThe fuzzer creates source files that lead to failures in/tmp/fuzzer_reports.Often it finds many similar source files that produce the same error. You canuse the toolscripts/uniqueErrors.sh to filter out the unique errors.
Whiskers
Whiskers is a string templating system similar toMustache. It is used by thecompiler in various places to aid readability, and thus maintainability and verifiability, of the code.
The syntax comes with a substantial difference to Mustache. The template markers{{ and}} arereplaced by< and> in order to aid parsing and avoid conflicts withYul(The symbols< and> are invalid in inline assembly, while{ and} are used to delimit blocks).Another limitation is that lists are only resolved one depth and they do not recurse. This may change in the future.
A rough specification is the following:
Any occurrence of<name> is replaced by the string-value of the supplied variablename without anyescaping and without iterated replacements. An area can be delimited by<#name>...</name>. It is replacedby as many concatenations of its contents as there were sets of variables supplied to the template system,each time replacing any<inner> items by their respective value. Top-level variables can also be usedinside such areas.
There are also conditionals of the form<?name>...<!name>...</name>, where template replacementscontinue recursively either in the first or the second segment depending on the value of the booleanparametername. If<?+name>...<!+name>...</+name> is used, then the check is whetherthe string parametername is non-empty.
Documentation Style Guide
In the following section you find style recommendations specifically focusing on documentationcontributions to Solidity.
English Language
Use International English, unless using project or brand names. Try to reduce the usage oflocal slang and references, making your language as clear to all readers as possible.Below are some references to help:
Note
While the official Solidity documentation is written in English, there are community contributedTranslationsin other languages available. Please refer to thetranslation guidefor information on how to contribute to the community translations.
Title Case for Headings
Usetitle case for headings. This means capitalise all principal words intitles, but not articles, conjunctions, and prepositions unless they start thetitle.
For example, the following are all correct:
Title Case for Headings.
For Headings Use Title Case.
Local and State Variable Names.
Order of Layout.
Expand Contractions
Use expanded contractions for words, for example:
“Do not” instead of “Don’t”.
“Can not” instead of “Can’t”.
Active and Passive Voice
Active voice is typically recommended for tutorial style documentation as ithelps the reader understand who or what is performing a task. However, as theSolidity documentation is a mixture of tutorials and reference content, passivevoice is sometimes more applicable.
As a summary:
Use passive voice for technical reference, for example language definition and internals of the Ethereum VM.
Use active voice when describing recommendations on how to apply an aspect of Solidity.
For example, the below is in passive voice as it specifies an aspect of Solidity:
Functions can be declared
purein which case they promise not to readfrom or modify the state.
For example, the below is in active voice as it discusses an application of Solidity:
When invoking the compiler, you can specify how to discover the first elementof a path, and also path prefix remappings.
Common Terms
“Function parameters” and “return variables”, not input and output parameters.
Code Examples
A CI process tests all code block formatted code examples that begin withpragmasolidity,contract,libraryorinterface using the./test/cmdlineTests.sh script when you create a PR. If you are adding new code examples,ensure they work and pass tests before creating the PR.
Ensure that all code examples begin with apragma version that spans the largest where the contract code is valid.For examplepragmasolidity>=0.4.0<0.9.0;.
Running Documentation Tests
Make sure your contributions pass our documentation tests by running./docs/docs.sh that installs dependenciesneeded for documentation and checks for any problems such as broken links or syntax issues.
Solidity Language Design
To actively get involved in the language design process and to share your ideas concerning the future of Solidity,please join theSolidity forum.
The Solidity forum serves as the place to propose and discuss new language features and their implementation inthe early stages of ideation or modifications of existing features.
As soon as proposals get more tangible, theirimplementation will also be discussed in theSolidity GitHub repositoryin the form of issues.
In addition to the forum and issue discussions, we regularly host language design discussion calls in which selectedtopics, issues or feature implementations are debated in detail. The invitation to those calls is shared via the forum.
We are also sharing feedback surveys and other content that is relevant to language design in the forum.
If you want to know where the team is standing in terms of implementing new features, you can follow the implementation status in theSolidity GitHub project.Issues in the design backlog need further specification and will either be discussed in a language design call or in a regular team call. You cansee the upcoming changes for the next breaking release by changing from the default branch (develop) to thebreaking branch.
For ad-hoc cases and questions, you can reach out to us via theSolidity-dev Gitter channel — adedicated 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.