56 个版本 (6 个稳定版)
2.0.0 | 2024年3月26日 |
---|---|
1.1.2 | 2023年11月23日 |
1.1.0 | 2023年6月20日 |
1.0.1 | 2022年12月19日 |
0.1.0 | 2020年7月7日 |
#1443 in 神奇豆
每月下载量 31,466
用于 322 个 crate (210 个直接使用)
33KB
465 行
CW20 规范:可交易代币
CW20 是基于 CosmWasm 的可交易代币规范。名称和设计灵感来源于以太坊的 ERC20 标准,但进行了许多修改。这里定义的类型可以被希望实现此规范的合约或调用任何标准 cw20 合约的合约导入。
本规范分为多个部分,合约可能只实现其中的一些功能,但必须实现基本功能。
基础
这部分处理余额和转账。注意,所有金额都以 Uint128
(128 位整数,具有 JSON 字符串表示形式) 处理。小数点的处理留给 UI,不会被解释。
消息
Transfer{recipient, amount}
- 将 amount
代币从 info.sender
账户转移到 recipient
账户。此操作设计为向由私钥控制的地址发送,如果接收方是合约,则不会触发任何操作。
发射的属性
键 | 值 |
---|---|
"action" | "transfer" |
"from" | sender |
"to" | recipient |
"amount" | amount |
Send{contract, amount, msg}
- 将 amount
个代币从 info.sender
账户转移到 contract
账户。 contract
必须是实现 Receiver
接口的合约的地址。 msg
将与数量一起传递给接收合约。
发射的属性
键 | 值 |
---|---|
"action" | "send" |
"from" | sender |
"to" | recipient |
"amount" | amount |
Burn{amount}
- 从 info.sender
的余额中移除 amount
个代币,并将 total_supply
减少相同数量。
发射的属性
键 | 值 |
---|---|
"action" | "burn" |
"from" | sender |
"amount" | amount |
查询
Balance{address}
- 返回给定地址的余额。如果该地址对合约来说是未知的,则返回 "0"。返回类型是 BalanceResponse{balance}
。
TokenInfo{}
- 返回合约的代币信息。返回类型是 TokenInfoResponse{name, symbol, decimal, total_supply}
。
接收器
Send
的对应操作是 Receive
,任何希望管理 CW20 代币的合约都必须实现该操作。这通常 不是 由任何 CW20 合约实现的。
Receive{sender, amount, msg}
- 这是用来处理 Send
消息的。合约地址存储在 info.sender
中,因此不能伪造。合约应确保发送者匹配它期望处理的代币合约,并且不允许任意地址。
sender
是请求移动代币的原始账户,msg
是可以解码为特定合约消息的 Binary
数据。如果只有一个默认操作,则此字段可以为空,或者它可能是一个 ReceiveMsg
变体,以明确意图。例如,如果我将代币发送到 uniswap 合约,我可以使用此字段指定我想与之交换的代币。
许可
合约可能允许行为者将部分余额委托给其他账户。这与 ERC20 不同,因为我们使用 Send
/Receive
将代币发送到合约,而不是使用 Approve
/TransferFrom
。但这仍然是一个很好的用例,你可以看到 Cosmos SDK 如何想要向原生代币添加支付许可。这主要是为了提供对基于公钥的其他账户的访问。
原始 ERC20 许可规范中存在竞争条件问题。如果你有一个 50 的许可,而我想要将其减少到 20,我提交一个交易将许可设置为 20。如果你看到这个交易,并立即提交一个交易使用整个 50,那么你将获得额外的 20。这不仅在你减少之前迅速消耗了 50,你还免费获得了另外 20。
在以太坊社区中讨论的解决方案是使用一个IncreaseAllowance
和DecreaseAllowance
操作符(而不是Approve
)。为了最初设置批准,使用IncreaseAllowance
,这在没有之前批准的情况下也能正常工作。DecreaseAllowance
旨在具有鲁棒性,即如果你减少的金额超过当前批准的金额(例如,用户在中间花了一些),它将直接向下取整到0,不会产生任何下溢错误。
消息
IncreaseAllowance{spender, amount, expires}
- 设置或增加批准,使得spender
可以访问最多amount + current_allowance
个来自info.sender
账户的代币。这可以附带一个Expiration
时间,如果设置了,将限制批准的使用时间(时间或高度)。
发射的属性
键 | 值 |
---|---|
"action" | "increase_allowance" |
"owner" | sender |
"spender" | spender |
"amount" | amount |
DecreaseAllowance{spender, amount, expires}
- 减少或清除批准,使得spender
可以访问最多current_allowance - amount
个来自info.sender
账户的代币。这可以附带一个Expiration
时间,如果设置了,将限制批准的使用时间(时间或高度)。如果amount >= current_allowance
,这将清除批准(删除它)。
发射的属性
键 | 值 |
---|---|
"action" | "decrease_allowance" |
"owner" | sender |
"spender" | spender |
"amount" | amount |
TransferFrom{owner, recipient, amount}
- 这利用了批准,如果存在一个有效的、未过期的对info.sender
的预批准,那么我们将amount
个代币从owner
转移到recipient
,并从可用的批准中扣除。
发射的属性
键 | 值 |
---|---|
"action" | "transfer_from" |
"from" | 转账账户 |
"to" | recipient |
"by" | 消息发送者 |
"amount" | amount |
SendFrom{owner, contract, amount, msg}
- SendFrom
相当于Send
,而TransferFrom
相当于Transfer
。这允许一个预批准的账户不仅可以将代币转移,还可以将其发送到另一个合约以触发特定的操作。注意 SendFrom
将设置Receive{sender}
为info.sender
(触发转账的账户)而不是owner
账户(资金来源的账户)。这是一个开放性问题,我们应该切换这个吗?
发射的属性
键 | 值 |
---|---|
"action" | "send_from" |
"from" | 发送账户 |
"to" | recipient |
"by" | 消息发送者 |
"amount" | amount |
BurnFrom{owner, amount}
- 这与TransferFrom
类似,但是是销毁代币而不是转账。这将减少所有者的余额、total_supply
和调用者的批准。
发射的属性
键 | 值 |
---|---|
"action" | "burn_from" |
"from" | 销毁账户 |
"by" | 消息发送者 |
"amount" | amount |
查询
Allowance{owner, spender}
- 此函数返回spender
可以访问的owner
账户中可用的额度,以及过期信息。返回类型为AllowanceResponse{balance, expiration}
。
可铸造
这允许另一个合约铸造新的代币,可能还有上限。这里只指定了一个铸造者,如果您需要更复杂的访问管理,请使用多签或其它合约作为铸造者地址,并在那里处理ACL的更新。
消息
Mint{recipient, amount}
- 如果info.sender
是允许的铸造者,这将创建amount
个新的代币(更新总供应量)并将其添加到recipient
的余额中,只要不超过上限。
发射的属性
键 | 值 |
---|---|
"action" | "mint" |
"to" | recipient |
"amount" | amount |
UpdateMinter { new_minter: Option<String> }
- 仅由当前铸造者可调用。如果new_minter
是Some(address)
,则铸造者设置为指定的地址,否则移除铸造者,并且不能设置未来的铸造者。
发射的属性
键 | 值 |
---|---|
"action" | "update_minter" |
"new_minter" | 铸造者地址或移除时为"None" |
查询
Minter{}
- 返回谁可以铸造以及可以铸造多少。返回类型为MinterResponse {minter, cap}
。上限可能未设置。
如果设置了上限,它定义了可以存在的最大total_supply
。如果初始供应量为1000,上限为Some(2000)
,则只能再铸造1000个代币。然而,如果有人后来销毁了500个代币,铸造者可以再次铸造这500个。这允许在一定的参数内动态调整代币供应量,尤其是在铸造者是智能合约的情况下。
可枚举
这应该在所有具有迭代器支持的区块链上启用。它允许我们通过分页获取结果列表。
查询
AllAllowances{owner, start_after, limit}
- 返回给定所有者所有未过期额度的列表。 start_after
和limit
提供分页。
AllAccounts{start_after, limit}
- 返回在合约上创建的所有账户的列表(仅地址)。 start_after
和limit
提供分页。
营销
这使我们能够在代币上附加更多元数据,以帮助在钱包中显示代币。当你在网站上看到代币,然后在钱包中看到它时,你就知道它是什么。然而,如果你在钱包或去中心化交易所(DEX)交易对中看到它,就没有明确的方式来获取更多关于它的信息。
这个扩展允许我们附加更多“营销”元数据,这对代币的链上功能没有影响,但在提供更好的客户端体验方面非常有用。请注意,我们添加了一个新的角色 marketing
,它可以更新此类信息,但不能影响链上逻辑。
消息
UploadLogo{url | embedded}
- 如果 info.sender
是允许的营销账户,这将设置一个新的URL引用,其中提供logo,或者允许它们在区块链上上传一个小于5KB的小型(小于5KB)SVG或PNG logo。
发射的属性
键 | 值 |
---|---|
"action" | "upload_logo" |
UpdateMarketing{project, description, marketing}
- 如果 info.sender
是允许的营销账户,这将更新合约上的一些与营销相关的元数据。
发射的属性
键 | 值 |
---|---|
"action" | "update_marketing" |
查询
MarketingInfo{}
- 返回与营销相关的元数据。返回类型是 MarketingInfoResponse {project, description, logo, marketing}
。
DownloadLogo{}
- 如果代币的logo之前已上传到区块链(请参阅 UploadLogo
消息),则返回要在浏览器中显示的原始数据。返回类型是 DownloadLogoResponse{ mime_type, data }
。
依赖关系
~3.5–7MB
~144K SLoC