古いSolidityスマートコントラクト(The DAOなど)を現在のSOLCバージョンでコンパイルしようとしたとき、いくつかの問題に遭遇しました。この記事では、Solidity コンパイラのバージョンと、異なるバージョンをどのようにビルドするかを見ていきます。
Solidity コンパイラ: solc と solcjs
C++ で書かれたsolc と、 solc C++ のソースコードから JavaScript へのクロスコンパイルにEmscripten を使用するsolc-js です。技術的には同じソースコードから作られていますが、実際には微妙に異なる結果が得られるようです。また、コマンドラインインターフェイスも異なっており、 solcjs は (予想通り) solc よりもかなり遅いです。
SolidityコンパイラのJavaScriptビルドでは、WebベースのRemix Solidity IDEのようなクールなアプリケーションを実現することができます。
Solidityスマートコントラクト言語とそのバージョン
SolidityはEthereumブロックチェーンのスマートコントラクト言語です。これは高レベルのCファミリー言語で、Ethereumバイトコードにコンパイルされ、Ethereum仮想マシン(EVM)上で動作します。EVMは、Ethereumブロックチェーンに参加しているすべてのノードで動作する分散仮想マシンであり、Ethereumクライアントに統合されています。Ethereumクライアントとしては、cpp-ethereum、go-ethereum、[Parity][evm-parity](Rustで書かれています)などがあります。バイトコードやEVMの動作については、Gavin Wood氏によるいわゆるEthereumのイエローペーパーで詳しく解説されています。
Ethereum ブロックチェーンは不変なので、ブロックチェーン上に展開されたスマートコントラクト (バイトコード) は常に有効であることが期待できます。つまり、もしSolidityのバイトコードの仕様に変更が加えられた場合、EVMは常に既に配備されているバイトコードをサポートする必要があります。しかし、高レベルのSolidity言語に変更を加えた場合、古いバージョンのsolcコンパイラと後方互換性がない可能性があります。
これはまさにevmdisを使って実験したときに遭遇したことで、最新バージョンのsolc(2017年5月頃)でThe DAOのソースコード(2016年3月頃)をコンパイルできませんでした。
バージョンプラグマ
Solidity の 0.4.0 リリース以降、すべての Solidity ファイルの先頭にpragma solidity^x.y.z のようなバージョンの pragma ステートメントが必要になりました。ドキュメントに記載されているように、より複雑なルールが可能であり、これによりコンパイラは、(おそらく)未定義の、または望ましくない結果でコンパイルするのではなく、互換性のないソースファイルを潔く拒否することができるようになりました。
ソリダリティのバージョン。Ethereumの改善提案
Solidityの言語変更の包括的なリストがあるのか、それともその鏡とも言える、同じSolidityの入力に対するsolcの出力の変更があるのかは不明です。ブログやredditの投稿は別として、私たちが見つけることができた最も注目すべきソースは、Ethereum Improvement Proposals (EIPs)のリストで、Ethereumの標準変更が議論され、形式化され、Ethereumのために合意されるプロセスです。
ソルクのインストール
Solidity と solc は非常に活発な開発が行われており、時間の経過とともに大幅に変更されています。私たちは一般的に solc のビルドとインストールについて Solidity のドキュメントに従っていましたが、0.4.11 バージョン (2017 年 5 月) については、いくつかの奇妙な点を指摘しました。
- ビルドパイプラインの問題があるため、現在、Mac OS用のバイナリパッケージはダウンロードできません。Linux と Windows ユーザーはバイナリからインストールできます。
- Homebrew経由でインストールすると、Boostを再コンパイルするのに10分もかかってしまいました。中止しました。
- 結局、Github上のソースからクローンしてビルドしました。30分ほどで完了しましたが、Boostでは特に問題はありませんでした。
以前のバージョンの solc のインストール
Solidity の活発な開発プロセスの一部は、ドキュメントとソースコード、およびそれらの依存関係が移動したことを意味します。前回の投稿の一部として The DAO を再コンパイルするためには、約 1 年前の 2016 年 5 月頃のバージョンの solc を入手する必要がありました。実際、私たちは、デプロイされたバージョンの The DAO をコンパイルするために使用した solc のバージョン、[solc version v0.3.1-2016-04-12-3ad5e82][the-dao-contract] を正確に使用したいと思っていました。Github で検索した結果、この特定のリビジョン (3ad5e82) を見つけることができませんでしたので、あきらめて solc 0.3.2 (28b30ec13) を使用しました。
ビルドプロセスも変更されました。ドキュメントでは移動したり非推奨になったreposを指しているので、基本的には古いコマンドで新しいrepos(cpp-ethereum)を使い、動作するようになるまでハックしまくりました。
結論
任意のバージョンの solc をビルドして、Solidity のソースコードをコンパイルすることができる solc-meta-Builder をビルドするのは興味深いプロジェクトでしょう。