Let's Move は、より多くの人々が Move 言語を学ぶことを奨励する SUI のインセンティブプログラムです。
学習ログ (alva-lin)
タスク 2 - 2 つの Coin コントラクトのメインネットへのデプロイを完了する#
任务
Coin に関連する知識の学習を完了する
My Coin
の学習を完了し、メインネットにデプロイする
Faucet Coin
の学習を完了し、メインネットにデプロイする
My Coin
とFaucet Coin
コントラクトの公開package id
を提出する
My Coin
をアドレス0x7b8e0864967427679b4e129f79dc332a885c6087ec9e187b53451a9006ee15f2
に送信する
主に Managed Coin ケース - Sui Move 入門 を参照
sui::coin ライブラリ#
Coin#
Coin コントラクトの作成には、主に sui::coin
ライブラリで提供される構造体とメソッドが使用されます。
struct Coin<phantom T> has key, store {
id: UID,
balance: Balance<T>
}
struct Balance<phantom T> has store {
value: u64
}
Coin は key と store の能力を持ち、資産と見なされ、異なるアドレス間で移動可能であり、後でブロックエクスプローラーで自分が所有するすべての Coin を確認できます。
create_currency#
public fun create_currency<T: drop>(
witness: T,
decimals: u8,
symbol: vector<u8>,
name: vector<u8>,
description: vector<u8>,
icon_url: Option<Url>,
ctx: &mut TxContext
): (TreasuryCap<T>, CoinMetadata<T>) {
// Make sure there's only one instance of the type T
assert!(sui::types::is_one_time_witness(&witness), EBadWitness);
// Emit Currency metadata as an event.
event::emit(CurrencyCreated<T> {
decimals
});
(
TreasuryCap {
id: object::new(ctx),
total_supply: balance::create_supply(witness)
},
CoinMetadata {
id: object::new(ctx),
decimals,
name: string::utf8(name),
symbol: ascii::string(symbol),
description: string::utf8(description),
icon_url
}
)
}
create_currency
メソッドのパラメータ
パラメータ | 説明 |
---|---|
decimals | 精度、分割された最小単位。 10^(-1*n) |
symbol | シンボル |
name | 名称 |
description | 説明 |
icon_url | 画像 |
メソッドの戻り値は、TreasuryCap
と CoinMetadata
の 2 つの値を含むタプルです。
ここで TreasuryCap
は資産の一種で、一回限りの証人パターン によって単一のオブジェクトであることが保証され、その型宣言は以下の通りです。
/// Capability allowing the bearer to mint and burn
/// coins of type `T`. Transferable
struct TreasuryCap<phantom T> has key, store {
id: UID,
total_supply: Supply<T>
}
/// A Supply of T. Used for minting and burning.
/// Wrapped into a `TreasuryCap` in the `Coin` module.
struct Supply<phantom T> has store {
value: u64
}
この total_supply
値は、現在の通貨 T
の発行総量を追跡するため、TreasuryCap は 1 つだけで十分です。そして CoinMetadata
は、現在の通貨のメタデータを保持します。
coin コントラクトコード#
sui フレームワークライブラリの充実のおかげで、mint
(鋳造) と burn
(消去) 機能を持つトークンコントラクトを作成するために必要なコードは非常に少ないです。
// file: my_coin.move
module new_coin::my_coin {
use std::option;
use sui::coin::{Self, Coin, TreasuryCap};
use sui::transfer;
use sui::tx_context::{Self, TxContext};
struct MY_COIN has drop {}
fun init(witness: MY_COIN, ctx: &mut TxContext) {
let (treasury_cap, metadata) = coin::create_currency<MY_COIN>(
witness,
2,
b"MY_COIN",
b"MC",
b"learning for letsmove, power by alva-lin",
option::none(),
ctx
);
transfer::public_freeze_object(metadata);
transfer::public_transfer(treasury_cap, tx_context::sender(ctx));
}
public fun mint(
treasury_cap: &mut TreasuryCap<MY_COIN>,
amount: u64,
recipient: address,
ctx: &mut TxContext
) {
coin::mint_and_transfer(treasury_cap, amount, recipient, ctx);
}
public fun burn(treasury_cap: &mut TreasuryCap<MY_COIN>, coin: Coin<MY_COIN>) {
coin::burn(treasury_cap, coin);
}
#[test_only]
public fun test_init(ctx: &mut TxContext) {
init(MY_COIN {}, ctx);
}
}
my_coin
モジュールは、Witness モード
に基づいて MY_COIN
という名前の構造体を定義します。その後、init
メソッドのパラメータに MY_COIN
型の witness リソースを追加し、モジュールがプッシュされた後に自動的に作成されます。
init
メソッド内で、coin::create_currency
メソッドを呼び出し、TreasuryCap
と CoinMetadata
リソースを取得し、即座に CoinMetadata
を凍結します。
TreasuryCap
は mint
メソッドと burn
メソッドを呼び出すための証明書として、発行者のアドレスに送信されます。
テスト#
テストコードは以下の通りで、複数の取引時間をシミュレートし、mint
操作と burn
操作を行います。
#[test_only]
module new_coin::my_coin_tests {
use new_coin::my_coin::{Self, MY_COIN};
use sui::coin::{Coin, TreasuryCap};
use sui::test_scenario::{Self, next_tx, ctx};
#[test]
fun mint_burn() {
// Initialize a mock sender address
let addr1 = @0xA;
// Begins a multi transaction scenario with addr1 as the sender
let scenario = test_scenario::begin(addr1);
// Run the coin module init function
{
my_coin::test_init(ctx(&mut scenario))
};
// Mint a `Coin<MY_COIN>` object
next_tx(&mut scenario, addr1);
{
let treasurycap = test_scenario::take_from_sender<TreasuryCap<MY_COIN>>(&scenario);
my_coin::mint(&mut treasurycap, 100, addr1, test_scenario::ctx(&mut scenario));
test_scenario::return_to_address<TreasuryCap<MY_COIN>>(addr1, treasurycap);
};
// Burn a `Coin<MY_COIN>` object
next_tx(&mut scenario, addr1);
{
let coin = test_scenario::take_from_sender<Coin<MY_COIN>>(&scenario);
let treasurycap = test_scenario::take_from_sender<TreasuryCap<MY_COIN>>(&scenario);
my_coin::burn(&mut treasurycap, coin);
test_scenario::return_to_address<TreasuryCap<MY_COIN>>(addr1, treasurycap);
};
// Cleans up the scenario object
test_scenario::end(scenario);
}
}
公開#
まず、ネットワークを必要な環境に切り替えます。
sui client switch --env mainnet
プロジェクトフォルダ内で、以下のコマンドを実行して、パッケージを公開するか、モジュールを個別に公開します。
# publish package
sui client publish --gas-budget 30000
# または必要に応じてモジュールを公開
# publish module
# sui client publish sources/my_coin.move --gas-budget 30000
公開後の出力結果には、以下が含まれます。
-
Package:
Object Changes > Published Objects
ブロックに位置します。 -
CoinMetadata:
Object Changes > Created Objects
ブロックに位置します。その ObjectType は
0x2::coin::CoinMetadata<<Package ID>::<Module>::<Witness Type>>
です。 -
TreasuryCap:
Object Changes > Created Objects
に位置します。その ObjectType は
0x2::coin::TreasuryCap<<Package ID>::<Module>::<Witness Type>>
です。
Package ID
と TreasuryCap ID
を記録します。
export PACKAGE_ID=0xf9623587d620d26024868578a3539642993e2da44598c3fcaa1f384f5327f6a5
export TREASURYCAP_ID=0x97233be4acd1688c93f2c60ce81350b993a810c6b4851e8cdf214402759fad88
鋳造と消去#
sui cli を使用して、モジュールの対応するモジュール関数を呼び出すことができます。
注意が必要なのは、希望するトークンの数量 = 渡す値 * 10^(-1*n)
であり、ここで n は前述の公開されたコントラクトコードの decimals
の値です。
この記事では、decimals の値は 2 です。100 枚のトークンを鋳造したい場合は、値を 10000 にする必要があります。
# 送信先のウォレットアドレス
export RECIPIENT_ADDRESS=<YOUR_WALLET_ADDRESS>
# mint
sui client call --gas-budget 3000 --package $PACKAGE_ID --module my_coin --function mint --args $TREASURYCAP_ID \"10000\" $RECIPIENT_ADDRESS
出力内容には、取引の詳細が表示されます。
または、取引ハッシュを取得して、SuiScan や他の sui ブロックエクスプローラーで取引の詳細を確認できます。
# 取引ハッシュの形式は以下のようになります。通常、出力内容の最初に表示されます。
Transaction Digest: <hash>
鋳造時の出力内容の中で、Object Changes > Created Objects
ブロック内の ObjectType が 0x2::coin::Coin<<package>, <module>, <type>>
のオブジェクトを見つけて、ObjectID を取得します。
この ObjectID が CoinID
であり、変数として保存します。
コマンドライン出力の coin id が見つからない場合は、ブロックエクスプローラーから見つけることもできます。
export COIN_ID=0x3460204ae7f9385df79dc963a17d8b11eb0fa7a699f7196fac80405e1777d36c
burn メソッドを呼び出して、通貨を消去します。
# 注意: gas 予算を増やす必要があります
# burn
sui client call --gas-budget 7500000 --package $PACKAGE_ID --module joker --function burn --args $TREASURYCAP_ID $COIN_ID
コマンドが成功すると、ウォレットから以前に鋳造した金額が削除されたことが確認できます。
トークンが消去された後、COIN ID を使用して直接ブロックエクスプローラーで検索することはできず、履歴取引から間接的にその記録を見つけることしかできません。