見出し画像

Solidity勉強日誌⑤ブロックチェーン上の他人のコントラクトとやりとりするには?

Ethereumの特異なこととして、公開されているコントラクトを読み込んで、自分のブロックチェーンで使うことが出来ます。この特性がEthereumの未来に期待してしまうところです。公開したコントラクトがEthereumで公開される様々なプロジェクトと繋がっていく。今でも企業間のAPI連携はありますが、それが現在よりも速さと安全性をもって、繋がっていくことになります。様々な産業で使われるDappsのコントラクトが繋がっていくと、どんな世界になるかワクワクしませんか?

では、ブロックチェーン上の他人のコントラクトとやりとりするには、どうすれば良いか。最初にinterfaceを定義する必要があります。

例えば、こんなコントラクトがブロックチェーン上にあったとします。
1つ目の関数(setNum)は、numbersという変数があり、この関数を呼び出したユーザーのアドレスに_numという変数を入れる形になっています。
2つ目の関数(getNum)は、自分のアドレスを入れることで、入れた値を参照する関数になっています。

contract LuckyNumber {
   mapping(address => uint) numbers;
   function setNum(uint _num) public {
   numbers[msg.sender] = _num;
 }
  function getNum(address _myAddress) public view returns (uint) {
   return numbers[_myAddress];
 }
}

そして、外部にコントラクトを持っていたとして、numbers変数の値を知りたくなったとしましょう。上記のgetNum関数を実施してコントラクトのデータを読みにいきます。その、まずはLuckyNumberコントラクトのinterfaceを定義するのです。下記になります。

contract NumberInterface {
 function getNum(address _myAddress) public view returns (uint);
}

これはやりとりしたい関数(getNum関数)のみを宣言していて、他の関数には触れていません。また、関数の処理は一切書かれていません。コンパイラはこれを見てinterfaceだと理解するのです。

でも、ちょっと待って、プログラム初心者の方はそもそもInterfaceってなんやねん?となりませんか?僕もなりました。JavaやC#をやっている方からすると馴染みのある概念のようですね。

インターフェースは、コントラクトを束ねる上位規定になります。上位規定が定まっていると、開発に変更が出て新しいコントラクトを作る必要が出た場合も、「過去のコントラクトはこういう規定があるから、使い方が明示されていて、安心して、使える!」となるのです。

こうして、自分のコントラクトの中で、getNum関数を呼び出すことができます。それには、上記のLuckyNumberコントラクトをデプロイした時に出来るコントラクトアドレスを格納します。(以前のブログでEthereumにはスマートコントラクトにもアドレスが存在するということについて書いてますので、こちらもご参考ください。)
そして、上記で作成したinterfaceにコントラクトアドレスを食わせてあげることで、メソッドとして関数を呼び出すことが出来るのです。

contract MyContract {
 address NumberInterfaceAddress = 0xab38...; 
 NumberInterface numberContract = NumberInterface(NumberInterfaceAddress);
 function someFunction() public {
 uint num = numberContract.getNum(msg.sender);
 }
}

参照:CryptoZombies


この記事が気に入ったらサポートをしてみませんか?