你的第一个 Coin
本教程介绍了如何编译、部署和铸造自己的代币,名为 MoonCoin。
第 1 步:选择一个 SDK
从以下列表中安装您喜欢的 SDK:
步骤 2:安装 CLI
步骤 3:运行示例
克隆 aptos-core 存储库:
git clone https://github.com/aptos-labs/aptos-core.git
- Typescript
- Python
- Rust
切换到 TypeScript SDK 目录:
cd ~/aptos-core/ecosystem/typescript/sdk
安装必要的依赖项:
yarn
运行示例 TypeScript your_coin
:
yarn your_coin ~/aptos-core/aptos-move/move-examples/moon_coin
切换到 Python SDK 目录:
cd ~/aptos-core/ecosystem/python/sdk
安装必要的依赖项。 另请参阅 Aptos 开发人员资源:
curl -sSL https://install.python-poetry.org | python3
poetry update
运行示例 Python your-coin
:
poetry run python -m examples.your-coin ~/aptos-core/aptos-move/move-examples/moon_coin
Coming soon.
步骤 3.1:构建包
示例运行将会暂停并显示以下输出:
=== Addresses ===
Alice: 0x5e603a89cf690d7134cf2f24fdb16ba90c4f5686333721c12e835fb6c76bc7ba
Bob: 0xc8421fa4a99153f955e50f1de2a6acff2f3fd0bb33aa17ba1f5b32b699f6c825
Update the package with Alice's address, compile, and press enter.
此时,打开另一个终端并将目录更改为 MoonCoin 包的目录:
cd ~/aptos-core/aptos-move/move-examples/moon_coin
接下来,使用 CLI 构建包:
aptos move compile --named-addresses MoonCoin=0x5e603a89cf690d7134cf2f24fdb16ba90c4f5686333721c12e835fb6c76bc7ba --save-metadata
--named-addresses
是一个地址映射列表,必须指定这些地址映射,以便将要编译的包存储在 Alice 的帐户中。请注意MoonCoin
是如何设置为上面打印的 Alice 的地址的。发布包还需要--save-metadata
。
步骤 3.2:完成示例
返回到上一个提示,按 ENTER,因为包现在可以发布了。
应用程序将完成,打印:
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 合约实际上是一组称为包的 Move 模块。部署或升级新包时,必须使用 --save-metadata 调用编译器来发布包。对于 MoonCoin,以下输出文件至关重要:
build/Examples/package-metadata.bcs
:包含与包关联的元数据。build/Examples/bytecode_modules/moon_coin.mv
:包含moon_coin.move
模块的字节码。
这些由示例读取并发布到 Aptos 区块链:
- Typescript
- Python
- Rust
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 });
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)
Coming soon.
步骤 4.2:了解 MoonCoin 模块
MoonCoin 模块定义了 MoonCoin
结构,或代币类型的不同类型。此外,它还包含一个名为 init_module
的函数。发布模块时会调用 init_module
函数。在这种情况下,MoonCoin 将MoonCoin
代币类型初始化为ManagedCoin
,由账户所有者维护。
ManagedCoin
是一个简单的代币管理框架对于由用户直接管理的代币。它为 mint
和 burn
提供了方便的包装器。
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
。在本教程中,这是CoinStore<MoonCoin>
。
步骤 4.3.1:初始化代币
一旦代币类型发布到 Aptos 区块链,发布该代币类型的实体就可以对其进行初始化:
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>{ })}
这确保了这种代币类型以前从未被初始化过。 请注意第 10 行和第 15 行的检查,以确保initialize
的调用者与实际发布此模块的调用者相同,并且他们的帐户中没有存储CoinInfo
。 如果这两个条件都满足,则存储CoinInfo
,调用者获得燃烧、冻结和铸造的能力。
MoonCoin 在发布包时会自动调用此initialize
函数。
步骤 4.3.2:注册代币
要使用代币,实体必须在其帐户上为其注册一个CoinStore
:
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 的script
来调用该函数。
MoonCoin 使用提供入口函数包装器的ManagedCoin
:managed_coin::register
。
步骤 4.3.3:铸造代币
铸造代币需要在初始化期间产生的铸造能力。 mint
函数(见下文)接受该能力和数量,并返回一个包含该数量代币的 Coin<T>
结构。 如果代币跟踪供应,它将被更新。
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 不会发出转账事件,而是利用提款和存款事件。