距离上一次 NFT MetadataView 标准发布以来, 历时 11 个月, Flow 同质化代币也迎来了 MetadataView 的标准, 虽然还是在测试阶段, 但可以期待标准的正式采用, 这次的升级不仅为我们带来了同质化代币的 MetadataView 标准合约, FungibleTokenSwitchboard 可以实现一个通用的收款 Receiver 资源解决之前 NFTMetadataView 中 Royalty 配置的问题.
这次的升级也是以对标准合约低修改的方式进行, 整体的设计思路与 NFTMetadataViews 一致, 对 NFTMetadataViews 感兴趣的小伙伴可以在这里阅读我之前写的介绍文章, 还有一篇是关于 Flow NFT 与 FT 的设计实践与说明, 本文会根据 FT 标准合约的两个重大的更新进行介绍和说明.
要点:
本次的更新升级只部署在测试网, 新的特性需要新版本的 Cadence 支持
原有的 FT 合约不强制升级, 不升级不会影响使用
用户已经初始化过的 Vault 的资源也不需要重新初始化, 如果合约实现进行函数升级, 则用户已经初始化的资源会自动继承
除了包含基础的 FT 信息之外, 也会包含资源信息和类型信息 ( 猜测是为了链上信息聚合展示做准备 )
同 NFTMetadataView 类似, FTMetadataView 也具备展示类型扩展的能力, 可以支持未来更多的 Metadata 种类.
FungibleTokenSwitchboard 作为一个额外的路由资源, 保存了用户账户下的 FT Receiver 资源, 能够作为一个路由通过一个资源接收多种 FT token
FungibleTokenMetadataViews
FungibleTokenMetadataViews.cdc 依赖了 FungibleToken 与 MetadataViews
其中定义了 FTView 结构, 包含了 FTDisplay 和 FTVaultData 两个结构
FTDisplay 包含了 FT 展示所需要的信息, 名称, 符号, 描述, 外部链接, Logo 链接和一些社交账号的链接, 可以理解为 Token 的基本信息
FTVaultData 这是包含了 FT Vault 的资源信息和接口的一些类型信息,这里还包含了一个创建 Vault 的初始化函数 createEmptyVault
从实现来看 FTDisplay 是为了丰富 FungibleToken 的链上基础信息而设计, 而 FTVaultData 这是为了方便第三方集成对 Token 做链上集成而设计, 通过标准的 MetadataViews 接口就可以兼容各种类型的 FungibleToken
当然这个假设的前提是 FungibleToken 都实现了 MetadataViews 所需要的接口, 接下来我们看 FungibleToken 做了哪些改动和升级:
pub fun getViews(): [Type] {
return []
}
pub fun resolveView(_ view: Type): AnyStruct? {
return nil
}
其实 FungibleToken 只是在原有的 Balance 类型的接口中添加了 getViews 和 resolveView 两个函数, 返回的是 optional 的类型.这里并没有引入新添加的合约依赖, 反而是在示例的 ExampleToken 中引入:
注意: 这里 FungibleToken 的改动略有不同.因为增加了 Balance 接口类型中的实现函数, 会导致现有部署在网络中继承了 FungibleToken.Balance 的资源出现问题, ( 正常来讲这样继承了 FungibleToken.Balance 却没有实现 getViews 和 resolveView 的合约是无法正常部署的 ) 在和 B.T.Wood 讨论时候他告诉我了一个 Cadecne 最近的更新 概括来说是如果继承了接口的资源即使没有实现接口定义的方法,这会使用接口自身的默认方法, 这样就不会出现上述问题.这个 feature 将会在未来的 spork 更新.
并在 Vault 资源里实现了这两个新的接口:
pub fun getViews(): [Type]{
return [Type<FungibleTokenMetadataViews.FTView>(),
Type<FungibleTokenMetadataViews.FTDisplay>(),
Type<FungibleTokenMetadataViews.FTVaultData>()]
}
这里定义了三种结构类型 FTView 和他其中的两个包含的结构 FTDisplay 与 FTVaultData。
升级之后我们就可以在现有的 FungibleToken 的 Balance 接口中直接调用 getViews 去获取当前 Token 支持的 MetadataView 类型, 并通过 resolveView 获取具体的 Metadata 信息。
这样的代码结构, 达到了向后兼容的效果, 也满足了未来根据需要动态增加 Metadata 类型的需求, 可以通过扩展 FungibleTokenMetadataViews 支持的类型来丰富 FT 的链上元数据。
FungibleTokenSwitchboard
我们可以将 FungibleTokenSwitchboard 理解为一个账户中的聚合路由资源, 他实现了 FungibleToken.Receiver 的接口, 在标准中充当了一个万能收款的角色, 通过资源中的 receiverCapabilities 来保存用户账户下的 Vault 的 Receiver 实现了只需要一个 Receiver 就能将收款转发至对应具体的 Receiver 的功能.
Switchboard 资源里定义了 receiverCapabilities 来聚合 FungibleToken 的收款资源:
pub resource Switchboard: FungibleToken.Receiver, SwitchboardPublic {
access(contract) var receiverCapabilities: {Type: Capability<&{FungibleToken.Receiver}>}
//....
}
receiverCapabilities 以 Type 为键, Vault 的收款 Capability 为值作为路由收款的核心
同时提供了管理路由的方法:
addNewVault 支持通过 Capability 添加新的 Vault 路由到 Switchboard
addNewVaultsByPath 通过资源路径的数组批量添加到 Switchboard
removeVault 移除
因为 Switchboard 继承了 FungibleToken.Receiver 所以需要实现 deposit 函数
pub fun deposit(from: @FungibleToken.Vault) {
// Get the capability from the ones stored at the switchboard
let depositedVaultCapability = self
.receiverCapabilities[from.getType()]
?? panic ("The deposited vault is not available on this switchbard")
// Borrow the reference to the desired vault
let vaultRef = depositedVaultCapability.borrow()
?? panic ("Can not borrow a reference to the the vault")
vaultRef.deposit(from: <-from)
}
这个充值函数实现了一个转发存款的功能, 将收款路由至配置中的具体资源, 我们也看到这里如果没有找到 receiverCapabilities 对应的值, 程序就会 Panic 导致 deposit 的交易失败。
为了方便第三方使用, 同时定义了 SwitchboardPublic 的接口类型定义了三种函数:
getVaultTypes 获取支持接收的 Vault 类型
deposit 同上
safeDeposit 安全的充值函数, 即使失败也不会引起 Panic 而是返回 @FungibleToken.Vault 资源
和 Deposit 相同, 接收 @FungibleToken.Vault 资源
会先做判断 receiverCapabilities 是否有配置对应资源的接收资源
如果没找到且充值金额大于零, 则触发充值失败的事件, 并将充值的 @FungibleToken.Vault 资源返回
否则直接销毁充值资源并返回 nil
pub fun safeDeposit(from: @FungibleToken.Vault): @FungibleToken.Vault? {
// Try to get the proper vault capability from the switchboard
// If the desired vault is present on the switchboard...
if let depositedVaultCapability = self
.receiverCapabilities[from.getType()] {
// We try to borrow a reference to the vault from the capability
// If we can borrow a reference to the vault...
if let vaultRef = depositedVaultCapability.borrow() {
// We deposit the funds on said vault
vaultRef.deposit(from: <-from.withdraw(amount: from.balane))
}
}
// if deposit failed for some reason
if from.balance > 0.0 {
emit NotCompletedDeposit(type: from.getType(),
amount: from.balance,
switchboardOwner: self.owner?.address)
return <-from
}
destroy from
return nil
}
总之 Switchboard 资源作为一个第三方的路由资源, 给用户提供了一个通用的收款方式, 这样在之前 NFTMetadataViews 中关于 Royalty 的版税配置就可以接收多种 FT 资产了。
从应用的角度来讲, 仍需要第三方开发者或钱包入口进行新合约的整合与引入, 能够方便用户自己手动配置和管理 Switchboard 中的资源。
NFT borrowNFTSafe
另外 NFT 的标准合约也发布了更新, 在 NFT CollectionPublic 的资源接口中新增了 borrowNFTSafe 函数, 目的是为了防止在查询脚本的执行过程中因无法找到账户下具体 ID 的 NFT 会导致脚本执行报错的情况,提高了开发者的查询与开发的体验。
最后
本次的更新还在测试网部署的阶段, 开发者可以在测试网体验新标准和新合约的功能, 待未来主网 spork 之后,这些新的代码将会部署, 届时 FT 就具备了链上查询 Metadata 的能力, 原有的 FT 发行方就可以根据示例的 FT 项目进行新函数的实现并升级自己的合约.
如此一来, 支持 FT 的 catalog 产品应该就不远了.
关注 Flow
什么是 Flow 福洛链?
Flow 福洛链是一个快速,去中心化,且对开发者友好的区块链,旨在为新一代游戏、娱乐应用程序提供动力的数字资产的基础。Flow 是唯一一个由始至终为消费者提供出色体验的 Layer-1 区块链团队。其团队创造的 dApp 包括:CryptoKitties、Dapper Wallets、NBA Top shot。
CrytoKitties 于 2017 年推出时便快速成为加密市场最受欢迎的 dApp,因其成功而导致以太坊堵塞。在 Flow 上运营的 NBA Top shot 也已成为增长最快的 dApp,在公开发布后的 6 个月创造了 7 亿美金销量。正因为 Flow 公链的可扩展性和消费者友好的体验,让这一切成为可能。目前有 1000 多个项目正在 Flow 链上筹备中,我们期待看到一个伟大的生态系统蓬勃发展。
关于 Dapper Labs
Dapper Labs 是一家位于加拿大的全球顶尖区块链服务商,在 2017 年年底通过 CryptoKitties 收藏游戏成功进入⽤户视野,并且因为加密猫的爆⽕导致以太坊拥堵,从而推出 Flow 公链以及全新的开发语言—— Cadence,旨在吸引更多的开发者在 Flow 上开发应⽤。
Flow 的合作伙伴们:
我们欢迎越来越多的小伙伴加入 Flow 星球,为星球增添色彩!
Flow 官网:https://zh.onflow.org/
Flow 论坛: https://forum.onflow.org/
Flow Discord:
https://discord.com/invite/flow
Flow CN Telegram: https://t.me/flow_zh
Flow B 站:https://space.bilibili.com/1002168058
Flow 微博:
https://weibo.com/7610419699
Flow CSDN:
https://blog.csdn.net/weixin_57551966?spm=1010.2135.3001.5343
扫码添加 Flow 官方账号微信号,加入 Flow 生态群
微信号 : FlowChainOfficial
【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。