Chapter 4 リソースの使い方
リソースが作られて、それを使える様になりました。
リソースの使い方は、それを使った後には破棄することになっているということを除いて、構造体とほぼ同じです。
このチャプタでは、リソースは現在のトランザクションスクリプトでのみ使われて、当面どのアドレスにも送られないものとします。これはリソースがmain()
の後で破棄されなければならないことを意味しています。
次に、例を見てリソースをどうやって使うかを理解し、またリソースの生成と破棄について復習しましょう。
modules:
module MoneyHolder {
import 0x0.LibraCoin;
resource T { money: LibraCoin.T }
public new(m: LibraCoin.T): Self.T {
return T{ money: move(m) };
}
public destroy_t(t: Self.T) {
let money: LibraCoin.T;
T{ money } = move(t);
LibraCoin.destroy_zero(move(money));
return;
}
}
script:
import Transaction.MoneyHolder;
import 0x0.LibraCoin;
main() {
let coin: LibraCoin.T;
let money_holder: MoneyHolder.T;
coin = LibraCoin.zero();
money_holder = MoneyHolder.new(move(coin));
MoneyHolder.destroy_t(move(money_holder));
return;
}
この例では、5行目でプロシージャにより生成されて、8行目にプロシージャを通して破壊されるリソースT
を持ったMoneyHolder
というモジュールを定義しています。
リソースT
のメンバ変数もまたリソースであることに注意しなければなりません。そのため、T
を破棄するとき、10行目と11行目の二つの破棄が必要とされています。二つ目の破棄はLibraCoin
モジュールのLibraCoin.destroy_zero()
をコールしてcoin
を破壊しています。
これは最初の2つのチャプタに含まれていたポイントです。もし忘れている場合は戻って復習してください。
次にこの例のスクリプト部分を見ていきましょう。main()
プロシージャの最初の2行は、二つのリソースを定義しています。その一つはLibraCoin.T
でもう一つは、私たちが宣言したMoneyHolder.T
です。変数の宣言の後、未初期化の変数は操作できないため、それらを初期化します。
21行目のLibraCoin.zero()
関数は、LibraCoint.T
を初期化するためのものです。これはLibraのオフィシャルなLibraCoin
モジュールで定義されたもので、ここではさらに分析することはしません。
22行目のMoneyHolder.new(move(coin))
は、money_holder
変数をイニシャライズするために定義したリソース生成プロシージャです。そのため、この変数を今使うことができます。
Note:この引数は、copy(coin)
ではなくmove(coin)
です。もし後でcoin
変数を使いたいとしても、copy()
関数を使うことは許されていません。coin
はリソースであり、リソースはcopy()
関数ではなく、move()
関数によってのみ操作ができるためです。
ここでは、money_holder
の操作は実装しません。そのため次のステップは、コントラクトが抹消される前にこれを破棄することです。プロシージャ内のパラメータについてもcopy()
ではなくmove()
関数を使うことに注意してください。
一般にリソースを使うためには、最初にlet
ステートメントを通して、リソース変数を宣言しなければなりません。そしてその変数を初期化するためリソース生成のプロシージャをコールします。最後にリソースの使用が終わった時に、それを破壊するための破棄プロセスも実装します。
<img src=${require("../static/images/lesson3/pic_3_4_1_en.png")} style="width:80%;position:relative;left:10%">
実習
前のチャプタでcastle
を生成して破棄するプロシージャを完了していますが、まだmain()
プロシージャ内の、リソースの生成と破壊について細部調整が必要なため、コントラクトを上手くコンパイルすることはできません。
Note:当面、アカウントリソースはどんな実際上の効果もないので、ここではmain()
内でこれを呼びません。CastleAccount
リソースが使われる必要があるとき、それぞれnewAccount
やdesAccount
関数を呼ぶことによって、それを作ったり消したりできます。
main()
の中にCastle
リソースを破棄するステートメントを追加してください。