コントラクトの継承と連携(他のコントラクトのメソッド実行)まったりお勉強ぶろっくちぇーんコントラクトの継承と連携(他のコントラクトのメソッド実行)どうも、ぺろりんです。Books)」をテキストとして使った勉強のつづきです。3の「コントラクトの継承」と「他のコントラクトのメソッドを実行」というセクションに戻って理解を深めようと思います。ここで私が理解したいのは「(1つのソースコードに)2つ以上のコントラクトが書いてあるときの動き」です。これを「コントラクトの継承」と、「他のコントラクトのメソッドを実行」という2つの切り口から調べていきます。(テキストを参照しつつ)前提知識お恥ずかしながらオブジェクト指向言語の理解が浅くて、まず単語でつまずきましたwなので、このへんからちゃんと理解しておこうかと思います。「クラス」、「インスタンス」とは?「クラス」は“鋳型”とか“設計図”にあたるもので、これをもとに作られた“実体”が「インスタンス」です。「メソッド」とは?実質的には関数だったりしますが、関数とは別の概念です。オブジェクト指向では・属性(どんなもの?)...a,b,cという性質を持つ・操作(何ができる?)...X,Yという動作ができるをひとまとめにした(a,b,c,X,Y)を1つの「オブジェクト」と考えます。オブジェクトができる「操作」のことを「メソッド」と呼びます。〈オブジェクト〉.〈オブジェクト内の変数や関数名〉と書くことで、〈オブジェクト〉内で定義された属性や操作を呼び出せます。「継承」、「オーバーライド」とは?オブジェクト指向では、親子関係をつけたクラスを定義することができます。何がうれしいかと言うと、たとえば2つのクラスAとBを定義するときに、AとBには共通の性質Pがあったとします。「性質Pを持った親クラスX」を作ってAとBをXの子クラスとすれば、子クラスは親クラスの性質を引き継ぐため、AとBの中で共通の性質Pを定義する必要がなくなります。この「子クラスは親クラスの性質を引き継ぐ」性質を「継承」と呼びます。子クラスの中で、継承した親クラスの変数などを上書きするのが「オーバーライド」です。ここまでがオブジェクト指向についての前提知識です。このへんの理解をちゃんとしておかないと分からない!(私だけか......?w)「コントラクト」、「デプロイ」とは?オブジェクト指向の言葉はすこし分かった気がしますが、今度はイーサリアムの言葉の理解も浅いことに気付きましたwまだいまいち「コントラクト」と「デプロイ」のイメージがつかめてなかったので、これらも調べてみました。ここまでオブジェクト指向の言葉を復習しておくと、以下のような理解ができるようです。Books)」へ戻ってきます。コンパイラのバージョンをソースに合わせつつ、サンプルコードをコンパイルします。このサンプルコードの概要としては以下のようなものです。・1つのソースコードの中に1コントラクトA2AのサブコントラクトB3コントラクトCという3つのコントラクトが書いてある。・コントラクトCの中で、AとBをデプロイしている(「new」コマンドを使うことでデプロイできる)。このサンプルコードで、コントラクトの継承について動きを見ていきます。初心者の私としては、はじめは素朴に「上に書いてるAから順にSolidityでデプロイしていくべきなのかな?」と考えました。考えてみると、コントラクトCの中でAとBのインスタンスを作っている(デプロイしている)ので、コントラクトCだけデプロイすれば事足りるのでは?......と思って、コントラクトCのみデプロイすることを試してみました。VMにしつつデプロイしてみます。できたのはCだけです。この状態で「c」と「getData」を押してみても初期状態という感じです。ソースコードの中で、コントラクトAとBのインスタンスを作っている(中でnewしている)関数「makeContract」を押してみます。この後ふただび「c」と「getData」を押してみると、値を拾っています。今度は、はじめに考えていた通り、A、B、Cの順にすべてデプロイしてみました。この状態で、青いボタンだけ押してみます。何も値は入っていません。ちなみにここで、BはAを継承しているため、Bの中では定義されていない「setA」と「a」のボタンがBのところにもあります。ためしに、Aのところでa=15と設定して「setA」を実行してみます。この直後にA、B、Cで青いボタンを押してみます。すると、Aの「a」と「getData」の値のみ変わりました。次に、Bのところでa=20と設定して「setA」を実行してみます。この直後にもA、B、Cで青いボタンを押してみると、今度はBの「a」と「getData」の値のみ変わりました。Aの中に定義された「a」をBの中でも定義していますが、これは別に、BがAの中で定義した「a」の値を参照する動きにはなっていないようです。この時点でCの「makeContract」をするとどうなるでしょうか?これを実行しつつ、Cの中の「c」と「getData」を押してみます。Cの中ではあくまでa=1としてAとBのインスタンスを作成して計算しているので、先ほどAやBの中で設定した「a」とは関係なくCの中で計算されていることがわかります。ちなみに、Cで「makeContract」した後も、AとBの中にある「a」と「getData」は変わっていませんでした。以下のようなことが言えるようです。・AとBのインスタンスを中で作っているCだけデプロイすれば、AとBをデプロイしなくてもCは結果を出せる。・A、B、Cをそれぞれデプロイすると、それぞれは独立に動く(設定した「a」の値は、あくまで各A、B、C内でのみ使われる)。次に、他のコントラクトのメソッドを実行するサンプルコードをコンパイルしてみます。コードの概要としては、以下のようなものです。・1つのコードに1コントラクトA2コントラクトBの2つが書いてある。・コントラクトBの中で「コントラクトA」や「Aの中で定義した変数」を呼ぶけど、Aの“インスタンス化”(newコマンド)はやらない。先ほどの「継承」ではコントラクトCの中でAとBをインスタンス化していたので、CだけデプロイすればAやBの中にあるデータを拾ってきました。今回はコントラクトBの中でAのインスタンス化はしていないので、おそらくBだけデプロイしても「Bで呼んでいる、Aの中で定義した変数」の値は拾えないでしょう......という想定のもと、まずはBだけデプロイしてみます。ためしにBだけデプロイした状態で青いボタンだけ押してみると、どれも初期状態です。(というかコントラクトAをデプロイしていないので、そもそもコントラクトAのアドレスを入れなさいという場所に何も入れられない......)次に、Aもデプロイしてみます。Aのアドレスを入れて「setA」を押してから、Bの青いボタンを押してみます。めでたく値を拾うことができました。コントラクトAをデプロイしたときのアドレスを使うことでAとBが紐づいて、BからAの中で定義された変数の値を呼び出すことができました。A(_a)というようにセットします。aNum()はa.num()を返すことで(numはコントラクトAの中で定義された状態変数)、Aで定義されたnumの値を返します。A(_a)」は「オブジェクト」になっているようです。コントラクト名の引数にそのコントラクトのデプロイアドレスを指定したら「オブジェクト」化(もしくはインスタンス化)されるようです。MetaMask連携)(Qiita)まとめオブジェクト指向言語に慣れている方だとそんなに困らないのかも知れませんが、私は慣れておらず詰まりながらいくつか試してみましたwオブジェクト指向言語の本も手元に置いておく方が良さそうだなぁ。今回触ってみて、個人的には以下のような理解が得られました。・1つのコード内に複数のコントラクトが含まれるとき、1あるコントラクトXの中で別のコントラクトYをデプロイしているならば、XをデプロイすればYのデプロイは不要。2それぞれのコントラクトを別々にデプロイすると、各々が独立して動く。・コントラクトZの引数にそのコントラクトZのデプロイアドレスWを指定したZ(W)は「オブジェクト」化(インスタンス化)される。»PagetopプロフィールAuthor:ぺろりんまだ始まってもいない暗号資産(仮想通貨)、今後が楽しみです。基本的な技術をちゃんと知りたいなぁと思いつつ、まったりお勉強していこうかと思います。Reserved.|プライバシーポリシ。