Solidityソースファイルのレイアウト

 

ソースファイルには、任意の数のコントラクト定義、インクルードディレクティブおよびプラグマディレクティブを含めることができます。

Version Pragma

ソースファイルには、互換性のない変更を導入する可能性のある将来のコンパイラバージョンでコンパイルされることを拒否するために、いわゆるバージョンプラグマで注釈を付けることができます。 このような変更を最小限に抑えようとすると、セマンティクスの変更にも構文の変更が必要になるような変更が加えられますが、もちろんこれは必ずしも可能ではありません。 そのため、少なくとも変更の激しいリリースのチェンジログを読むことは常に良い考えです。これらのリリースでは、常に0.x.0またはx.0.0という形式のバージョンが存在します。

 

バージョンプラグマは、次のように使用されます。

 

pragma solidity ^0.4.0;

 

このようなソースファイルはバージョン0.4.0より前のコンパイラではコンパイルされず、バージョン0.5.0からコンパイラでも機能しません(この2番目の条件は^を使用して追加されます)。 この背後にあるアイデアは、バージョン0.5.0までは大きな変更はありませんので、私たちのコードが意図したとおりにコンパイルされることを常に確認できます。 私たちはコンパイラの正確なバージョンを修正していないので、バグ修正リリースはまだ可能です。

コンパイラのバージョンにはるかに複雑なルールを指定することができます。式はnpmで使用される式に従います。

 

他のソースファイルのインポート

Syntax and Semantics(構文とセマンティクス)

SolidityはJavaScript(ES6以降)で使用可能なものと非常に似ているインポートステートメントをサポートしていますが、Solidityは「デフォルトエクスポート」の概念を認識していません。

グローバルレベルでは、次の形式のimport文を使用できます。

 

import "filename";

 

この文は、 “filename”(およびそこからインポートされたシンボル)のすべてのグローバルシンボルを現在のグローバルスコープにインポートします(ES6では異なりますが、Solidityでは下位互換性があります)。

 

import * as symbolName from "filename";

 

..新しいグローバルシンボルsymbolNameを作成します。メンバのメンバはすべて “filename”のグローバルシンボルです。

 

import {symbol1 as alias, symbol2} from "filename";

 

…は、それぞれ、 “filename”からsymbol1とsymbol2を参照する新しいグローバルシンボルaliasとsymbol2を作成します。

別の構文はES6の一部ではありませんが、おそらく便利です:

 

import "filename" as symbolName;

 

これは “filename”からのsymbolNameとしてのimport *と同等です。

パス

上の例では、filenameは常に/とディレクトリ区切り文字を持つパスとして扱われます。 親ディレクトリとして現在と..を指定します。 いつ 。 または..の後に/以外の文字が続いた場合、現在のディレクトリまたは親ディレクトリとみなされません。 すべてのパス名は、現在のパスで始まらない限り、絶対パスとして扱われます。 または親ディレクトリ…

現在のファイルと同じディレクトリからファイルxをインポートするには、import “./x”をx;とします。 import “x”をxとすると、 代わりに、別のファイルを参照することができます(グローバルな “includeディレクトリ”内)。

実際にパスを解決する方法は、コンパイラ(下記参照)によって異なります。 一般に、ディレクトリ階層はあなたのローカルファイルシステムに厳密にマッピングする必要はなく、例えば、ディレクトリ階層を介して発見されたリソースにマップすることもできます。 ipfs、httpまたはgitです。

実際のコンパイラでの使用

コンパイラが呼び出されると、パスの最初の要素を発見する方法を指定することができるだけでなく、パスプレフィックスの再マッピングを指定することができます。 github.com/ethereum/dapp-bin/libraryは/ usr / local / dapp-bin / libraryに再マップされ、コンパイラはそこからファイルを読み込みます。複数の再マッピングを適用できる場合、最も長いキーを持つものが最初に試されます。これは、例えば、次のような「フォールバック・リマッピング」を可能にする。 “”は “/ usr / local / include / solidity”にマップされます。さらに、これらの再マッピングはコンテキストに依存する可能性があります。同じ名前のライブラリの異なるバージョン。

solc:

solc(コマンドラインコンパイラ)の場合、これらの再マッピングはcontext:prefix = targetargumentsとして提供されます。context:とtarget =両方の部分はオプションです(この場合targetはデフォルトでprefixになります)。通常のファイルであるすべての再マッピング値がコンパイルされます(依存関係を含む)。このメカニズムは完全に下位互換性があります(ファイル名に=または:)が含まれていない限り、改ざんの変更はありません)。接頭辞で始まるファイルをインポートするディレクトリコンテキスト以下のファイル内のすべてのインポートは、接頭辞をターゲットに置き換えることによってリダイレクトされます。

例として、github.com/ethereum/dapp-bin/を/ usr / local / dapp-binにローカルにクローンすると、ソースファイルで次のように使用できます。

 

import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;

 

コンパイラを次のように実行します。

 

solc github.com/ethereum/dapp-bin/=/usr/local/dapp-bin/ source.sol

 

より複雑な例として、非常に古いバージョンのdapp-binを使用するモジュールを使用しているとします。 その古いバージョンのdapp-binは/ usr / local / dapp-bin_oldでチェックアウトされています。

 

solc module1:github.com/ethereum/dapp-bin/=/usr/local/dapp-bin/ \
     module2:github.com/ethereum/dapp-bin/=/usr/local/dapp-bin_old/ \
     source.sol

 

module2のすべてのインポートは古いバージョンを指しますが、module1のインポートは新しいバージョンを取得します。

solcでは、特定のディレクトリからのファイルのみをインクルードすることができます。明示的に指定されたソースファイルの1つ(またはサブディレクトリ)または再マッピング対象のディレクトリ(またはサブディレクトリ)になければなりません。 直接絶対インクルードを許可したい場合は、再マッピング= /を追加するだけです。

有効なファイルにつながる複数の再マッピングがある場合、最も長い共通接頭辞を持つ再マッピングが選択されます。

 

Remix:

 

Remixはgithubの自動再マッピングを提供し、ネットワーク経由でファイルを自動的に取得します。itimap;として、例えば、「github.com/ethereum/dapp-bin/library/iterable_mapping.sol」をインポートすることで、反復可能マッピングをインポートできます。

将来、他のソースコードプロバイダが追加される可能性があります。

コメント

単一行コメント(//)と複数行コメント(/*…*/)が可能です。

 

// This is a single-line comment.

/*
This is a
multi-line comment.
*/

 

さらに、natspecコメントと呼ばれるもう1つのタイプのコメントがあります。これは、ドキュメンテーションがまだ書かれていないためです。 それらは3つのスラッシュ(///)または2つのアスタリスクブロック(/ ** … * /)で書かれており、関数の宣言またはステートメントの直上で使用する必要があります。 これらのコメントの中にDoxygenスタイルのタグを使用して関数を文書化したり、正式な検証のための条件を注釈付けしたり、関数を呼び出そうとしたときにユーザーに表示される確認テキストを提供することができます。

次の例では、コントラクトのタイトル、2つの入力パラメータと2つの戻り値の説明を文書化します。

 

pragma solidity ^0.4.0;

/** @title Shape calculator. */
contract shapeCalculator {
    /** @dev Calculates a rectangle's surface and perimeter.
      * @param w Width of the rectangle.
      * @param h Height of the rectangle.
      * @return s The calculated surface.
      * @return p The calculated perimeter.
      */
    function rectangle(uint w, uint h) returns (uint s, uint p) {
        s = w * h;
        p = 2 * (w + h);
    }
}