变更记录
- 30-09-2020:初始草案
状态
提议中摘要
账户重置密钥是一种允许账户将其认证公钥替换为新公钥的过程。背景
当前在 Cosmos SDK 中,认证BaseAccount 的地址基于公钥的哈希。一旦账户被创建,该账户的公钥就会被固定下来,无法更改。对于用户来说,这会带来问题,因为密钥轮换是一种有价值的安全实践,但目前无法实现。此外,由于多重签名本身也是一种公钥,一旦为账户设置了某个多重签名,就无法再更新。这同样存在问题,因为多重签名通常由组织或公司使用,而它们可能由于内部原因需要调整多签签名人的集合。
仅将账户的全部资产转移到一个具有更新后公钥的新账户并不足够,因为账户的一些“关联状态”并不容易转移。例如,在质押场景中,要转移已绑定的 Atom,账户必须先解除所有委托,并等待三周的解绑期。更重要的是,对于验证人运营者而言,对验证人的所有权根本不可转移,这意味着验证人的运营者密钥永远无法更新,从而导致验证人的运维安全性较差。
决策
我们提议为x/auth 增加一项新功能,使账户能够更新与自身关联的公钥,同时保持地址不变。
之所以可行,是因为 Cosmos SDK 的 BaseAccount 会在状态中存储账户的公钥,而不是像 Bitcoin 和 Ethereum 等其他区块链那样,假定公钥包含在交易中(无论是显式包含,还是通过签名隐式包含)。由于公钥存储在链上,因此即使公钥的哈希结果不等于账户地址也没有问题,因为地址与签名校验过程并无直接关系。
为构建这一系统,我们设计了如下新的 Msg 类型:
MsgChangePubKey 交易需要由当前状态中的现有公钥签名。
一旦获批,此消息类型对应的 handler 会接收 AccountKeeper,并更新账户在状态中的公钥,将其替换为 Msg 中提供的公钥。
公钥发生过变更的账户不能被自动从状态中裁剪。这是因为如果被裁剪,要重新创建相同地址就需要该账户的原始公钥,但地址所有者可能已经不再持有原始公钥。当前我们本来就不会自动裁剪任何账户,但我们希望未来仍然保留这一能力(这也是账户编号的用途)。为了解决这个问题,我们对该操作额外收取 gas 费用,以补偿这一外部性(这部分有界 gas 数量由参数 PubKeyChangeCost 配置)。这部分额外 gas 会在 handler 内通过 ConsumeGas 函数扣除。此外,未来我们还可以允许已经重置密钥的账户通过新的 Msg 类型(例如 MsgDeleteAccount)自行手动裁剪。作为激励,手动裁剪账户可以获得一定的 gas 返还。
影响
正面
- 将允许用户和验证人运营者通过密钥轮换采用更好的运维安全实践。
- 将允许组织或群组更轻松地变更多签签名人,以及添加或移除签名人。
负面
这打破了当前默认假设的地址与公钥关系,即 H(pubkey) = address。由此会带来一些后果。- 这会使支持该功能的钱包实现更加复杂。例如,如果链上的某个地址被更新,CLI 钱包中对应的密钥也需要同步更新。
- 对于那些公钥已变更且余额为 0 的账户,无法自动裁剪。
中性
- 虽然该功能的本意是让账户所有者将公钥更新为自己持有的新公钥,但从技术上讲,它也可以被用来将账户所有权转移给新的拥有者。例如,它可用于出售一个无需解绑的质押头寸,或出售一个持有归属期代币的账户。不过,这种方式的摩擦成本很高,因为这本质上必须作为一种非常特定的场外交易来完成。此外,还可以增加额外约束,禁止持有 Vesting 代币的账户使用该功能。
- 会要求在创世导出中包含账户的 PubKey。
参考资料
Changelog
- 30-09-2020: Initial Draft
Status
PROPOSEDAbstract
Account rekeying is a process hat allows an account to replace its authentication pubkey with a new one.Context
Currently, in the Cosmos SDK, the address of an authBaseAccount is based on the hash of the public key. Once an account is created, the public key for the account is set in stone, and cannot be changed. This can be a problem for users, as key rotation is a useful security practice, but is not possible currently. Furthermore, as multisigs are a type of pubkey, once a multisig for an account is set, it can not be updated. This is problematic, as multisigs are often used by organizations or companies, who may need to change their set of multisig signers for internal reasons.
Transferring all the assets of an account to a new account with the updated pubkey is not sufficient, because some “engagements” of an account are not easily transferable. For example, in staking, to transfer bonded Atoms, an account would have to unbond all delegations and wait the three week unbonding period. Even more significantly, for validator operators, ownership over a validator is not transferrable at all, meaning that the operator key for a validator can never be updated, leading to poor operational security for validators.
Decision
We propose the addition of a new feature tox/auth that allows accounts to update the public key associated with their account, while keeping the address the same.
This is possible because the Cosmos SDK BaseAccount stores the public key for an account in state, instead of making the assumption that the public key is included in the transaction (whether explicitly or implicitly through the signature) as in other blockchains such as Bitcoin and Ethereum. Because the public key is stored on chain, it is okay for the public key to not hash to the address of an account, as the address is not pertinent to the signature checking process.
To build this system, we design a new Msg type as follows:
PubKeyChangeCost). The bonus gas is charged inside the handler, using the ConsumeGas function. Furthermore, in the future, we can allow accounts that have rekeyed manually prune themselves using a new Msg type such as MsgDeleteAccount. Manually pruning accounts can give a gas refund as an incentive for performing the action.
Consequences
Positive
- Will allow users and validator operators to employ better operational security practices with key rotation.
- Will allow organizations or groups to easily change and add/remove multisig signers.
Negative
Breaks the current assumed relationship between address and pubkeys as H(pubkey) = address. This has a couple of consequences.- This makes wallets that support this feature more complicated. For example, if an address on chain was updated, the corresponding key in the CLI wallet also needs to be updated.
- Cannot automatically prune accounts with 0 balance that have had their pubkey changed.
Neutral
- While the purpose of this is intended to allow the owner of an account to update to a new pubkey they own, this could technically also be used to transfer ownership of an account to a new owner. For example, this could be use used to sell a staked position without unbonding or an account that has vesting tokens. However, the friction of this is very high as this would essentially have to be done as a very specific OTC trade. Furthermore, additional constraints could be added to prevent accouns with Vesting tokens to use this feature.
- Will require that PubKeys for an account are included in the genesis exports.