Blockchain
Ethereum
SmartContract

アップデートできるスマートコントラクトを実装してみました

コントラクトなのに、更新するの?という問題は一旦おいておいて、ブロックチェーン上で更新できる方法をやってみました。
といっても、Truffle の Migration は何をやっている? - Qiita の応用編的な感じですね。

コード

pragma solidity ^0.4.17;

contract InnerContract {
  function say() public pure returns (bytes32) {
    return "first ver";
  }
}

contract MyContract {
  address public owner;
  address public innerContractAddress;

  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }

  function MyContract() public {
    owner = msg.sender;
  }

  function say() public view returns (bytes32) {
    InnerContract innerContract = InnerContract(innerContractAddress);
    return innerContract.say();
  }

  function setInnerContract(address new_address) public onlyOwner {
    innerContractAddress = new_address;
  }
}

初期バージョンをデプロイする

  • 環境準備
    • Ganacheを起動しておく
    • https://ethereum.github.io/browser-solidity にアクセスして、EnvironmentWeb 3選択し、http://127.0.0.1:7545に接続しておく
  • 初期バージョンデプロイ
    1. 上記ソースをRemixのエディターに貼り付ける
    2. 右側のデプロイ対象コントラクトをInnerContract選択し、ピンク色のCreateボタンをクリックしデプロイする
    3. 同じくMyContractを選択し、デプロイする
    4. デプロイできたら、InnerContractのアドレスをコピーして、MyContractsetInnerContract関数のパラメータとして設定し(ダブルクオーテーションを忘れずに)、setInnerContractを呼び出す
    5. 結果確認:MyContractsay関数を実行する
    6. 添付画像のようによく分からに値が出てくる

スクリーンショット 2017-12-20 17.09.33.png

  • 左側の下の部分をクリックすればコンソール使えるので、そこでデコードしてみたら、ちゃんとfirst verになっている!!!

スクリーンショット 2017-12-20 17.14.16.png

アップデートしてみる

  • InnerContractの戻り値をsecond verに変更して、上記と同じく、InnerContractを再度デプロイする
contract InnerContract {
  function say() public pure returns (bytes32) {
    return "second ver";
  }
}

スクリーンショット 2017-12-20 17.19.37.png

  • 上記画像のように、2個目のInnerContractが出て来る
  • 初期バージョンのデプロイと同じくInnerContractのアドレスをMyContractsetInnerContract経由して設定する
  • 再度MyContractsay関数を呼び出して、同じく値をweb3.toAscii()でデコードすると、second verになっている!

まとめ

  • エンドユーザ側から見ると、MyContractがアップデートできるようになっています。
  • 入り口のコントラクトを用意して、実処理を裏側のコントラクトに任せることで、コントラクトのアップデートはできる
  • もちろん、課題はまだまだいろいろある

課題