インポートパスの解決
全てのプラットフォームで再現可能なビルドをサポートするために、Solidityコンパイラはソースファイルが格納されるファイルシステムを抽象化する必要があります。 インポートで使用されるパスは、どこでも同じように動作しなければならない一方で、コマンドラインインターフェースは、良いユーザーエクスペリエンスを提供するために、プラットフォーム固有のパスを扱うことができなければなりません。 このセクションでは、Solidityがこれらの要件をどのように解決しているかを詳しく説明します。
バーチャルファイルシステム
コンパイラは内部データベース( virtual filesystem 、略して VFS )を保持しており、各ソースユニットには不透明で構造化されていない識別子である一意の ソースユニット名 が割り当てられています。 インポート文 を使用する際には、ソースユニット名を参照する インポートパス を指定します。
インポートコールバック
VFSには、コンパイラーが入力として受け取ったファイルのみが最初に入力されます。 使用するコンパイラの種類によって異なる インポートコールバック を使用して、コンパイル中に追加のファイルを読み込むことができます(後述)。 コンパイラは、VFS内のインポートパスに一致するソースユニット名が見つからない場合、コールバックを起動し、その名前で配置されるソースコードを取得する役割を果たします。 インポートコールバックは、ソースユニット名をパスとしてだけでなく、任意の方法で自由に解釈できます。 必要なときに利用可能なコールバックがない場合や、ソースコードの取得に失敗した場合は、コンパイルに失敗します。
コマンドラインコンパイラには、ソースユニット名をローカルファイルシステムのパスとして解釈する初歩的なコールバックである Host Filesystem Loader が用意されています。 JavaScriptインターフェース はデフォルトでは提供していませんが、ユーザーが提供することもできます。 このメカニズムを使用して、ローカルファイルシステム以外の場所からソースコードを取得できます(ブラウザでコンパイラを実行している場合など、アクセスできない場合もあります)。 例えば、 Remix IDE は汎用性の高いコールバックを提供しており、これを利用して HTTP、IPFS、SwarmのURLからファイルをインポートしたり、NPMレジストリのパッケージを直接参照したり できます。
注釈
Host Filesystem Loaderのファイル検索は、プラットフォームに依存します。 例えば、ソースユニット名のバックスラッシュは、ディレクトリセパレータとして解釈されるかどうか、また、検索では大文字と小文字が区別されるかどうかが、基礎となるプラットフォームに依存します。
移植性を考慮して、特定のインポートコールバックでのみ正しく動作するインポートパスや、特定のプラットフォームでのみ動作するインポートパスは使用しないことをお勧めします。 例えば、バックスラッシュをサポートするプラットフォームでもパスの区切りとして機能するフォワードスラッシュを常に使用するべきです。
Virtual Filesystemの初期コンテンツ
VFSの初期コンテンツは、コンパイラの起動方法によって異なります。
solc / コマンドラインインターフェース
コンパイラのコマンドラインインターフェースを使用してファイルをコンパイルする際に、Solidityコードを含むファイルへの1つまたは複数のパスを指定します。
solc contract.sol /usr/local/dapp-bin/token.sol
この方法で読み込まれたファイルのソースユニット名は、そのパスを正規の形式に変換し、可能であればベースパスまたはインクルードパスのいずれかからの相対パスとすることで構築されます。 この処理の詳細については、 CLI Path NormalizationとStripping を参照してください。
Standard JSON
Standard JSON APIを使用する場合( JavaScriptインターフェース または
--standard-json
コマンドラインオプションを使用)、すべてのソースファイルのコンテンツなどを含むJSONフォーマットの入力を提供します。{ "language": "Solidity", "sources": { "contract.sol": { "content": "import \"./util.sol\";\ncontract C {}" }, "util.sol": { "content": "library Util {}" }, "/usr/local/dapp-bin/token.sol": { "content": "contract Token {}" } }, "settings": {"outputSelection": {"*": { "*": ["metadata", "evm.bytecode"]}}} }
sources
辞書は仮想ファイルシステムの初期コンテンツとなり、そのキーはソースユニット名として使用されます。
Standard JSON (インポートコールバック経由)
Standard JSONでは、ソースコードの取得にインポートコールバックを使用するようにコンパイラに指示することも可能です。
{ "language": "Solidity", "sources": { "/usr/local/dapp-bin/token.sol": { "urls": [ "/projects/mytoken.sol", "https://example.com/projects/mytoken.sol" ] } }, "settings": {"outputSelection": {"*": { "*": ["metadata", "evm.bytecode"]}}} }
インポートコールバックが利用可能な場合、コンパイラーは
urls
で指定された文字列を一つずつ、読み込みに成功するかリストの最後に達するまで渡します。ソースユニット名は
content
を使用する場合と同じ方法で決定されます。 これらはsources
辞書のキーであり、urls
の内容はこれらに何ら影響を与えません。
標準入力
コマンドラインでは、コンパイラの標準入力にソースを送信することも可能です。
echo 'import "./util.sol"; contract C {}' | solc -
引数の1つとして使われる
-
は、標準入力の内容を仮想ファイルシステムの特別なソースユニット名<stdin>
の下に置くようにコンパイラに指示します。
VFSが初期化された後も、インポートコールバックによってのみファイルを追加できます。
インポート
インポート文では インポートパス を指定します。 インポートパスの指定方法に基づいて、インポートは2つの種類に分けられます。
ダイレクトインポート: ソースユニットのフルネームを直接指定します。
相対インポート:
./
または../
で始まるパスを指定して、インポートファイルのソースユニット名と組み合わせます。
import "./math/math.sol";
import "contracts/tokens/token.sol";
上の例では、 ./math/math.sol
と contracts/tokens/token.sol
がインポートパスで、変換後のソースユニット名はそれぞれ contracts/math/math.sol
と contracts/tokens/token.sol
です。
ダイレクトインポート
./
や ../
で始まらないインポートは、 ダイレクトインポート です。
import "/project/lib/util.sol"; // source unit name: /project/lib/util.sol
import "lib/util.sol"; // source unit name: lib/util.sol
import "@openzeppelin/address.sol"; // source unit name: @openzeppelin/address.sol
import "https://example.com/token.sol"; // source unit name: https://example.com/token.sol
import remappings を適用すると、インポートパスは単にソースユニット名になります。
注釈
ソースユニット名は単なる識別子であり、その値がたまたまパスのように見えたとしても、シェルで一般的に期待される正規化ルールの対象にはなりません。
/./
や /../
のセグメントや複数のスラッシュのシーケンスがあっても、その一部として残ります。
ソースが標準のJSONインターフェースで提供されている場合、ディスク上の同じファイルを参照するソースユニット名に、異なるコンテンツを関連付けることができます。
ソースが仮想ファイルシステムで利用できない場合、コンパイラはソースユニット名をインポートコールバックに渡します。
ホストファイルシステムローダーはこの名前をパスとして使用し、ディスク上のファイルを検索しようとします。
このとき、プラットフォーム固有の正規化ルールが働き、VFSでは異なるとされていた名前が、実際には同じファイルが読み込まれることがあります。
例えば、 /project/lib/math.sol
と /project/lib/../lib///math.sol
は、ディスク上の同じファイルを参照しているにもかかわらず、VFSでは全く異なるものとみなされます。
注釈
インポートコールバックがディスク上の同じファイルから2つの異なるソースユニット名のソースコードを読み込むことになっても、コンパイラーはそれらを別々のソースユニットと見なします。 重要なのはソースユニット名であって、コードの物理的な場所ではありません。
相対インポート
./
または ../
で始まるインポートは、相対インポート です。
このようなインポートは、インポート元のソースユニット名からの相対パスを指定します。
import "./util.sol" as util; // source unit name: /project/lib/util.sol
import "../token.sol" as token; // source unit name: /project/token.sol
import "./util.sol" as util; // source unit name: lib/util.sol
import "../token.sol" as token; // source unit name: token.sol
注釈
相対インポートは 常に に ./
または ../
で始まるので、 import "util.sol"
は import "./util.sol"
とは異なり、ダイレクトインポートとなります。
どちらのパスもホストファイルシステムでは相対パスとみなされますが、VFSでは util.sol
が絶対パスとなります。
ここでは、セパレータを含まず、2つのパスセパレータで囲まれた空でない部分を パスセグメント と定義します。
セパレータとは、フォワードスラッシュや文字列の先頭/末尾のことです。
例えば、 ./abc/..//
では3つのパスセグメントがあります: .
、 abc
、 ..
。
コンパイラは、インポートパスに基づき、次のようにインポートをソースユニット名に解決します:
インポートするソースユニット名から始めます。
解決された名前から、スラッシュが先行する最後のパスセグメントが削除されます。
次に、インポートパスの各セグメントについて、左端から順に説明します:
セグメントが
.
の場合、それはスキップされます。セグメントが
...
の場合、スラッシュが先行する最後のパスセグメントが解決された名前から削除されます。それ以外の場合は、そのセグメント(解決された名前が空でない場合は、スラッシュが1つ先行する)が解決された名前に追加されます。
スラッシュが先行する最後のパスセグメントの削除は、以下のように動作すると理解されています。
最後のスラッシュから先はすべて削除されます(例:
a/b//c.sol
がa/b//
になります)。後続のスラッシュはすべて削除されます(例:
a/b//
がa/b
になります)。
つまり、 .
と ..
はすべて削除され、複数のスラッシュは1つにつぶされます。
一方、インポートモジュールのソースユニット名から来る部分は非正規化されたままです。
これにより、インポートファイルがURLで識別される場合、 protocol://
の部分が protocol:/
にならないようにできます。
インポートパスがすでに正規化されている場合は、上記のアルゴリズムで非常に直感的な結果を得ることができます。 以下は、正規化されていない場合の例です。
import "./util/./util.sol"; // source unit name: lib/src/../util/util.sol
import "./util//util.sol"; // source unit name: lib/src/../util/util.sol
import "../util/../array/util.sol"; // source unit name: lib/src/array/util.sol
import "../.././../util.sol"; // source unit name: util.sol
import "../../.././../util.sol"; // source unit name: util.sol
注釈
先行する ..
セグメントを含む相対インポートの使用はお勧めできません。
同じ効果を得るには、 ベースパスとインクルードパス を含むダイレクトインポートを使用する方がより確実です。
ベースパスとインクルードパス
ベースパスとインクルードパスは、ホストファイルシステムローダがファイルをロードするディレクトリを表します。 ローダーにソースユニット名が渡されると、その前にベースパスが付けられ、ファイルシステムのルックアップが行われます。 ルックアップが成功しない場合は、インクルードパスリスト上のすべてのディレクトリに対して同様の処理を行います。
ベースパスをプロジェクトのルートディレクトリに設定し、インクルードパスを使って、プロジェクトが依存するライブラリを含む追加の場所を指定することをお勧めします。
これにより、プロジェクトのファイルシステム上の位置にかかわらず、これらのライブラリから統一的にインポートできます。
例えば、npmを使用してパッケージをインストールし、コントラクトが @openzeppelin/contracts/utils/Strings.sol
をインポートする場合、これらのオプションを使用して、npmパッケージディレクトリのいずれかにライブラリが存在することをコンパイラに伝えることができます。
solc contract.sol \
--base-path . \
--include-path node_modules/ \
--include-path /usr/local/lib/node_modules/
ライブラリをローカルパッケージディレクトリやグローバルパッケージディレクトリにインストールしても、あるいはプロジェクトルートの直下にインストールしても、コントラクトは(同じメタデータで)コンパイルされます。
デフォルトでは、ベースパスは空で、ソースユニット名は変更されません。 ソースユニット名が相対パスの場合、コンパイラを起動したディレクトリでファイルが検索されます。 また、ソースユニット名の絶対パスが実際にディスク上の絶対パスとして解釈される唯一の値です。 ベースパスが相対パスの場合は、コンパイラの現在の作業ディレクトリからの相対パスとして解釈されます。
注釈
インクルードパスは空の値を持つことはできず、空ではないベースパスと一緒に使用する必要があります。
注釈
インクルードパスとベースパスは、インポートの解決を曖昧にしない限り、重なっても構いません。 例えば、ベースパス内のディレクトリをインクルードディレクトリとして指定したり、別のインクルードディレクトリのサブディレクトリであるインクルードディレクトリを持つことができます。 ホストファイルシステムローダーに渡されたソースユニット名が、複数のインクルードパスまたはインクルードパスとベースパスの組み合わせで既存のパスを表している場合にのみ、コンパイラはエラーを発行します。
CLI Path NormalizationとStripping
コマンドラインでは、コンパイラは他のプログラムと同じように動作します。 プラットフォームに固有の形式でパスを受け取り、相対パスは現在の作業ディレクトリからの相対パスです。 しかし、コマンドラインでパスが指定されたファイルに割り当てられたソースユニット名は、プロジェクトが別のプラットフォームでコンパイルされていたり、コンパイラが別のディレクトリから起動されていたりしても、変更されるべきではありません。 そのためには、コマンドラインで指定されたソースファイルのパスを正規の形式に変換し、可能であればベースパスまたはインクルードパスからの相対パスにする必要があります。
正規化のルールは以下の通りです。
パスが相対パスの場合は、カレントワーキングディレクトリを先頭に置くことで絶対パスになります。
内部の
.
と..
のセグメントは折りたたまれます。
プラットフォーム固有のパスセパレータは、フォワードスラッシュに置き換えられます。
複数の連続したパスセパレータのシーケンスは、1つのセパレータに潰されます( UNCパス の先頭のスラッシュでない限り)。
パスにルート名(Windowsのドライブレターなど)が含まれていて、そのルートが現在の作業ディレクトリのルートと同じ場合は、ルートを
/
に置き換えます。
パスのシンボリックリンクは解決 されません 。
唯一の例外は、相対パスを絶対パスにする際に、現在の作業ディレクトリへのパスを前置することです。 一部のプラットフォームでは、作業ディレクトリは常にシンボリックリンクが解決された状態で報告されるため、一貫性を保つためにコンパイラはすべての場所でシンボリックリンクを解決します。
ファイルシステムでは大文字と小文字を区別しない(case-insensitive)が、 case-preserving とディスク上の実際の大文字と小文字が異なる場合でも、パスの元の大文字と小文字は保存されます。
注釈
プラットフォームに依存しないパスを作ることができない場合があります。
例えば、Windowsでは、コンパイラが現在のドライブのルートディレクトリを /
として参照することで、ドライブレターの使用を避けることができますが、他のドライブにつながるパスにはドライブレターが必要です。
このような状況を回避するには、すべてのファイルが同じドライブ上の単一のディレクトリツリーで利用できるようにする必要があります。
正規化後、コンパイラはソースファイルのパスを相対化しようとします。
まずベースパスを試し、次にインクルードパスを指定された順に試します。
ベースパスが空であったり、指定されていない場合は、カレントワーキングディレクトリへのパス(すべてのシンボリックリンクが解決されている)と同じであるかのように扱われます。
この結果は、正規化されたディレクトリパスが正規化されたファイルパスの正確なプレフィックスである場合にのみ受け入れられます。
そうでなければ、ファイルパスは絶対的なままです。
これにより、変換が曖昧にならず、相対パスが ../
で始まらないことが保証されます。
変換後のファイルパスがソースユニット名となります。
注釈
ストリッピングによって生成される相対パスは、ベースパスおよびインクルードパス内で一意でなければなりません。
例えば、次のコマンドで /project/contract.sol
と /lib/contract.sol
の両方が存在する場合、コンパイラはエラーを発行します。
solc /project/contract.sol --base-path /project --include-path /lib
注釈
バージョン 0.8.8 より前の CLI では、パスストリッピングは行われず、適用される正規化はパスセパレータの変換のみでした。 古いバージョンのコンパイラーを使用する場合は、ベースパスからコンパイラーを起動し、コマンドラインでは相対パスのみを使用することをお勧めします。
許可されるパス
セキュリティ対策として、Host Filesystem Loaderは、デフォルトで安全とされるいくつかの場所以外からのファイルのロードを拒否します。
Standard JSONモード以外の場合。
コマンドラインで指定された入力ファイルを含むディレクトリ。
リマッピング ターゲットとして使用されるディレクトリ。 ターゲットがディレクトリでない場合(
/
、/.
、/..
で終わらない場合)は、ターゲットを含むディレクトリが代わりに使用されます。ベースパスとインクルードパス。
Standard JSONモードの場合。
ベースパスとインクルードパス。
--allow-paths
オプションを使って、追加のディレクトリをホワイトリストに登録できます。
このオプションでは、コンマで区切ってパスのリストを指定できます。
cd /home/user/project/
solc token/contract.sol \
lib/util.sol=libs/util.sol \
--base-path=token/ \
--include-path=/lib/ \
--allow-paths=../utils/,/tmp/libraries
上記のコマンドでコンパイラを起動した場合、Host Filesystem Loaderは以下のディレクトリからのファイルのインポートを許可します。
/home/user/project/token/
(token/
には入力ファイルがあり、またベースパスでもあるため)。/lib/
(/lib/
はインクルードパスの一つであるため)。/home/user/project/libs/
(libs/
はリマップ対象を含むディレクトリのため)。/home/user/utils/
(../utils/
が--allow-paths
にパスされたため)。/tmp/libraries/
(/tmp/libraries
が--allow-paths
にパスされたため)。
注釈
コンパイラの作業ディレクトリは、デフォルトで許可されているパスのうち、たまたまベースパスであった場合(またはベースパスが指定されていないか空の値であった場合)にのみ許可されます。
注釈
コンパイラは、許可されたパスが実際に存在するかどうか、またそれらがディレクトリであるかどうかはチェックしません。 存在しないパスや空のパスは単に無視されます。 許可されたパスがディレクトリではなくファイルに一致した場合、そのファイルもホワイトリストとみなされます。
注釈
許可されたパスは、ファイルシステムがそうでない場合でも、大文字と小文字を区別します。
大文字と小文字は、インポートで使われているものと正確に一致しなければなりません。
例えば、 --allow-paths tokens
は import "Tokens/IERC20.sol"
とは一致しません。
警告
許可されているディレクトリからシンボリックリンクでのみアクセスできるファイルやディレクトリは、自動的にホワイトリストに登録されません。
例えば、上の例の token/contract.sol
が実際には /etc/passwd
を指すシンボリックリンクであった場合、 /etc/
が許可されたパスの一つでない限り、コンパイラはそれを読み込むことを拒否します。
インポートリマッピング
インポートリマッピングでは、インポートを仮想ファイルシステムの異なる場所にリダイレクトできます。
このメカニズムは、インポートパスとソースユニット名の間の変換を変更することで機能します。
例えば、仮想ディレクトリ github.com/ethereum/dapp-bin/library/
からのインポートを、代わりに dapp-bin/library/
からのインポートと見なすようなリマッピングを設定できます。
コンテキスト を指定することで、リマッピングの範囲を制限できます。 これにより、特定のライブラリまたは特定のファイルにあるインポートのみに適用されるリマッピングを作成できます。 コンテキストを指定しない場合、リマッピングは仮想ファイルシステム内のすべてのファイルにある、一致するすべてのインポートに適用されます。
インポートのリマッピングは context:prefix=target
の形をしています。
context
は、インポートを含むファイルのソースユニット名の先頭と一致する必要があります。
prefix
は、インポート後のソースユニット名の先頭と一致する必要があります。
target
は、プレフィックスが置き換えられる値です。
例えば、ローカルで https://github.com/ethereum/dapp-bin/ を /project/dapp-bin
にクローンして、コンパイラを実行した場合:
solc github.com/ethereum/dapp-bin/=dapp-bin/ --base-path /project source.sol
をソースファイルに記述できます。
import "github.com/ethereum/dapp-bin/library/math.sol"; // source unit name: dapp-bin/library/math.sol
コンパイラは、 dapp-bin/library/math.sol
の下のVFSでファイルを探します。
そこにファイルがない場合は、ソースユニット名がHost Filesystem Loaderに渡され、Host Filesystem Loaderは /project/dapp-bin/library/iterable_mapping.sol
を探します。
警告
リマッピングに関する情報はコントラクトメタデータに格納されています。 コンパイラが生成するバイナリにはメタデータのハッシュが埋め込まれているため、リマッピングを変更すると異なるバイトコードになります。
このため、リマッピングのターゲットにローカル情報が含まれないように注意する必要があります。
例えば、あなたのライブラリが /home/user/packages/mymath/math.sol
にある場合、 @math/=/home/user/packages/mymath/
のようなリマッピングを行うと、あなたのホームディレクトリがメタデータに含まれることになります。
このようなリマッピングを行った同じバイトコードを別のマシンで再現するためには、ローカルのディレクトリ構造の一部をVFSに、(Host Filesystem Loaderに依存している場合は)ホストファイルシステムにも再現する必要があります。
ローカルのディレクトリ構造がメタデータに埋め込まれるのを避けるために、ライブラリを含むディレクトリを インクルードパス として指定することが推奨されます。
例えば、上記の例では、 --include-path /home/user/packages/
を指定すると、 mymath/
で始まるインポートを使用できます。
リマッピングとは異なり、このオプションだけでは mymath
を @math
に見せることはできませんが、シンボリックリンクを作成したり、パッケージのサブディレクトリの名前を変更することで実現できます。
もっと複雑な例として、 /project/dapp-bin_old
にチェックアウトした古いバージョンのdapp-binを使っているモジュールに依存しているとします。
solc module1:github.com/ethereum/dapp-bin/=dapp-bin/ \
module2:github.com/ethereum/dapp-bin/=dapp-bin_old/ \
--base-path /project \
source.sol
つまり、 module2
のインポートはすべて旧バージョンを指しますが、 module1
のインポートは新バージョンを指します。
ここでは、リマッピングの動作に関する詳細なルールをご紹介します。
リマッピングは、インポートパスとソースユニット名の間の変換にのみ影響します。
その他の方法でVFSに追加されたソースユニット名は、リマッピングできません。 例えば、コマンドラインで指定したパスや、Standard JSONの
sources.urls
にあるパスは影響を受けません。solc /project/=/contracts/ /project/contract.sol # source unit name: /project/contract.sol
上記の例では、コンパイラは
/project/contract.sol
からソースコードを読み込み、VFSの/contract/contract.sol
の下ではなく、その正確なソースユニット名の下に置くことになります。コンテキストとプレフィックスは、インポートパスではなく、ソースユニット名と一致する必要があります。
つまり、
./
や../
はソースユニット名への変換時に置き換えられてしまうため、直接リマップできませんが、置き換えられた部分をリマップすることは可能です。solc ./=a/ /project/=b/ /project/contract.sol # source unit name: /project/contract.sol
import "./util.sol" as util; // source unit name: b/util.sol
ベースパスや、インポートコールバックによって内部的に追加されるだけのパスの部分をリマッピングすることはできません:
solc /project/=/contracts/ /project/contract.sol --base-path /project # source unit name: contract.sol
import "util.sol" as util; // source unit name: util.sol
Targetはソースユニット名に直接挿入され、必ずしも有効なパスである必要はありません。
インポートコールバックがそれを処理できる限り、何でもよいのです。 ホストファイルシステムローダーの場合は、相対パスも含まれます。 JavaScriptインターフェースを使用する場合、コールバックが処理できるならば、URLや抽象的な識別子を使用することもできます。
リマッピングは、相対的なインポートがすでにソースユニット名に解決された後に行われます。 つまり、
./
や../
で始まるターゲットは特別な意味を持たず、ソースファイルの位置ではなくベースパスに対する相対的なものです。リマップ対象は正規化されていないので、
@root/=./a/b//
は@root/contract.sol
を./a/b//contract.sol
にリマップし、a/b/contract.sol
にはなりません。ターゲットがスラッシュで終わっていない場合、コンパイラは自動的にスラッシュを追加しません。
solc /project/=/contracts /project/contract.sol # source unit name: /project/contract.sol
import "/project/util.sol" as util; // source unit name: /contractsutil.sol
コンテキストとプレフィックスはパターンであり、マッチは正確でなければなりません。
a//b=c
はa/b
に合わせません。ソースユニット名は正規化されていないので、
a/b=c
はa//b
にもマッチしません。ファイル名やディレクトリ名の一部もマッチします。
/newProject/con:/new=old
は/newProject/contract.sol
と一致し、oldProject/contract.sol
にリマップされます。
1つのインポートに適用されるリマッピングは、最大で1つです。
複数のリマッピングが同じソースユニット名と一致する場合、最も長く一致する接頭辞を持つものが選択されます。
プレフィックスが同一の場合は、最後に指定されたものが優先されます。
リマッピングは、他のリマッピングには作用しません。 例えば、
a=b b=c c=d
はa
をd
にリマッピングすることはありません。
プレフィックスは空欄にできないが、コンテキストとターゲットは任意です。
target
が空の文字列の場合、prefix
は単にインポートパスから削除されます。空の
context
は、リマッピングがすべてのソースユニットのすべてのインポートに適用されることを意味します。
インポートでのURLの使用
https://
や data://
のようなほとんどのURLプレフィックスは、インポートパスでは特別な意味を持ちません。
唯一の例外は file://
で、これはHost Filesystem Loaderによってソースユニット名から取り除かれます。
ローカルにコンパイルする場合、インポートリマッピングを使用して、プロトコルとドメインの部分をローカルパスに置き換えることができます。
solc :https://github.com/ethereum/dapp-bin=/usr/local/dapp-bin contract.sol
先頭の :
に注目してください。
これは、リマッピングコンテキストが空の場合に必要です。
そうしないと、 https:
の部分がコンパイラーによって文脈として解釈されてしまいます。