コントリビューティング

貢献はいつでも歓迎です。 Solidityに貢献するための選択肢はたくさんあります。

特に、以下の領域でのサポートに感謝します。

まずは ソースからのビルド を使って、Solidityのコンポーネントやビルドプロセスに慣れてみてください。 また、Solidityでのスマートコントラクトの書き方を熟知することも有効でしょう。

このプロジェクトは Contributor Code of Conduct 付きで公開されていることにご注意ください。 イシュー、プルリクエスト、Gitterチャンネルなど、このプロジェクトに参加することで、その条件を守ることに同意したことになります。

チームコール

議論したいイシューやプルリクエストがある場合や、チームやコントリビューターが取り組んでいることを聞きたい場合は、パブリックなチームコールに参加できます。

  • 毎週水曜日の午後3時(CET/CEST)から。

コールは Jitsi で行われます。

イシューの報告方法

問題を報告するには、 GitHubイシュートラッカー を利用してください。 報告の際には、以下の内容をお知らせください。

  • Solidityのバージョン。

  • ソースコード(必要に応じて)。

  • オペレーティングシステム。

  • イシューを再現するための手順。

  • 実際の挙動と期待される挙動の比較。

イシューの原因となったソースコードを最小限に減らすことは、常に非常に役に立ち、時には誤解を解くことにもなります。

言語設計に関する技術的な議論については、 Solidity forum への投稿が正しい場所です( Solidityの言語設計 を参照してください)。

プルリクエストのワークフロー

貢献するためには、 develop ブランチをフォークして、そこで変更を加えてください。 コミットメッセージには、変更した内容に加えて、変更した理由を詳しく書いてください(小さな変更の場合を除く)。

フォーク後に develop からの変更を取り込む必要がある場合(たとえば、潜在的なマージコンフリクトを解決するため)、 git merge の使用を避け、代わりに git rebase でブランチを作成してください。 そうすることで、あなたの変更をより簡単に確認できます。

また、新機能を書いている場合は、 test/ の下に適切なテストケースを追加してください(下記を参照してください)。

ただし、より大きな変更を行う場合は、まず Solidity Development Gitter チャンネル (前述のものとは異なり、こちらは言語の使い方ではなく、コンパイラや言語の開発に重点を置いています)に相談してください。

新機能やバグフィックスは、 Changelog.md ファイルに追加してください。 該当する場合は、過去のエントリーのスタイルに従ってください。

最後に、このプロジェクトの コーディングスタイル を尊重するようにしてください。 また、CIテストを行っているとはいえ、プルリクエストを提出する前にコードをテストし、ローカルにビルドされることを確認してください。

プルリクエストを提出する前に、私たちの レビューチェックリスト に目を通すことを強くお勧めします。 私たちはすべてのPRを徹底的にレビューし、あなたが正しい結果を得られるようサポートしますが、簡単に回避できる多くの一般的な問題があり、レビューがよりスムーズに行えるようになります。

ご協力ありがとうございます!

コンパイラーテストの実行

事前準備

すべてのコンパイラテストを実行するために、いくつかの依存関係( evmonelibz3 )をオプションでインストールできます。

macOSでは、一部のテストスクリプトでGNU coreutilsがインストールされていることが前提となっています。 インストールするにはHomebrewを使うのが最も簡単です: brew install coreutils

Windowsシステムでは、シンボリックリンクを作成する権限を持っていることを確認してください、さもなければいくつかのテストが失敗するかもしれません。 管理者がその権限を持つべきですが、 他のユーザーにその権限を与えること や、 開発者モードを有効にする ことも可能です。

テストの実行

Solidityには様々なタイプのテストがあり、そのほとんどが Boost C++ Test Framework アプリケーション soltest にバンドルされています。 ほとんどの変更には、 build/test/soltest またはそのラッパー scripts/soltest.sh を実行すれば十分です。

./scripts/tests.sh スクリプトは、 Boost C++ Test Framework アプリケーション soltest (またはそのラッパー scripts/soltest.sh )にバンドルされているものや、コマンドラインテスト、コンパイルテストなど、ほとんどのSolidityテストを自動的に実行します。

テストシステムは、セマンティックテストを実行するための evmone の場所を自動的に発見しようとします。

evmone ライブラリは、現在の作業ディレクトリ、その親、またはその親の親に対する deps または deps/lib ディレクトリに配置されている必要があります。 また、環境変数 ETH_EVMONE を使って evmone 共有オブジェクトの場所を明示的に指定することもできます。

evmone は主にセマンティックテストとガステストを実行するために必要です。 インストールされていない場合は、 scripts/soltest.sh--no-semantic-tests フラグを渡すことで、これらのテストをスキップできます。

evmone ライブラリと hera ライブラリは、どちらもファイル名の拡張子が、Linuxでは .so 、Windowsシステムでは .dll 、macOSでは .dylib になるようにしてください。

SMTテストを実行するためには、 libz3 ライブラリがインストールされており、コンパイラのconfigure段階で cmake が位置を特定できる必要があります。

libz3 ライブラリがシステムにインストールされていない場合は、 ./scripts/tests.sh を実行する前に SMT_FLAGS=--no-smt をエクスポートしてSMTテストを無効にするか、 ./scripts/soltest.sh --no-smt を実行する必要があります。 これらのテストは libsolidity/smtCheckerTestslibsolidity/smtCheckerTestsJSON です。

注釈

Soltestで実行されたすべてのユニットテストのリストを取得するには、 ./build/test/soltest --list_content=HRF を実行してください。

より迅速な結果を得るために、一部のテストや特定のテストを実行できます。

テストのサブセットを実行するには、 ./scripts/soltest.sh -t TestSuite/TestName``のようにフィルターを使うことができます。 ``TestName にはワイルドカード * を指定できます。

あるいは、例えば、yul disambiguatorのすべてのテストを実行するには、次のようにします。 ./scripts/soltest.sh -t "yulOptimizerTests/disambiguator/*" --no-smt です。

./build/test/soltest --help には、利用可能なすべてのオプションに関する広範なヘルプがあります。

特に、以下のオプションを参考にしてください。

注釈

Windows環境で、上記の基本セットをlibz3なしで実行したい方は、次のようにしてください。 Git Bashを使っている場合、 ./build/test/Release/soltest.exe -- --no-smt を実行してください。 プレーンなコマンドプロンプトで実行する場合、 .\build\test\Release\soltest.exe -- --no-smt を実行してください。

GDBを使ってデバッグしたい場合は、「通常」とは異なる方法でビルドするようにしてください。 例えば、 build フォルダで以下のコマンドを実行します。

cmake -DCMAKE_BUILD_TYPE=Debug ..
make

これにより、 --debug フラグを使ってテストをデバッグする際に、ブレークやプリントが可能な関数や変数にアクセスできるようにシンボルが作成されます。

CIは、Emscriptenターゲットのコンパイルを必要とする追加のテスト( solc-js やサードパーティのSolidityフレームワークのテストなど)を実行します。

構文テストの作成と実行

構文テストは、コンパイラが無効なコードに対して正しいエラーメッセージを生成し、有効なコードを適切に受け入れるかどうかをチェックします。 これらのテストは tests/libsolidity/syntaxTests フォルダー内の個々のファイルに格納されます。 これらのファイルには、それぞれのテストで期待される結果を記載した注釈を含める必要があります。 テストスイートは、これらのファイルをコンパイルし、期待される結果に対してチェックします。

例えば、次のようなものです。 ./test/libsolidity/syntaxTests/double_stateVariable_declaration.sol

contract test {
    uint256 variable;
    uint128 variable;
}
// ----
// DeclarationError: (36-52): Identifier already declared.

構文テストは、少なくともテスト対象のコントラクトそのものと、それに続くセパレータ // ---- を含んでいなければなりません。 セパレータに続くコメントは、予想されるコンパイラのエラーや警告を説明するために使用されます。 数字の範囲は、エラーが発生したソースの場所を示します。 もし、エラーや警告を出さずにコントラクトをコンパイルしたい場合は、セパレータとそれに続くコメントを省くことができます。

上の例では、状態変数 variable が2回宣言されていますが、これは許されません。 この結果、識別子がすでに宣言されているという DeclarationError が表示されます。

これらのテストには isoltest ツールが使用されており、 ./build/test/tools/ で見つけることができます。 これは対話型のツールで、好みのテキストエディタを使って失敗したコントラクトを編集できます。 variable の2番目の宣言を削除することで、このテストを破ってみましょう。

contract test {
    uint256 variable;
}
// ----
// DeclarationError: (36-52): Identifier already declared.

./build/test/tools/isoltest を再度実行すると、テストが失敗します。

syntaxTests/double_stateVariable_declaration.sol: FAIL
    Contract:
        contract test {
            uint256 variable;
        }

    Expected result:
        DeclarationError: (36-52): Identifier already declared.
    Obtained result:
        Success

isoltest は、期待される結果を得られた結果の横に表示し、また、現在のコントラクトファイルを編集、更新、スキップしたり、アプリケーションを終了する方法を提供します。

テストを失敗させるためのいくつかのオプションがあります。

  • edit: isoltest は、コントラクト内容を調整できるように、エディタでコントラクト内容を開こうとします。 isoltest --editor /path/to/editor のようにコマンドラインで指定されたエディタを使用するか、 EDITOR のように環境変数で指定されたエディタを使用するか、 /usr/bin/editor だけを使用するか(順不同)。

  • update: テスト中のコントラクトに対する期待値を更新。 これは、満たされていない期待値を削除し、満たされていない期待値を追加することで、アノテーションを更新します。 その後、テストが再度実行されます。

  • skip: この特定のテストの実行をスキップします。

  • quit: isoltest を終了します。

これらのオプションは、テストプロセス全体を停止する quit を除いて、すべて現在のコントラクトに適用されます。

上のテストを自動的に更新すると、次のように変更されます。

contract test {
    uint256 variable;
}
// ----

そして、テストを再実行します。 これで合格です。

Re-running test case...
syntaxTests/double_stateVariable_declaration.sol: OK

注釈

コントラクトファイルの名前には、 double_variable_declaration.sol など、テストする内容を説明するものを選んでください。 継承やクロスコントラクトコールをテストする場合を除き、1つのファイルに複数のコントラクトを入れないでください。 各ファイルは、新機能の1つの側面をテストする必要があります。

コマンドラインテスト

エンドツーエンドのコマンドラインテストスイートは、様々なシナリオにおけるコンパイラバイナリ全体の動作をチェックします。 これらのテストは test/cmdlineTests/ にサブディレクトリごとに1つずつあり、 cmdlineTests.sh スクリプトを使って実行できます。

デフォルトでは、スクリプトは利用可能なすべてのテストを実行します。 また、1つ以上の ファイル名パターン を指定することもでき、その場合は少なくとも1つのパターンにマッチするテストのみが実行されます。 また、特定のパターンの前に --exclude をつけることで、そのパターンにマッチするファイルを除外することもできます。

デフォルトでは、スクリプトは solc バイナリが作業コピーの build/ サブディレクトリにあると仮定します。 コンパイラをソースツリーの外でビルドする場合は、 SOLIDITY_BUILD_DIR 環境変数を使ってビルドディレクトリを別の場所に指定できます。

例:

export SOLIDITY_BUILD_DIR=~/solidity/build/
test/cmdlineTests.sh "standard_*" "*_yul_*" --exclude "standard_yul_*"

上記のコマンドは test/cmdlineTests/standard_ で始まるディレクトリと test/cmdlineTests/ のサブディレクトリで、名前のどこかに _yul_ が含まれるテストを実行しますが、名前が standard_yul_ で始まるテストは実行されません。 また、ホームディレクトリにある solidity/build/solc/solc ファイルがコンパイラのバイナリであると仮定されます(Windows を使用している場合は、 solidity/build/solc/Release/solc.exe を使用します)。

コマンドラインテストにはいくつかの種類があります。

  • 標準JSONテスト: 少なくとも input.json ファイルが含まれます。 一般的に含まれているものは以下の通りです。

    • input.json: コマンドラインで --standard-json オプションに渡す入力ファイル。

    • output.json: 標準JSON出力ファイル。

    • args: solc に渡す追加のコマンドライン引数。

  • CLIテスト: 少なくとも input.* ファイルが含まれます( input.json 以外). 一般的に含まれているものは以下の通りです。

    • input.*: コマンドラインで solc に与えられる単一の入力ファイル。 通常は input.sol または input.yul

    • args: solc に渡される追加のコマンドライン引数。

    • stdin: 標準入力から solc に渡す内容。

    • output: 期待される標準出力の内容。

    • err: 期待される標準エラー出力の内容。

    • exit: 期待される終了コード。省略された場合は0。

  • スクリプトテスト: test.* ファイルが含まれます。 一般的に含まれているものは以下の通りです。

    • test.*: 単一のスクリプトで、通常は test.sh または test.py 。 スクリプトは実行可能でなければなりません。

AFLによるファザーの実行

ファジングとは、多かれ少なかれランダムな入力に対してプログラムを実行し、例外的な実行状態(セグメンテーションフォールトや例外など)を見つける技術です。 最近のFuzzerは賢く、入力の内部で有向検索を行います。 私たちは solfuzzer と呼ばれる特殊なバイナリを持っています。 solfuzzer はソースコードを入力として受け取り、内部のコンパイラエラーやセグメンテーションフォールトなどに遭遇するたびに失敗しますが、例えばコードにエラーが含まれている場合は失敗しません。 このようにして、ファジングツールはコンパイラの内部問題を見つけることができます。

ファジングには主に AFL を使用しています。 AFLパッケージをリポジトリ(afl, afl-clang)からダウンロードしてインストールするか、手動でビルドする必要があります。 次に、AFLをコンパイラとしてSolidity(または solfuzzer バイナリのみ)をビルドします。

cd build
# if needed
make clean
cmake .. -DCMAKE_C_COMPILER=path/to/afl-gcc -DCMAKE_CXX_COMPILER=path/to/afl-g++
make solfuzzer

この段階では、以下のようなメッセージが表示されます。

Scanning dependencies of target solfuzzer
[ 98%] Building CXX object test/tools/CMakeFiles/solfuzzer.dir/fuzzer.cpp.o
afl-cc 2.52b by <lcamtuf@google.com>
afl-as 2.52b by <lcamtuf@google.com>
[+] Instrumented 1949 locations (64-bit, non-hardened mode, ratio 100%).
[100%] Linking CXX executable solfuzzer

インストルメンテーションメッセージが表示されない場合は、AFLのclangバイナリを指すcmakeフラグを切り替えてみてください。

# if previously failed
make clean
cmake .. -DCMAKE_C_COMPILER=path/to/afl-clang -DCMAKE_CXX_COMPILER=path/to/afl-clang++
make solfuzzer

そうでない場合は、実行時に「binary is not instrumented」というエラーでファザーが停止します。

afl-fuzz 2.52b by <lcamtuf@google.com>
... (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

次に、いくつかのサンプルソースファイルが必要です。 これにより、ファザーがエラーを見つけるのが非常に簡単になります。 構文テストからいくつかのファイルをコピーするか、ドキュメントや他のテストからテストファイルを抽出できます。

mkdir /tmp/test_cases
cd /tmp/test_cases
# extract from tests:
path/to/solidity/scripts/isolate_tests.py path/to/solidity/test/libsolidity/SolidityEndToEndTest.cpp
# extract from documentation:
path/to/solidity/scripts/isolate_tests.py path/to/solidity/docs

AFLのドキュメントでは、コーパス(最初の入力ファイル)はあまり大きくしない方が良いとされています。 ファイル自体の大きさは1kB以下で、1つの機能に対して入力ファイルは多くても1つなので、少ない数から始めた方が良いでしょう。 また、 afl-cmin というツールがあり、バイナリの挙動が似ている入力ファイルをトリミングできます。

ここで、ファザーを実行します( -m ではメモリサイズを60MBに拡張しています)。

afl-fuzz -m 60 -i /tmp/test_cases -o /tmp/fuzzer_reports -- /path/to/solfuzzer

ファザーは、 /tmp/fuzzer_reports の失敗につながるソースファイルを作成します。 多くの場合、同じエラーを発生させる多くの類似したソースファイルを見つけます。 ツール scripts/uniqueErrors.sh を使って、固有のエラーをフィルタリングできます。

Whiskers

Whiskers は、 Mustache に似た文字列テンプレートシステムです。 コンパイラは、コードの可読性、ひいては保守性や検証性を高めるために、さまざまな場所でこのシステムを使用しています。

この構文は、Mustacheとは大幅に異なります。 テンプレートマーカー {{}} は、解析を助け、 Yul との衝突を避けるために、 <> に置き換えられています(シンボル <> はインラインアセンブリでは無効であり、 {} はブロックの区切りに使用されます)。 もう1つの制限は、リストは1つの深さまでしか解決されず、再帰的にはならないことです。 これは将来変更される可能性があります。

大まかな仕様は以下の通りです。

<name> が出現すると、与えられた変数 name の文字列値で置き換えられます。 このとき、エスケープや繰り返しの置き換えは行われません。 ある領域は <#name>...</name> で区切ることができます。 領域は、テンプレートシステムに供給された変数セットの数だけ、その内容を連結したものに置き換えられ、その都度、 <inner> 項目をそれぞれの値で置き換えます。 トップレベルの変数は、このような領域内で使用することもできます。

<?name>...<!name>...</name> 形式の条件式もあります。 ここでは、ブーリアンパラメータ name の値に応じて、テンプレートの置換が最初のセグメントまたは2番目のセグメントで再帰的に続けられます。 <?+name>...<!+name>...</+name> を使用する場合は、文字列パラメータ name が空でないかどうかをチェックします。

ドキュメンテーションのスタイルガイド

次のセクションでは、Solidityへのドキュメント提供に特化したスタイルの推奨事項を紹介します。

英語

プロジェクト名やブランド名を使用する場合を除き、国際英語を使用してください。 ローカルのスラングや参考文献の使用を極力控え、誰が読んでも分かりやすい言葉遣いを心がけてください。 以下は参考資料です。

注釈

公式のSolidityドキュメントは英語で書かれていますが、コミュニティの貢献によって他の言語の 翻訳 も利用できます。 コミュニティの翻訳に貢献する方法については、 翻訳ガイド を参照してください。

見出しのタイトルケース

見出しには タイトルケース を使用します。 つまり、タイトルの主要な単語はすべて大文字にしますが、冠詞、接続詞、前置詞はタイトルの最初でない限り、大文字にしません。

例えば、次のようなものはすべて正しいです。

  • Title Case for Headings

  • For Headings Use Title Case

  • Local and State Variable Names

  • Order of Layout

短縮形の展開

単語では短縮形を利用しないでください。 例えば、

  • 「Don't」ではなく「Do not」。

  • 「Can't」ではなく「Can not」。

能動態と受動態

チュートリアル形式のドキュメントでは、誰が、何がタスクを実行しているのかを読者が理解しやすいように、能動態(アクティブボイス)を推奨します。 しかし、Solidityのドキュメントは、チュートリアルとリファレンスコンテンツが混在しているため、受動態(パッシブボイス)の方が適している場合もあります。

要約すると

  • 例えば、Ethereum VMの言語定義や内部構造などの技術的な参照には、受動態を使用します。

  • Solidityのある側面を適用するための推奨事項を説明する際には、能動態を使用します。

例えば、以下はSolidityの側面を指定しているため、受動態になっています。

Functions can be declared pure in which case they promise not to read from or modify the state.

例えば、以下はSolidityのアプリケーションについて説明しているので、能動態になっています。

When invoking the compiler, you can specify how to discover the first element of a path, and also path prefix remappings.

一般的用語

  • 「function parameters」と「return variables」であり、input parametersとoutput parametersではありません。

コードの例

CIプロセスでは、PRを作成する際に ./test/cmdlineTests.sh スクリプトを使用して pragma soliditycontractlibraryinterface で始まるコードブロック形式のコード例をすべてテストします。 新しいコード例を追加する場合は、PRを作成する前にそのコード例が動作し、テストに合格することを確認してください。

すべてのコード例は、コントラクトコードが有効な最大の範囲をカバーする pragma バージョンで始まるようにします。 例えば、 pragma solidity >=0.4.0 <0.9.0; などとしてください。

ドキュメントのテストの実行

ドキュメントに必要な依存関係をインストールし、リンク切れや構文の問題などの問題をチェックする ./docs/docs.sh を実行することで、あなたの貢献が私たちのドキュメントテストに合格することを確認してください。

Solidityの言語設計

言語設計のプロセスに積極的に参加し、Solidityの将来に関するアイデアを共有するには、 Solidityフォーラム に参加してください。

Solidityフォーラムは、新しい言語機能やその実装のアイデアの初期段階や、既存の機能の修正を提案し、議論する場として機能しています。

提案が具体的になれば、その実現に向けて SolidityのGitHubリポジトリ でもイシューという形で議論されます。

フォーラムやイシューの議論に加えて、定期的に言語設計ディスカッションコールを開催し、特定のトピックや課題、機能の実装について詳細に議論しています。 これらのコールへの招待状は、フォーラムを通じて共有されます。

また、フィードバックアンケートなど、言語設計に関連したコンテンツをフォーラムで共有しています。

新機能の実装についてチームの状況を知りたい場合は、 SolidityのGithubプロジェクト で実装状況を確認できます。 デザインバックログに登録されている問題は、さらに詳細な仕様が必要なため、言語デザインコールまたは通常のチームコールで議論されます。 デフォルトのブランチ( develop )から breakingブランチ に変更することで、次のブレーキングリリースに向けた変更点を確認できます。

その場限りのケースや質問については、Solidityコンパイラや言語開発に関する会話のための専用チャットルームである Solidity-dev Gitter チャンネル を通じて連絡を取ることができます。

言語設計のプロセスをより協力的で透明性の高いものに改善するために、みなさんの意見をお聞かせください。