AuthZ
Last updated
Last updated
x/authz
是一个基于 实现的 Cosmos SDK 模块,允许从一个账户(授予者)向另一个账户(被授权者)授予任意权限。授权必须针对特定的 Msg
服务方法逐个授予,使用 Authorization
接口的实现。
Authorization
和 Grant
Grant
是一种授权,允许被授权者代表授予者执行一个 Msg
。Authorization
是一个接口,必须由具体的授权逻辑实现,以验证和执行授权。授权是可扩展的,可以为任何 Msg
服务方法定义,即使该方法定义在模块之外。有关更多细节,请参见下一节中的 SendAuthorization
示例。
Cosmos SDK x/authz
模块提供以下授权类型:
GenericAuthorization
实现了 Authorization
接口,授予无限制的权限,允许代表授予者账户执行提供的 Msg
。
msg
存储 Msg
类型的 URL。
SendAuthorization
实现了 Authorization
接口,用于 cosmos.bank.v1beta1.MsgSend
消息。
它接受一个(正数)SpendLimit
,指定被授权者可以花费的最大代币数量。随着代币的花费,SpendLimit
会更新。
它还接受一个(可选的)AllowList
,指定被授权者可以向哪些地址发送代币。
spend_limit
用于跟踪授权中剩余的代币数量。
allow_list
指定一个可选的地址列表,受权人可以代表授予者向这些地址发送代币。
为了防止 DoS 攻击,授予 StakeAuthorization
使用 x/authz
模块会消耗 gas。StakeAuthorization
允许你授权另一个账户向验证者进行委托、取消委托或重新委托。授权者可以定义一个验证者列表,允许或拒绝向这些验证者进行委托。Cosmos SDK 会遍历这些列表,并对每个列表中的验证者收取 10 gas。
由于状态维护着具有相同过期时间的授予者和被授权者对列表,我们会遍历列表以移除授予(如果某个特定的 msgType
被撤销),每次迭代收取 20 gas。
授权通过组合授予者地址(授予者的地址字节)、被授权者地址(被授权者的地址字节)和授权类型(其类型 URL)来标识。因此,我们只允许为(授予者、被授权者、授权类型)三元组设置一个授权。
Grant: 0x01 | granter_address_len (1 byte) | granter_address_bytes | grantee_address_len (1 byte) | grantee_address_bytes | msgType_bytes -> ProtocolBuffer(AuthorizationGrant)
grant
对象封装了一个授权类型和一个过期时间戳:
我们正在维护一个用于 authz
剔除的队列。每当创建一个授权时,带有过期时间、授予者和被授权者的键将被添加到 GrantQueue
中。
在 EndBlock
(每个区块都会执行)中,我们不断检查并剔除过期的授权,通过形成一个前缀键,使用当前区块时间与 GrantQueue
中存储的过期时间进行比较,遍历所有匹配的记录并从 GrantQueue
和 Grants
存储中删除它们。
GrantQueue: 0x02 | expiration_bytes | granter_address_len (1 byte) | granter_address_bytes | grantee_address_len (1 byte) | grantee_address_bytes -> ProtocalBuffer(GrantQueueItem)
expiration_bytes
是以 UTC 格式表示的过期日期,格式为 "2006-01-02T15:04:05.000000000"
。
GrantQueueItem
对象包含在授予者和被授权者之间的类型 URL 列表,这些授权将在键中指示的时间过期。
在本节中,我们描述了 authz
模块消息的处理过程。
An authorization grant is created using the MsgGrant
message. If there is already a grant for the (授予者、被授权者、授权类型)三元组,如果存在相同的三元组,则新的授权将覆盖之前的授权。要更新或扩展现有的授权,应创建一个具有相同(授予者、被授权者、授权类型)三元组的新授权。
如果出现以下情况,消息处理应失败:
授予者和被授权者具有相同的地址。
提供的过期时间小于当前的 Unix 时间戳(但如果未提供过期时间,则会创建授权,因为过期时间是可选的)。
提供的 Grant.Authorization
未实现。
Authorization.MsgTypeURL()
在路由器中未定义(应用程序路由器中没有定义处理该消息类型的处理程序)。
授权可以通过 MsgRevoke
消息移除。
如果出现以下情况,消息处理应失败:
授予者和被授权者具有相同的地址。
提供的 MsgTypeUrl
为空。
注意:如果授权已过期,MsgExec
消息将移除该授权。
当被授权者希望代表授予者执行交易时,他们必须发送 MsgExec
消息。
如果出现以下情况,消息处理应失败:
提供的授权未实现。
被授权者没有权限执行该交易。
授予的授权已过期。
用户可以使用 CLI 查询和与 authz
模块进行交互。
查询命令允许用户查询 authz
状态。
grants
grants
命令允许用户查询授予者和被授权者对的授权。如果设置了消息类型 URL,则仅选择该消息类型的授权。
示例:
示例输出:
tx
命令允许用户与 authz
模块进行交互。
exec
exec
命令允许被授权者代表授予者执行交易。
示例:
grant
grant
命令允许授予者向被授权者授予授权。
示例:
revoke
revoke
命令允许授予者从被授权者那里撤销授权。
示例:
用户可以使用 gRPC
端点查询 authz
模块。
Grants
端点允许用户查询授予者和被授权者对的授权。如果设置了消息类型 URL,则仅选择该消息类型的授权。
示例:
示例输出:
用户可以使用 REST
端点查询 authz
模块。
示例:
示例输出:
x/authz
模块定义了接口和消息,用于授予其他账户代表一个账户执行操作的授权。该设计在 中进行了定义。
注意:authz
模块与 模块不同,后者负责指定基础的交易和账户类型。
StakeAuthorization
实现了 Authorization
接口,用于中的消息。
它接受一个 AuthorizationType
,指定是否授权委托、取消委托或重新委托(即这些操作必须分别授权)。
它还接受一个必需的 MaxTokens
,用于跟踪可以委托/取消委托/重新委托的代币数量限制。如果留空,则数量没有限制。
此外,该消息还接受一个 AllowList
或 DenyList
,允许你选择授权或拒绝被授权者与哪些验证者进行质押。
authz
模块会触发在 中定义的 proto 事件。