费用授权(Feegrant)
摘要
本文档指定了fee grant
模块。有关完整的ADR,请参阅Fee Grant ADR-029。
该模块允许账户授予费用授权并使用其账户中的费用。受赠者可以执行任何交易,而无需保持足够的费用。
目录
概念
授权
授权存储在KVStore中,以记录具有完整上下文的授权。每个授权将包含granter
、grantee
以及授予的费用类型。granter
是提供权限的账户地址,允许grantee
(受益账户地址)支付部分或全部交易费用。allowance
定义了授予grantee
的费用授权类型(BasicAllowance
或PeriodicAllowance
,见下文)。allowance
接受一个实现了FeeAllowanceI
接口的类型,编码为Any
类型。每个grantee
和granter
组合只能有一个现有的费用授权,不允许自我授权。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/feegrant/v1beta1/feegrant.proto#L83-L93
FeeAllowanceI
看起来像:
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/feegrant/fees.go#L9-L32
费用授权类型
目前有两种类型的费用授权:
BasicAllowance
PeriodicAllowance
AllowedMsgAllowance
BasicAllowance
BasicAllowance
是允许受赠者使用来自授权账户的费用。如果spend_limit
或expiration
达到限制,授权将从状态中移除。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/feegrant/v1beta1/feegrant.proto#L15-L28
spend_limit
是允许从授权账户使用的最大币数。如果为空,表示没有使用限制,受赠者可以在过期之前使用授权账户地址中任何数量的可用币。expiration
指定此授权过期的可选时间。如果值为空,则授权没有过期时间。创建授权时,如果
spend_limit
和expiration
为空,依然是有效授权。它不会限制受赠者使用任何数量的币,并且没有过期时间。唯一的限制受赠者的方式是撤销授权。
PeriodicAllowance
PeriodicAllowance
是针对指定时间段的重复费用授权,我们可以指定授权何时过期以及周期何时重置。还可以定义在指定时间段内可以使用的最大币数。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/feegrant/v1beta1/feegrant.proto#L34-L68
basic
是BasicAllowance
的实例,对于周期性费用授权来说是可选的。如果为空,授权将没有过期时间和使用限制。period
是特定的时间周期,在每个周期结束后,period_can_spend
将被重置。period_spend_limit
指定在该时间周期内可以使用的最大币数。period_can_spend
是在period_reset
时间之前,剩余可支出的币数。
AllowedMsgAllowance
AllowedMsgAllowance
是一种费用授权,它可以是 BasicFeeAllowance
或 PeriodicAllowance
,但仅限于授权者所指定的允许消息。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/feegrant/v1beta1/feegrant.proto#L70-L81
allowance
是BasicAllowance
或PeriodicAllowance
。allowed_messages
是允许执行给定授权的消息数组。
FeeGranter 标志
feegrant
模块为CLI引入了 FeeGranter
标志,用于执行带有费用授权者的交易。当设置此标志时,clientCtx
将为通过CLI生成的交易附加授权账户地址。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/client/cmd.go#L249-L260
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/client/tx/tx.go#L109-L109
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/auth/tx/builder.go#L275-L284
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/tx/v1beta1/tx.proto#L203-L224
Example cmd:
./simd tx gov submit-proposal --title="Test Proposal" --description="My awesome proposal" --type="Text" --from validator-key --fee-granter=cosmos1xh44hxt7spr67hqaa7nyx5gnutrz5fraw6grxn --chain-id=testnet --fees="10stake"
授权费用扣除
费用在 x/auth
ante 处理程序中从授权中扣除。要了解更多关于 ante 处理程序的工作原理,请阅读 Auth Module AnteHandlers Guide
。
Gas
为了防止DoS攻击,使用过滤后的 x/feegrant
会产生 gas 费用。SDK必须确保受赠者的交易符合授权者设置的过滤器。SDK通过迭代过滤器中的允许消息,并为每个过滤消息收取10 gas。然后,SDK会迭代受赠者发送的消息,确保这些消息符合过滤器,并且对每条消息收取10 gas。如果SDK发现一条不符合过滤器的消息,它将停止迭代并使交易失败。
警告: gas 将从授予的授权中扣除。确保您的消息符合过滤器(如果有),然后再使用您的授权发送交易。
修剪
在状态中维护一个队列,该队列以授权过期时间的前缀存储,并在每个区块的EndBlock
时使用当前区块时间进行检查,以便修剪过期的授权。
状态
FeeAllowance
费用授权通过将受赠者(grantee
,即费用授权受赠者的账户地址)与授权者(granter
,即费用授权授权者的账户地址)组合来标识。
费用授权存储在状态中,如下所示:
Grant:
0x00 | grantee_addr_len (1 byte) | grantee_addr_bytes | granter_addr_len (1 byte) | granter_addr_bytes -> ProtocolBuffer(Grant)
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/feegrant/feegrant.pb.go#L222-L230
FeeAllowanceQueue
费用授权队列项通过将 FeeAllowancePrefixQueue
(即 0x01
)、过期时间、受赠者(grantee
,费用授权受赠者的账户地址)和授权者(granter
,费用授权授权者的账户地址)组合来标识。EndBlocker
会检查 FeeAllowanceQueue
状态中的过期授权,并将其从 FeeAllowance
中修剪(如果发现有过期授权)。
费用授权队列键的存储方式如下:
Grant:
0x01 | expiration_bytes | grantee_addr_len (1 byte) | grantee_addr_bytes | granter_addr_len (1 byte) | granter_addr_bytes -> EmptyBytes
消息
Msg/GrantAllowance
费用授权将通过 MsgGrantAllowance
消息创建。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/feegrant/v1beta1/tx.proto#L25-L39
Msg/RevokeAllowance
允许的授权费用可以通过 MsgRevokeAllowance
消息移除。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/feegrant/v1beta1/tx.proto#L41-L54
事件
feegrant
模块会触发以下事件:
Msg Server
MsgGrantAllowance
message
action
set_feegrant
message
granter
{granterAddress}
message
grantee
{granteeAddress}
MsgRevokeAllowance
message
action
revoke_feegrant
message
granter
{granterAddress}
message
grantee
{granteeAddress}
Exec fee allowance
message
action
use_feegrant
message
granter
{granterAddress}
message
grantee
{granteeAddress}
Prune fee allowances
message
action
prune_feegrant
message
pruner
{prunerAddress}
客户端
CLI
用户可以使用CLI查询和与feegrant
模块进行交互。
Query
查询命令允许用户查询feegrant
状态。
simd query feegrant --help
grant
grant
命令允许用户查询给定授权者-受赠者对的授权。
simd query feegrant grant [granter] [grantee] [flags]
示例:
simd query feegrant grant cosmos1.. cosmos1..
示例输出:
allowance:
'@type': /cosmos.feegrant.v1beta1.BasicAllowance
expiration: null
spend_limit:
- amount: "100"
denom: stake
grantee: cosmos1..
granter: cosmos1..
grants
grants
命令允许用户查询给定受赠者的所有授权。
simd query feegrant grants [grantee] [flags]
示例:
simd query feegrant grants cosmos1..
示例输出:
allowances:
- allowance:
'@type': /cosmos.feegrant.v1beta1.BasicAllowance
expiration: null
spend_limit:
- amount: "100"
denom: stake
grantee: cosmos1..
granter: cosmos1..
pagination:
next_key: null
total: "0"
Transactions
tx
命令允许用户与feegrant
模块进行交互。
simd tx feegrant --help
grant
grant
命令允许用户向另一个账户授予费用授权。费用授权可以具有过期日期、总支出限制和/或周期性支出限制。
simd tx feegrant grant [granter] [grantee] [flags]
示例(一次性支出限制):
simd tx feegrant grant cosmos1.. cosmos1.. --spend-limit 100stake
示例(周期性支出限制:
simd tx feegrant grant cosmos1.. cosmos1.. --period 3600 --period-limit 10stake
revoke
revoke
命令允许用户撤销已授予的费用授权。
simd tx feegrant revoke [granter] [grantee] [flags]
示例:
simd tx feegrant revoke cosmos1.. cosmos1..
gRPC
用户可以使用 gRPC 端点查询 feegrant
模块。
Allowance
Allowance
端点允许用户查询已授予的费用授权。
cosmos.feegrant.v1beta1.Query/Allowance
示例:
grpcurl -plaintext \
-d '{"grantee":"cosmos1..","granter":"cosmos1.."}' \
localhost:9090 \
cosmos.feegrant.v1beta1.Query/Allowance
示例输出:
{
"allowance": {
"granter": "cosmos1..",
"grantee": "cosmos1..",
"allowance": {"@type":"/cosmos.feegrant.v1beta1.BasicAllowance","spendLimit":[{"denom":"stake","amount":"100"}]}
}
}
Allowances
Allowances
端点允许用户查询给定受赠者的所有已授予的费用授权。
cosmos.feegrant.v1beta1.Query/Allowances
示例:
grpcurl -plaintext \
-d '{"address":"cosmos1.."}' \
localhost:9090 \
cosmos.feegrant.v1beta1.Query/Allowances
示例输出:
{
"allowances": [
{
"granter": "cosmos1..",
"grantee": "cosmos1..",
"allowance": {"@type":"/cosmos.feegrant.v1beta1.BasicAllowance","spendLimit":[{"denom":"stake","amount":"100"}]}
}
],
"pagination": {
"total": "1"
}
}
Last updated