6 个版本 (稳定版)
3.0.0 | 2024 年 7 月 11 日 |
---|---|
2.0.0 | 2024 年 5 月 1 日 |
2.0.0-rc | 2024 年 4 月 25 日 |
1.4.0 |
|
1.0.1 | 2023 年 6 月 22 日 |
#706 在 魔法豆
4,398 每月下载次数
在 11 个crate中使用 (10 个直接使用)
33KB
466 行
CW20 规范:可互换代币
CW20 是基于 CosmWasm 的可互换代币规范。名称和设计灵感来源于以太坊的 ERC20 标准,但进行了许多改动。这里的类型可以被希望实现此规范的合约或调用任何标准 cw20 合约的合约导入。
规范分为多个部分,合约可以只实现其中一些功能,但必须实现基础功能。
基础
这部分处理余额和转账。注意,所有金额都处理为 Uint128
(128 位整数,具有 JSON 字符串表示形式)。小数点的处理留给 UI,不进行解释
消息
Transfer{recipient, amount}
- 将 amount
代币从 info.sender
账户转移到 recipient
账户。这是设计用来发送到由私钥控制的地址,如果接收方是合约,则不会触发任何动作。
发出的属性
键 | 值 |
---|---|
"action" | "转移" |
"从" | 发送者 |
"到" | 接收者 |
"数量" | 数量 |
Send{contract, amount, msg}
- 将amount
代币从info.sender
账户转移到contract
账户。 contract
必须是实现Receiver
接口的合约地址。消息msg
将随数量传递给接收合约。 contract
必须是一个实现Receiver
接口的合约地址。消息msg
将随数量传递给接收合约,并包含数量信息。
发出的属性
键 | 值 |
---|---|
"action" | "发送" |
"从" | 发送者 |
"到" | 接收者 |
"数量" | 数量 |
Burn{amount}
- 从info.sender
的余额中移除amount
代币,并将total_supply
减少相同数量。
发出的属性
键 | 值 |
---|---|
"action" | "销毁" |
"从" | 发送者 |
"数量" | 数量 |
查询
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
可以从info.sender
账户访问多达amount + current_allowance
个代币。这可以附带一个Expiration
时间,如果设置了,将限制批准额度可以使用的时间(按时间或高度)。
发出的属性
键 | 值 |
---|---|
"action" | "increase_allowance" |
"owner" | 发送者 |
"spender" | spender |
"数量" | 数量 |
DecreaseAllowance{spender, amount, expires}
- 减少或清除允许额度,使得spender
可以从info.sender
账户访问多达current_allowance - amount
个代币。这可以附带一个Expiration
时间,如果设置了,将限制批准额度可以使用的时间(按时间或高度)。如果amount >= current_allowance
,这将清除允许额度(删除它)。
发出的属性
键 | 值 |
---|---|
"action" | "decrease_allowance" |
"owner" | 发送者 |
"spender" | spender |
"数量" | 数量 |
TransferFrom{owner, recipient, amount}
- 这利用了允许额度,如果存在有效的、未过期的预先批准额度,那么我们将amount
个代币从owner
转移到recipient
,并从可用的允许额度中扣除。
发出的属性
键 | 值 |
---|---|
"action" | "transfer_from" |
"从" | 转账账户 |
"到" | 接收者 |
"by" | 消息发送者 |
"数量" | 数量 |
SendFrom{owner, contract, amount, msg}
- SendFrom
对应于Send
,而TransferFrom
对应于Transfer
。这允许预先批准的账户不仅能够转账代币,还可以将代币发送到另一个合约以触发特定的操作。注意 SendFrom
将Receive{sender}
设置为触发转账的账户(即info.sender
),而不是资金来源的账户(即owner
账户)。这是一个开放性问题,我们是否应该切换这个操作?
发出的属性
键 | 值 |
---|---|
"action" | "send_from" |
"从" | 发送账户 |
"到" | 接收者 |
"by" | 消息发送者 |
"数量" | 数量 |
BurnFrom{owner, amount}
- 这与 TransferFrom
类似,但不是转账而是销毁代币。这将减少所有者的余额、total_supply
和调用者的额度。
发出的属性
键 | 值 |
---|---|
"action" | "burn_from" |
"从" | 被销毁的账户 |
"by" | 消息发送者 |
"数量" | 数量 |
查询
Allowance{owner, spender}
- 这返回 spender
可以从 owner
的账户中使用的额度,以及过期信息。返回类型为 AllowanceResponse{balance, expiration}
。
可增发
这允许另一个合约增发新的代币,可能有限额。这里只指定了一个增发者,如果您需要更复杂的访问管理,请使用多重签名或其他合约作为增发者地址,并在那里处理更新 ACL。
消息
Mint{recipient, amount}
- 如果 info.sender
是允许的增发者,这将创建 amount
个新代币(更新总供应量)并将其添加到 recipient
的余额中,只要不超过限额。
发出的属性
键 | 值 |
---|---|
"action" | "mint" |
"到" | 接收者 |
"数量" | 数量 |
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
提供分页。
营销
这使我们能够在代币上附加更多元数据,以帮助在钱包中显示代币。当你在网站上看到代币,然后在钱包中看到它时,你就知道它是什么。然而,如果你在钱包或去中心化交易所交易对中看到它,就没有明确的方式来获取更多关于它的信息。
这个扩展使我们能够附加更多“营销”元数据,这对代币的链上功能没有影响,但在提供更好的客户端体验方面非常有用。请注意,我们添加了一个新的角色 marketing
,它可以更新此类信息,但不能影响链上逻辑。
消息
UploadLogo{url | embedded}
- 如果 info.sender
是允许的营销账户,这将设置一个新的URL引用,其中提供标志,或者允许它们将小于5KB的SVG或PNG标志上传到区块链以供服务。
发出的属性
键 | 值 |
---|---|
"action" | "upload_logo" |
UpdateMarketing{project, description, marketing}
- 如果 info.sender
是允许的营销账户,这将更新合约上的某些营销相关元数据。
发出的属性
键 | 值 |
---|---|
"action" | "update_marketing" |
查询
MarketingInfo{}
- 返回营销相关元数据。返回类型是 MarketingInfoResponse {project, description, logo, marketing}
。
DownloadLogo{}
- 如果代币的标志之前已上传到区块链(参见 UploadLogo
消息),则返回用于在浏览器中显示的原始数据。返回类型是 DownloadLogoResponse{ mime_type, data }
。
依赖关系
~5–17MB
~190K SLoC