ZeppelinOS におけるコントラクトのバージョンアップの仕組みについて
こんにちは。次世代システム研究室のT.M. です。
はじめに
ERC20 トークンのライブラリで有名なOpenZeppelin がバージョンアップ可能なスマートコントラクトの開発プラットフォームZeppelinOS を発表しました。私が開発に関わったZ.com Cloud ブロックチェーンでも同様にコントラクトのバージョンアップの仕組みを提供しています。そこで、両者のバージョンアップの仕組みを解説します。Z.com Cloud ブロックチェーンにおけるバージョンアップの仕組み
ContractNameService (CNS) というコントラクトにより、コントラクトの名前とそのアドレスのマップを管理します。トランザクションを作成する際は、このCNS により、名前からアドレスを解決して、取得したアドレスを利用してトランザクションを作成します。さらに、ロジックのコントラクトとデータを保存するコントラクトを分けることで、ロジックを新しくしても、データのコントラクトがデータを管理しているため、以前のロジックが保存したデータを新しいロジックから読み出すことができます。
ZeppelinOS におけるバージョンアップの仕組み
Proxy というコントラクトが、トランザクションにおいて関数の呼び出しを受け、そのトランザクションをそのまま本体のコントラクトへ転送します。この仕組みを実現するための技術的なポイントは2つあります。一つは、fallback により実装されていない関数呼び出しを受けるということです。もう一つは、delegatecall による別コントラクトへのトランザクションの実行です。
fallback
Solidity にはfallback という呼び出し関数がなかった場合に、呼び出される関数があります。トランザクションは本体のコントラクトの関数を呼び出すものですが、Proxy コントラクトにはその関数が実装されていません。そのため、本体のコントラクトの関数の呼び出しは、すべてのfallback が受けることができます。delegatecall
Solidity にはdelegatecall という他のコントラクトの関数を呼び出す関数があります。ほかのコントラクトの関数を呼び出す方法として、MyContact.func() というものがありますが、delegatecall とは、呼び出された関数におけるthis が呼び出したコントラクトである点が異なります。つまり、delegatecall により、MyContract で定義した変数x をMyContract の関数内でx = 1 とした際、このx の値が保存されるのは、delegatecall を呼び出したコントラクトとなります。これにより、コントラクトがバージョンアップされた際でも、データはそのまま読み出すことができます。おわりに
Z.com Cloud ブロックチェーンとZeppelinOS のバージョンアップの仕組みを説明しました。コントラクトがバージョンアップされて良いのか、という問題があり、このような方法がスタンダードになるかはわかりません。ただ、ZeppelinOS は今後も注目していく必要がある技術であるように感じました。次世代システム研究室では、グループ全体のインテグレーションを支援してくれるアーキテクトを募集しています。インフラ設計、構築経験者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ募集職種一覧からご応募をお願いします。
皆さんのご応募をお待ちしています。