メインコンテンツまでスキップ

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

· 約4分

コントラクトなのに、更新するの?という問題は一旦おいておいて、ブロックチェーン上で更新できる方法をやってみました。 といっても、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. 添付画像のようによく分からに値が出てくる

image0.png

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

image1.png

アップデートしてみる

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

image2.png

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

まとめ

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

課題