solcをブラウザで使うときに詰まった点

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のソースコードにも書かれている。うーん黒魔術。