本文由Flow的技术大使FOU编写。他在学习Flow链上稳定币FUSD的过程中总结得出,希望能够给学习FUSD代码的小伙伴一定的启发和帮助。
摘要
1. FUSD基础源码分析
2. 重点分析FUSD合约是如何授予别人mint权限并能单方面撤回的
3. 补足FUSD Github中缺失的transaction
4. 其他想法
建议前置知识:
1. 了解Fungible Token 标准: [https://github.com/onflow/flow-ft]
2. 熟悉Capability: [https://docs.onflow.org/cadence/language/capability-based-access-control/]
Flow的相关链接:
FUSD官方信息:
[https://docs.onflow.org/fusd/]
[https://docs.onflow.org/fusd/transactions/]
[https://docs.onflow.org/fusd/providers/]
FUSD在测试网和主网上的合约地址:
https://flow-view-source.com/testnet/account/0xe223d8a629e49c68/contract/FUSD
FUSD Github:
[https://github.com/onflow/fusd]
查询FUSD余额:
[https://github.com/onflow/fusd/blob/main/transactions/scripts/get_fusd_balance.cdc]
FUSD在Flow Scan:
[https://flowscan.org/contract/A.3c5959b568896393.FUSD/transfers]
FUSD合约概览:
FUSD合约遵循Fungible Token标准,因此任何人都可以创建 `Vault Resource`,并通过 `Vault Resource`接收或转出FUSD,并且任何人都可以查询所有人的FUSD 余额(Balance)。
此外,合约的AdminAccount可以通过“授予”其他用户 `Minter Capability`以允许其他账户mint FUSD。并且,AdminAccount可以单方面通过 `unlink capability`撤回(revoke)用户的mint FUSD的权利。
实现细节:
合约的前半部分是主要是实现Fungible Token标准的interface,在此不做赘述。将来我们会详细分析FT和NFT标准合约。
FUSD合约的亮点是在对于Minter权限的处理上。
首先我们可以看到在 `init()`语句中,创建了 `Administrator`的 `resource`并存储在 `adminAccount`的 `storage`中。
```swift
let admin <- create Administrator()
adminAccount.save(<-admin, to: self.AdminStoragePath)
```
`Administrator` `resource`只有一个用来创建新minter的 `function`,这个function会创建并返回一个 `Minter` `resource`
```swift
pub resource Administrator {
// createNewMinter
// Function that creates a Minter resource.
// This should be stored at a unique path in storage then a capability to it wrapped
// in a MinterProxy to be stored in a minter account's storage.
// This is done by the minter account running:
// transactions/FUSD/minter/setup_minter_account.cdc
// then the admin account running:
// transactions/flowArcaddeToken/admin/deposit_minter_capability.cdc
//
pub fun createNewMinter(): @Minter {
emit MinterCreated()
return <- create Minter()
}
} ;
`Minter` `resource`包含对应的 `mintTokens function`可以铸造新的FUSD,并将新铸造的FUSD数量累加到总供应量( `totalSupply`)中。mintTokens function利用 `pre condition`确保amount变量为正数,并创建返回一个 `FUSD.Vault resource`。
```swift
// Minter
// Resource object that can mint new tokens.
// The admin stores this and passes it to the minter account as a capability wrapper resource.
//
pub resource Minter {
// mintTokens
// Function that mints new tokens, adds them to the total supply,
// and returns them to the calling context.
//
pub fun mintTokens(amount: UFi