SolidityのコンパイラはC++で書かれている。JSでは、Emscriptenを用いてsoljson.jsという名前のJavascript(asm.js)に変換した上で使っている。そのwrapperこそが、おなじみのsolcだ。ちなみに、今までのsoljson.jsはhttps://github.com/ethereum/solc-binにある。
ではブラウザで使う場合はどうしよう?残念ながらsolcjsはコンパイル済みのjsファイルを持っていないため、Webpackを使うことになるのだが、ここで一つ問題が発生する。soljson.jsをWebpackに突っ込むと、コンパイルが終わらない。Parcelなど使おうものならヒープ領域がパンクする。V8でOutOfMemoryなんて初めて見たぞ。これはこのファイルが7MB超と大きいのが理由だと思われる。しかしWebpackもそこらへん察してほしいな。というか、そもそもNode.js用にnode-gypではなくEmscriptenを使っているのもどうかと思う。あとwasmないの(>_<)
ということで愚直にimport solc from 'solc'
していてはコンパイルが終わらないので、soljson.jsをブラウザからscriptタグでそのまま読み込みつつ、ラッピングして自分でsolcオブジェクトを作るという謎の芸当をしなくてはいけない。ということで以下のコード。
solc.js
import solc from 'solc/wrapper'
export default solc(require('module'))
webpack.config.js
module.exports = {
.
.
.
externals: {
'module': 'Module'
},
.
.
.
}
まず一行目で、solcの「ラッパー部分」を読み込んでいる。そして二行目で、読み込んだラッパーにscriptタグからsoljson.jsから生成されたModule変数を渡している。他のライブラリでrequire(‘module’)としている箇所があるので、require(‘module’)から一括してwindow.Moduleを取得するようにしている。で、これと似たようなことがremixのソースコードにも書かれている。うーん黒魔術。