本教程介绍了如何编译、部署和铸造 Moon Coin 代币。
第 1 步:选择 SDK
第 2 步:获取 CLI
从 Git 安装 CLI
第 3 步:运行示例
克隆 aptos-core
:
Copy git clone < https://github.com/aptos-labs/aptos-core.gi t >
第 3.1 步:SDK 特定示例
Typescript
导航至 Typescript SDK 目录:
Copy cd ~/aptos-core/ecosystem/typescript/sdk
安装必要的依赖项
运行 your_coin
示例:
Copy yarn your_coin ~/aptos-core/aptos-move/move-examples/moon_coin
Python
导航至 Python SDK 目录:
Copy cd ~/aptos-core/ecosystem/python/sdk
安装必要的依赖项
Copy curl -sSL < https://install.python-poetry.or g > | python3
poetry update
运行 your_coin
示例:
Copy poetry run python -m examples.your-coin ~/aptos-core/aptos-move/move-examples/moon_coin
第 3.2 步:构建包
进行到一半时,demo 会暂停并显示以下输出:
Copy === Addresses ===
Alice: 0x5e603a89cf690d7134cf2f24fdb16ba90c4f5686333721c12e835fb6c76bc7ba
Bob: 0xc8421fa4a99153f955e50f1de2a6acff2f3fd0bb33aa17ba1f5b32b699f6c825
Update the package with Alice's address, compile, and press enter.
此时,打开另一个终端并将目录更改为 MoonCoin 包的目录
Copy cd ~/aptos-core/aptos-move/move-examples/moon_coin
现在使用 CLI 构建包:
Copy aptos move compile --named-addresses MoonCoin=0x5e603a89cf690d7134cf2f24fdb16ba90c4f5686333721c12e835fb6c76bc7ba --save-metadata
--named-addresses
是一个必须转译的地址映射表,让编译后的软件包能够存储到 Alice 的帐户中。注意 MoonCoin
是如何被设置为上面显示的 Alice 地址的。另外,为了发布软件包,还需要 --save-metadata
。
第 3.3 步:完成示例
返回前面的提示,按回车键,现在软件包已经准备好发布了。
应用程序将完成,显示:
Copy Publishing MoonCoin package.
Bob registers the newly created coin so he can receive it from Alice.
Bob's initial MoonCoin balance: 0.
Alice mints Bob some of the new coin.
Bob's updated MoonCoin balance: 100.
第 4 步:深入了解 MoonCoin
第 4.1 步:构建和发布 MoonCoin 包
Move 软件或合约实际上是一组被称为包的模块。在部署或升级一个新的软件包时,必须用 --save-metadata
来调用编译器,以便发布该软件包。在 MoonCoin 的案例中,以下输出文件是至关重要的:
build/Examples/package-metadata.bcs
——与软件包相关的元数据
build/Examples/bytecode_modules/moon_coin.mv
—— moon_coin.move
模块的字节码
这些都由示例读取并发布到区块链上:
Typescript
Copy const modulePath = process .argv[ 2 ];
const packageMetadata = fs .readFileSync ( path .join (modulePath , "build" , "Examples" , "package-metadata.bcs" ));
const moduleData = fs .readFileSync ( path .join (modulePath , "build" , "Examples" , "bytecode_modules" , "moon_coin.mv" ));
console .log ( "Publishing MoonCoin package." );
let txnHash = await client .publishPackage (alice , new HexString ( packageMetadata .toString ( "hex" )) .toUint8Array () , [
new TxnBuilderTypes .Module ( new HexString ( moduleData .toString ( "hex" )) .toUint8Array ()) ,
]);
await client .waitForTransaction (txnHash , { checkSuccess : true });
Python
Copy moon_coin_path = sys . argv [ 1 ]
module_path = os . path . join (
moon_coin_path, "build" , "Examples" , "bytecode_modules" , "moon_coin.mv"
)
with open (module_path, "rb" ) as f :
module = f . read ()
metadata_path = os . path . join (
moon_coin_path, "build" , "Examples" , "package-metadata.bcs"
)
with open (metadata_path, "rb" ) as f :
metadata = f . read ()
print ( "\\nPublishing MoonCoin package." )
txn_hash = rest_client . publish_package (alice, metadata, [module])
rest_client . wait_for_transaction (txn_hash)
第 4.2 步:了解 MoonCoin 模块
MoonCoin 模块定义了 MoonCoin 结构,即不同的代币类型。此外,它还包含一个叫做 init_module
的函数。 init_module
在模块发布时被调用。在这种情况下,MoonCoin 将MoonCoin
币种初始化为 ManagedCoin
,该币种由帐户所有者维护。[ManagedCoin](<https://github.com/aptos-labs/aptos-core/blob/f81ccb01f00227f9c0f36856fead4879f185a9f6/aptos-move/framework/aptos-framework/sources/managed_coin.move#L1>)
是一个简单的 代币管理框架,由用户直接管理代币。它为铸造和销毁提供了便捷的包装。
Copy module MoonCoin :: moon_coin {
struct MoonCoin {}
fun init_module (sender : & signer) {
aptos_framework :: managed_coin :: initialize< MoonCoin >(
sender,
b"Moon Coin" ,
b"MOON" ,
6 ,
false ,
);
}
}
第 4.3 步:了解代币
代币有几个基本要素:
冻结——阻止一个帐户在 CoinStore 中储存代币
注册——在一个帐户上创建一个用于存储代币的 CoinStore 资源
创建一个新代币的实体也有铸造、销毁和冻结代币的能力。
为了转移、提取或存入代币,必须有一个为特定代币注册的 CoinStore。在本教程中,这就是 CoinStore<MoonCoin>
第 4.3.1 步:初始化代币
一旦代币类型发布到区块链上,发布该代币的实体可以初始化代币:
Copy public fun initialize< CoinType >(
account : & signer,
name : string :: String ,
symbol : string :: String ,
decimals : u8 ,
monitor_supply : bool ,
) : ( BurnCapability < CoinType >, FreezeCapability < CoinType >, MintCapability < CoinType >) {
let account_addr = signer :: address_of (account);
assert! (
coin_address< CoinType >() == account_addr,
error :: invalid_argument (ECOIN_INFO_ADDRESS_MISMATCH),
);
assert! (
! exists< CoinInfo < CoinType >>(account_addr),
error :: already_exists (ECOIN_INFO_ALREADY_PUBLISHED),
);
let coin_info = CoinInfo < CoinType > {
name,
symbol,
decimals,
supply : if (monitor_supply) { option :: some (optional_aggregator :: new (MAX_U128, false )) } else { option :: none () },
};
move_to (account, coin_info);
( BurnCapability < CoinType >{ }, FreezeCapability < CoinType >{ }, MintCapability < CoinType >{ })
}
这样可以确保这种代币类型之前未被初始化过,注意检查以确保初始化的调用者确实发布了这个模块,并且他们的帐户上没有存储 CoinInfo
。如果这两个条件都符合,那么就会存储一个 CoinInfo
,调用者就会获得销毁、冻结和铸造的能力。
MoonCoin 软件包发布时自动调用这个函数。
第 4.3.2 步:注册代币
实体必须在他们的帐户上为代币注册一个 CoinStore
才能使用代币:
Copy public fun register< CoinType >(account : & signer) {
let account_addr = signer :: address_of (account);
assert! (
! is_account_registered< CoinType >(account_addr),
error :: already_exists (ECOIN_STORE_ALREADY_PUBLISHED),
);
account :: register_coin< CoinType >(account_addr);
let coin_store = CoinStore < CoinType > {
coin : Coin { value : 0 },
frozen : false ,
deposit_events : account :: new_event_handle< DepositEvent >(account),
withdraw_events : account :: new_event_handle< WithdrawEvent >(account),
};
move_to (account, coin_store);
}
由于这是一个 public fun
而不是一个 public entry fun
,代币需要提供注册方式,或者用户可以构建 Move 脚本来调用该功能。
MoonCoin 使用 ManagedCoin
,它提供了一个入口函数封装器:managed_coin::register
第 4.3.3 步:铸造代币
铸造代币需要初始化时产生的铸造能力。它接受该功能和数量并返回一个包含代币数量的 Coin<T>
结构。它将在代币跟踪供应时更新。
Copy public fun mint< CoinType >(
amount : u64 ,
_cap : & MintCapability < CoinType >,
) : Coin < CoinType > acquires CoinInfo {
if (amount == 0 ) {
return zero< CoinType >()
};
let maybe_supply = &mut borrow_global_mut< CoinInfo < CoinType >>(coin_address< CoinType >()) . supply;
if (option :: is_some (maybe_supply)) {
let supply = option :: borrow_mut (maybe_supply);
optional_aggregator :: add (supply, (amount as u128 ));
};
Coin < CoinType > { value : amount }
}
ManagedCoin
通过提供一个入口函数 managed_coin::mint
让这个过程变得更容易。
第 4.3.4 步:转移代币
Aptos 提供了几个构建块来支持转移:
coin::deposit<CoinType>
允许任何实体将代币存入已经调用 coin::register<CoinType>
的帐户
coin::withdraw<CoinType>
允许任何实体从其帐户中提取代币金额
coin::transfer<CoinType>
利用提款和存款来执行端到端的转账
Aptos 不会发出转账事件,而是利用提款和存款事件。