AuthZ
摘要
x/authz
是一个基于 ADR 30 实现的 Cosmos SDK 模块,允许从一个账户(授予者)向另一个账户(被授权者)授予任意权限。授权必须针对特定的 Msg
服务方法逐个授予,使用 Authorization
接口的实现。
目录
概念
Authorization
和 Grant
Authorization
和 Grant
x/authz
模块定义了接口和消息,用于授予其他账户代表一个账户执行操作的授权。该设计在 ADR 030中进行了定义。
Grant
是一种授权,允许被授权者代表授予者执行一个 Msg
。Authorization
是一个接口,必须由具体的授权逻辑实现,以验证和执行授权。授权是可扩展的,可以为任何 Msg
服务方法定义,即使该方法定义在模块之外。有关更多细节,请参见下一节中的 SendAuthorization
示例。
注意:authz
模块与 auth
(身份验证)模块不同,后者负责指定基础的交易和账户类型。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/authz/authorizations.go#L11-L25
内建授权
Cosmos SDK x/authz
模块提供以下授权类型:
GenericAuthorization
GenericAuthorization
实现了 Authorization
接口,授予无限制的权限,允许代表授予者账户执行提供的 Msg
。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/authz/v1beta1/authz.proto#L14-L22
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/authz/generic_authorization.go#L16-L29
msg
存储Msg
类型的 URL。
SendAuthorization
SendAuthorization
实现了 Authorization
接口,用于 cosmos.bank.v1beta1.MsgSend
消息。
它接受一个(正数)
SpendLimit
,指定被授权者可以花费的最大代币数量。随着代币的花费,SpendLimit
会更新。它还接受一个(可选的)
AllowList
,指定被授权者可以向哪些地址发送代币。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/authz.proto#L11-L30
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/bank/types/send_authorization.go#L29-L62
spend_limit
用于跟踪授权中剩余的代币数量。allow_list
指定一个可选的地址列表,受权人可以代表授予者向这些地址发送代币。
StakeAuthorization
StakeAuthorization
实现了 Authorization
接口,用于质押模块中的消息。
它接受一个 AuthorizationType
,指定是否授权委托、取消委托或重新委托(即这些操作必须分别授权)。
它还接受一个必需的 MaxTokens
,用于跟踪可以委托/取消委托/重新委托的代币数量限制。如果留空,则数量没有限制。
此外,该消息还接受一个 AllowList
或 DenyList
,允许你选择授权或拒绝被授权者与哪些验证者进行质押。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/authz.proto#L11-L35
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/staking/types/authz.go#L15-L35
燃料
为了防止 DoS 攻击,授予 StakeAuthorization
使用 x/authz
模块会消耗 gas。StakeAuthorization
允许你授权另一个账户向验证者进行委托、取消委托或重新委托。授权者可以定义一个验证者列表,允许或拒绝向这些验证者进行委托。Cosmos SDK 会遍历这些列表,并对每个列表中的验证者收取 10 gas。
由于状态维护着具有相同过期时间的授予者和被授权者对列表,我们会遍历列表以移除授予(如果某个特定的 msgType
被撤销),每次迭代收取 20 gas。
状态
Grant
授权通过组合授予者地址(授予者的地址字节)、被授权者地址(被授权者的地址字节)和授权类型(其类型 URL)来标识。因此,我们只允许为(授予者、被授权者、授权类型)三元组设置一个授权。
Grant:
0x01 | granter_address_len (1 byte) | granter_address_bytes | grantee_address_len (1 byte) | grantee_address_bytes | msgType_bytes -> ProtocolBuffer(AuthorizationGrant)
grant
对象封装了一个授权类型和一个过期时间戳:
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/authz/v1beta1/authz.proto#L24-L32
GrantQueue
我们正在维护一个用于 authz
剔除的队列。每当创建一个授权时,带有过期时间、授予者和被授权者的键将被添加到 GrantQueue
中。
在 EndBlock
(每个区块都会执行)中,我们不断检查并剔除过期的授权,通过形成一个前缀键,使用当前区块时间与 GrantQueue
中存储的过期时间进行比较,遍历所有匹配的记录并从 GrantQueue
和 Grants
存储中删除它们。
https://github.com/cosmos/cosmos-sdk/blob/5f4ddc6f80f9707320eec42182184207fff3833a/x/authz/keeper/keeper.go#L378-L403
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"
。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/authz/keeper/keys.go#L77-L93
GrantQueueItem
对象包含在授予者和被授权者之间的类型 URL 列表,这些授权将在键中指示的时间过期。
消息
在本节中,我们描述了 authz
模块消息的处理过程。
MsgGrant
An authorization grant is created using the MsgGrant
message. If there is already a grant for the (授予者、被授权者、授权类型)三元组,如果存在相同的三元组,则新的授权将覆盖之前的授权。要更新或扩展现有的授权,应创建一个具有相同(授予者、被授权者、授权类型)三元组的新授权。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/authz/v1beta1/tx.proto#L35-L45
如果出现以下情况,消息处理应失败:
授予者和被授权者具有相同的地址。
提供的过期时间小于当前的 Unix 时间戳(但如果未提供过期时间,则会创建授权,因为过期时间是可选的)。
提供的
Grant.Authorization
未实现。Authorization.MsgTypeURL()
在路由器中未定义(应用程序路由器中没有定义处理该消息类型的处理程序)。
MsgRevoke
授权可以通过 MsgRevoke
消息移除。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/authz/v1beta1/tx.proto#L69-L78
如果出现以下情况,消息处理应失败:
授予者和被授权者具有相同的地址。
提供的
MsgTypeUrl
为空。
注意:如果授权已过期,MsgExec
消息将移除该授权。
MsgExec
当被授权者希望代表授予者执行交易时,他们必须发送 MsgExec
消息。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/authz/v1beta1/tx.proto#L52-L63
如果出现以下情况,消息处理应失败:
提供的授权未实现。
被授权者没有权限执行该交易。
授予的授权已过期。
事件
authz
模块会触发在 Protobuf 参考中定义的 proto 事件。
客户端
CLI
用户可以使用 CLI 查询和与 authz
模块进行交互。
Query
查询命令允许用户查询 authz
状态。
simd query authz --help
grants
grants
命令允许用户查询授予者和被授权者对的授权。如果设置了消息类型 URL,则仅选择该消息类型的授权。
simd query authz grants [granter-addr] [grantee-addr] [msg-type-url]? [flags]
示例:
simd query authz grants cosmos1.. cosmos1.. /cosmos.bank.v1beta1.MsgSend
示例输出:
grants:
- authorization:
'@type': /cosmos.bank.v1beta1.SendAuthorization
spend_limit:
- amount: "100"
denom: stake
expiration: "2022-01-01T00:00:00Z"
pagination: null
Transactions
tx
命令允许用户与 authz
模块进行交互。
simd tx authz --help
exec
exec
命令允许被授权者代表授予者执行交易。
simd tx authz exec [tx-json-file] --from [grantee] [flags]
示例:
simd tx authz exec tx.json --from=cosmos1..
grant
grant
命令允许授予者向被授权者授予授权。
simd tx authz grant <grantee> <authorization_type="send"|"generic"|"delegate"|"unbond"|"redelegate"> --from <granter> [flags]
示例:
simd tx authz grant cosmos1.. send --spend-limit=100stake --from=cosmos1..
revoke
revoke
命令允许授予者从被授权者那里撤销授权。
simd tx authz revoke [grantee] [msg-type-url] --from=[granter] [flags]
示例:
simd tx authz revoke cosmos1.. /cosmos.bank.v1beta1.MsgSend --from=cosmos1..
gRPC
用户可以使用 gRPC
端点查询 authz
模块。
Grants
Grants
端点允许用户查询授予者和被授权者对的授权。如果设置了消息类型 URL,则仅选择该消息类型的授权。
cosmos.authz.v1beta1.Query/Grants
示例:
grpcurl -plaintext \
-d '{"granter":"cosmos1..","grantee":"cosmos1..","msg_type_url":"/cosmos.bank.v1beta1.MsgSend"}' \
localhost:9090 \
cosmos.authz.v1beta1.Query/Grants
示例输出:
{
"grants": [
{
"authorization": {
"@type": "/cosmos.bank.v1beta1.SendAuthorization",
"spendLimit": [
{
"denom":"stake",
"amount":"100"
}
]
},
"expiration": "2022-01-01T00:00:00Z"
}
]
}
REST
用户可以使用 REST
端点查询 authz
模块。
/cosmos/authz/v1beta1/grants
示例:
curl "localhost:1317/cosmos/authz/v1beta1/grants?granter=cosmos1..&grantee=cosmos1..&msg_type_url=/cosmos.bank.v1beta1.MsgSend"
示例输出:
{
"grants": [
{
"authorization": {
"@type": "/cosmos.bank.v1beta1.SendAuthorization",
"spend_limit": [
{
"denom": "stake",
"amount": "100"
}
]
},
"expiration": "2022-01-01T00:00:00Z"
}
],
"pagination": null
}
Last updated