トップへ戻る
公開日
2017年5月12日
筆者:Curvegrid
ジェフ・ウェントワース

2日目: solc の様々なバージョン、Solidity コンパイラ

前回の記事では、Solidityコンパイラであるsolcと、抽象解釈の原理で動作するSolidityディスアセンブラであるevmdisを使用して、Ethereumスマートコントラクトのコンパイル、逆アセンブル、比較を試してみました。

古いSolidityスマートコントラクト(The DAOなど)を現在のSOLCバージョンでコンパイルしようとしたとき、いくつかの問題に遭遇しました。この記事では、Solidity コンパイラのバージョンと、異なるバージョンをどのようにビルドするかを見ていきます。

Solidity コンパイラ: solc と solcjs

C++ で書かれたsolc と、 solc C++ のソースコードから JavaScript へのクロスコンパイルにEmscripten を使用するsolc-js です。技術的には同じソースコードから作られていますが、実際には微妙に異なる結果が得られるようです。また、コマンドラインインターフェイスも異なっており、 solcjs は (予想通り) solc よりもかなり遅いです。


$ time solc --optimize --bin -o .Test1.sol
警告。これはプレリリース版のコンパイラですので、本番では使用しないでください。

実質0m0.075s
ユーザ0M007S
sys0m0.009s

$ time solcjs --optimize --bin Test1.sol

実質0m3.950s
ユーザ0M3.524S
sys0m0.337s

SolidityコンパイラのJavaScriptビルドでは、WebベースのRemix Solidity IDEのようなクールなアプリケーションを実現することができます。

Solidityスマートコントラクト言語とそのバージョン

SolidityはEthereumブロックチェーンのスマートコントラクト言語です。これは高レベルのCファミリー言語で、Ethereumバイトコードにコンパイルされ、Ethereum仮想マシン(EVM)上で動作します。EVMは、Ethereumブロックチェーンに参加しているすべてのノードで動作する分散仮想マシンであり、Ethereumクライアントに統合されています。Ethereumクライアントとしては、cpp-ethereumgo-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 をビルドするのは興味深いプロジェクトでしょう。