治理(Gov)

摘要

本文指定了 Cosmos SDK 的治理模块,该模块首次在 2016 年 6 月的 Cosmos 白皮书中描述。 该模块使基于 Cosmos SDK 的区块链支持链上治理系统。在此系统中,链的原生质押代币持有者可以基于 1 代币 1 投票的原则对提案进行投票。以下是该模块当前支持的功能列表:

  • 提案提交: 用户可以提交带有押金的提案。一旦达到最低押金,提案将进入投票期。最低押金可以通过在押金期内收集来自不同用户(包括提案人)的押金来达成。

  • 投票: 参与者可以对已达到最低押金并进入投票期的提案进行投票。

  • 继承与惩罚: 如果委托人没有投票,他们将继承其验证人的投票。

  • 领取押金: 对提案进行押金的用户可以在提案被接受或拒绝后取回押金。如果提案被否决,或未进入投票期(在押金期内未达到最低押金),则押金将被销毁。

该模块已在 Cosmos Hub(即 Gaia)上使用。未来可能添加的功能将在“未来改进”中描述。

目录

以下规范使用 ATOM 作为原生质押代币。通过将 ATOM 替换为链的原生质押代币,该模块可以适配任何权益证明(Proof-Of-Stake)区块链。

概念

免责声明:这项工作仍在进行中,机制可能会发生变化。

治理过程分为几个步骤,具体如下:

  • 提案提交: 提案通过存入押金提交到区块链。

  • 投票: 一旦押金达到一定值(MinDeposit),提案将被确认并开始投票。持有质押的 Atom 的用户可以通过发送 TxGovVote 交易来对提案进行投票。

  • 执行: 在一段时间后,投票结果将被统计,根据结果,提案中的消息将被执行。

提案提交

提交提案的权利

每个账户都可以通过发送 MsgSubmitProposal 交易来提交提案。一旦提案提交,它将通过唯一的 proposalID 进行标识。

提案消息

提案包括一个 sdk.Msgs 数组,这些消息在提案通过后会自动执行。消息由治理 ModuleAccount 本身执行。诸如 x/upgrade 等模块,如果希望某些消息仅由治理执行,应在相应的消息服务器中添加白名单,允许治理模块在达到法定人数后执行这些消息。治理模块使用 MsgServiceRouter 来检查这些消息是否正确构造并具有相应的执行路径,但不会执行完整的有效性检查。

押金

为了防止垃圾信息,提案必须提交时附带由 MinDeposit 参数定义的押金。 当提案提交时,必须附带一个严格为正数的押金,但可以低于 MinDeposit。提案提交者不需要单独支付整个押金。新创建的提案将存储在一个非活动提案队列中,并保持在该队列中,直到其押金超过 MinDeposit。其他代币持有者可以通过发送 Deposit 交易来增加提案的押金。如果提案在押金结束时间(即不再接受押金的时间)之前没有达到 MinDeposit,则提案将被销毁:提案将从状态中删除,押金将被销毁(见 x/gov EndBlocker)。当提案押金在押金结束时间之前(即使在提案提交时)超过 MinDeposit 阈值时,提案将移入活动提案队列并开始投票期。

押金将被保存在托管账户中,并由治理 ModuleAccount 持有,直到提案被最终确认(通过或拒绝)。

押金退款与销毁

当提案最终确定时,押金的币会根据提案的最终计票结果进行退款或销毁:

  • 如果提案被通过或拒绝但未被否决,每个押金将自动退还给各自的存款者(从治理 ModuleAccount 转账)。

  • 当提案被否决且否决票超过三分之一时,押金将从治理 ModuleAccount 中销毁,提案信息及其押金信息将从状态中移除。

  • 所有退款或销毁的押金都将从状态中移除。在销毁或退款押金时,将触发事件。

投票

参与者

参与者是有权对提案投票的用户。在 Cosmos Hub 上,参与者是绑定的 Atom 持有者。未绑定的 Atom 持有者和其他用户无权参与治理,但可以提交和存入提案。 请注意,当参与者同时持有绑定和未绑定的 Atom 时,他们的投票权仅根据绑定的 Atom 数量来计算

投票期

Once a proposal reaches MinDeposit, it immediately enters Voting period. We define 一旦提案达到 MinDeposit,它将立即进入投票期。我们将投票期定义为从投票开始到投票结束的时间间隔。投票期的初始值为 2 周。

选项集

提案的选项集是指参与者在投票时可以选择的选项集。 初始的选项集包括以下选项:

  • Yes

  • No

  • NoWithVeto

  • Abstain

NoWithVeto 计作 No,但同时也附加一个否决投票。Abstain 选项允许选民表示他们既不打算支持也不打算反对提案,但接受投票结果。 备注:在 UI 中,对于紧急提案,我们也许应该添加一个“非紧急”选项,这样可以投出 NoWithVeto 投票。

加权投票

ADR-037 引入了加权投票功能,允许质押者将他们的投票分配到多个选项上。例如,他们可以用 70% 的投票权投票支持(Yes),用 30% 的投票权投票反对(No)。 通常,拥有该地址的实体可能不是单一的个人。例如,一家公司可能有不同的利益相关者希望投出不同的票,因此允许他们分配投票权是有意义的。目前,他们不能进行“透传投票”,即允许他们的用户对他们的代币进行投票。然而,使用此系统,交易所可以根据用户的投票偏好进行投票,然后按投票结果在链上按比例投票。

为了在链上表示加权投票,我们使用以下 Protobuf 消息。

https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1beta1/gov.proto#L34-L47
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1beta1/gov.proto#L181-L201

为了使加权投票有效,options 字段中不得包含重复的投票选项,所有选项的权重之和必须等于 1。

法定人数

法定人数定义为为了使提案结果有效,必须对其进行投票的最小投票权比例。

加速提案

可以加速提案,使提案使用更短的投票时长和默认更高的计票阈值。如果加速提案未能在较短的投票时长内满足阈值,则该提案将转换为常规提案,并在常规投票条件下重新开始投票。

阈值

阈值定义为提案接受所需的最小支持票比例(不包括弃权票)。 最初,阈值设置为 50% 的支持票,排除弃权票。如果超过 1/3 的所有投票为否决票(NoWithVeto),则存在否决的可能。注意,这两个值都来自链上的 TallyParams 参数,且可以由治理修改。这意味着,提案只有在以下条件都满足时才会被接受:

  • 存在质押的 tokens。

  • 法定人数已达到。

  • 弃权票的比例低于 1/1。

  • 否决票的比例低于 1/3(包括弃权票)。

  • 在投票结束时,支持票的比例(不包括弃权票)超过 1/2。

对于加速提案,默认情况下,阈值高于常规提案,即为 66.7%。

继承

如果委托人未投票,则会继承其验证人的投票。

  • 如果委托人在验证人之前投票,则不会继承验证人的投票。

  • 如果委托人在验证人之后投票,则会用自己的投票覆盖验证人的投票。如果提案是紧急的,可能会在委托人有机会反应并覆盖验证人的投票之前,投票就已经结束。对此没有问题,因为提案需要超过 2/3 的总投票权才能通过,在投票期结束时进行统计。因为即使只有 1/3 + 1 的验证人投票权也可能合谋来审查交易,已经假设这些范围超过此阈值时不存在合谋。

验证人未投票的惩罚

目前,验证人未投票不会受到惩罚。

治理地址

以后可能会添加只能由某些模块签名交易的权限密钥。对于 MVP,治理地址将是创建账户时生成的主要验证人地址。该地址对应的 PrivKey 与负责签署共识消息的 CometBFT PrivKey 不同。因此,验证人无需使用敏感的 CometBFT PrivKey 来签署治理交易。

可销毁参数

有三个参数定义了提案的存款是否应当被销毁或退还给存款人:

  • BurnVoteVeto:如果提案被否决,则销毁提案存款。

  • BurnVoteQuorum:如果提案投票未达到法定人数,则销毁提案存款。

  • BurnProposalDepositPrevote:如果提案未进入投票阶段,则销毁提案存款。

Note: 这些参数可以通过治理进行修改。

状态

宪法(Constitution)

宪法存储在创世状态中。它是一个字符串字段,旨在描述特定区块链的目的及其预期规范。以下是一些宪法字段可能的使用方式示例:

  • 定义链的目的,为未来的发展奠定基础。

  • 设置委托人的预期。

  • 设置验证人的预期。

  • 定义链与“物理世界”实体(如基金会或公司)之间的关系。

由于这是一个更偏向于社会功能而非技术功能的特性,我们接下来将讨论一些在创世宪法中可能有用的项目:

  • 是否存在对治理的限制?

    • 如果社区决定不再希望某个“大户”存在,是否可以通过治理削减其钱包?(例如:Juno 提案 4 和 16)

    • 治理是否可以“社会性地削减”使用未经批准的 MEV(最大可提取价值)的验证人?(例如:commonwealth.im/osmosis)

    • 在经济紧急情况下,验证人应该做什么?

      • 2022年5月的 Terra 崩盘中,验证人选择运行一个未经治理批准的新二进制文件,因为治理代币已经被通货膨胀到几乎无价值。

  • 链的具体目的是什么?

    • 最好的例子是 Cosmos Hub,其中不同的创始团队对网络的目的有不同的解释。

这个创世条目“宪法”并不是为现有链设计的,现有链可能只需要通过它们的治理系统批准一份宪法。相反,这主要是为新链设计的。它将使验证人在操作节点时有一个更清晰的目的和期望。同样,对于社区成员来说,宪法将为他们提供一些关于“链团队”和验证人预期的指导。

这个宪法设计为不可变,仅在创世文件中存在,但随着时间的推移,可能会通过向 Cosmos SDK 提交拉取请求来改变,允许通过治理来修改宪法。希望修改原始宪法的社区应使用治理机制并通过“信号提案”来进行修改。

Cosmos 链宪法的理想使用场景

作为链的开发者,你决定为关键用户群体提供清晰的指导:

  • 验证人

  • 代币持有者

  • 开发者(包括你自己)

你使用宪法在创世文件中不可变地存储一些 Markdown 内容,以便在遇到困难问题时,宪法可以为社区提供指导。

提案(Proposals)

Proposal 对象用于统计投票结果,并跟踪提案的整体状态。它们包含一个任意 sdk.Msg 数组,Governance 模块会尝试解析并在提案通过后执行这些消息。

Proposal 通过唯一 id 进行标识,并包含一系列时间戳,以跟踪提案的生命周:submit_time:提交时间。deposit_end_time:存款截止时间。voting_start_time:投票开始时间。voting_end_time:投票结束时间。

https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L51-L99

一个提案通常需要的不仅仅是一组消息来解释其目的,还需要更深入的论证,并提供一个让相关参与者讨论和辩论的渠道。因此,大多数情况下,建议采用支持链上治理流程的链下系统。

为了适应这一需求,Proposal 包含一个特殊的 metadata 字段,该字段是一个字符串,可用于为提案添加背景信息。metadata 字段允许不同的网络自定义使用方式,但通常该字段应包含一个 URL,或使用 IPFS 等系统的 CID(内容标识符)。

为了支持跨网络的互操作性,SDK 建议 metadata 采用以下 JSON 模板格式:

{
  "title": "...",
  "description": "...",
  "forum": "...", // a link to the discussion platform (i.e. Discord)
  "other": "..." // any extra data that doesn't correspond to the other fields
}

这样可以更方便地支持多个网络。

metadata 的最大长度由应用开发者决定,并作为配置参数传递给 gov keeper。在 SDK 中,默认的最大长度为 255 个字符。

编写使用 Governance 的模块

在区块链或各个模块中,可能会有许多需要通过 Governance 进行管理的方面,例如更改各种参数。这一过程相对简单:编写消息类型 (message types) 和 MsgServer 实现。在 keeper 中添加 authority 字段,并在构造函数中用 governance module account 进行初始化:goCopyEditgovKeeper.GetGovernanceAccount().GetAddress()。在 msg_server.go 方法中,检查消息的签名者是否与 authority 匹配,以防止未经授权的用户执行该消息。

参数和基础类型

Parameters(参数)定义了投票运行的规则。在任何时间点,系统只能有一个 Active Parameter Set(活动参数集)。如果 Governance 需要更改参数集(无论是修改参数值,还是添加/删除参数字段),则必须创建一个新的 Parameter Set,并将之前的参数集设为 Inactive(非活动)。

DepositParams

https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L152-L162

VotingParams

https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L164-L168

TallyParams

https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L170-L182

参数存储在全局 GlobalParams KVStore 中。

此外,我们引入了一些基础类型:

type Vote byte

const (
    VoteYes         = 0x1
    VoteNo          = 0x2
    VoteNoWithVeto  = 0x3
    VoteAbstain     = 0x4
)

type ProposalType  string

const (
    ProposalTypePlainText       = "Text"
    ProposalTypeSoftwareUpgrade = "SoftwareUpgrade"
)

type ProposalStatus byte


const (
    StatusNil           ProposalStatus = 0x00
    StatusDepositPeriod ProposalStatus = 0x01  // Proposal is submitted. Participants can deposit on it but not vote
    StatusVotingPeriod  ProposalStatus = 0x02  // MinDeposit is reached, participants can vote
    StatusPassed        ProposalStatus = 0x03  // Proposal passed and successfully executed
    StatusRejected      ProposalStatus = 0x04  // Proposal has been rejected
    StatusFailed        ProposalStatus = 0x05  // Proposal passed but failed execution
)

Deposit

https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L38-L49

ValidatorGovInfo

此类型在计票时用于临时映射。

  type ValidatorGovInfo struct {
    Minus     sdk.Dec
    Vote      Vote
  }

存储

:::note Storesmulti-store 中的 KVStores。用于查找存储的键是列表中的第一个参数。:::

我们将使用一个 KVStore Governance 来存储四种映射关系:

  • proposalID|'proposal' 映射到 Proposal

  • proposalID|'addresses'|address 映射到 Vote。此映射允许我们通过对 proposalID:addresses 进行范围查询,以获取所有对该提案投票的地址及其投票内容。

  • ParamsKey|'Params' 映射到 Params。此映射允许查询所有 x/gov 参数。

  • VotingPeriodProposalKeyPrefix|proposalID 映射到单个字节。此映射以极低的 gas 成本判断某个提案是否处于投票期。

为了便于伪代码描述,以下是用于在存储中读写的两个函数:

  • load(StoreKey, Key): 在 multi-store 中,查找 StoreKey 处的 store,并检索存储在 Key 处的项目。

  • store(StoreKey, Key, Value): 在 multi-store 中,查找 StoreKey 处的 store,并将 Value 写入 Key 处。

提案处理队列

存储:

  • ProposalProcessingQueue:一个队列 queue[proposalID],其中包含所有已达到 MinDepositProposalID。在每个 EndBlock 期间,所有投票期已结束的提案都会被处理。处理已完成的提案时,应用程序会:统计投票结果。计算每个验证人的投票。检查验证人集合中的所有验证人是否已投票。如果提案被接受,则退还 deposit。执行提案的 content Handler

ProposalProcessingQueue 的伪代码:

  in EndBlock do

    for finishedProposalID in GetAllFinishedProposalIDs(block.Time)
      proposal = load(Governance, <proposalID|'proposal'>) // proposal is a const key

      validators = Keeper.getAllValidators()
      tmpValMap := map(sdk.AccAddress)ValidatorGovInfo

      // Initiate mapping at 0. This is the amount of shares of the validator's vote that will be overridden by their delegator's votes
      for each validator in validators
        tmpValMap(validator.OperatorAddr).Minus = 0

      // Tally
      voterIterator = rangeQuery(Governance, <proposalID|'addresses'>) //return all the addresses that voted on the proposal
      for each (voterAddress, vote) in voterIterator
        delegations = stakingKeeper.getDelegations(voterAddress) // get all delegations for current voter

        for each delegation in delegations
          // make sure delegation.Shares does NOT include shares being unbonded
          tmpValMap(delegation.ValidatorAddr).Minus += delegation.Shares
          proposal.updateTally(vote, delegation.Shares)

        _, isVal = stakingKeeper.getValidator(voterAddress)
        if (isVal)
          tmpValMap(voterAddress).Vote = vote

      tallyingParam = load(GlobalParams, 'TallyingParam')

      // Update tally if validator voted
      for each validator in validators
        if tmpValMap(validator).HasVoted
          proposal.updateTally(tmpValMap(validator).Vote, (validator.TotalShares - tmpValMap(validator).Minus))



      // Check if proposal is accepted or rejected
      totalNonAbstain := proposal.YesVotes + proposal.NoVotes + proposal.NoWithVetoVotes
      if (proposal.Votes.YesVotes/totalNonAbstain > tallyingParam.Threshold AND proposal.Votes.NoWithVetoVotes/totalNonAbstain  < tallyingParam.Veto)
        //  proposal was accepted at the end of the voting period
        //  refund deposits (non-voters already punished)
        for each (amount, depositor) in proposal.Deposits
          depositor.AtomBalance += amount

        stateWriter, err := proposal.Handler()
        if err != nil
            // proposal passed but failed during state execution
            proposal.CurrentStatus = ProposalStatusFailed
         else
            // proposal pass and state is persisted
            proposal.CurrentStatus = ProposalStatusAccepted
            stateWriter.save()
      else
        // proposal was rejected
        proposal.CurrentStatus = ProposalStatusRejected

      store(Governance, <proposalID|'proposal'>, proposal)

旧版提案(Legacy Proposal)

:::warnin 旧版提案已被弃用。请使用新的提案流程,并授予治理模块执行消息的权限。 :::

Legacy Proposal 是治理提案的旧实现方式。与可以包含任意消息的现代 Proposal 相比,Legacy Proposal 仅允许提交一组预定义的提案类型。这些提案由特定类型定义,并由 gov v1beta1 路由器中注册的处理程序(Handlers)处理。

有关如何在客户端部分提交提案的更多信息,请参阅 Client 章节

消息

提案提交

任何账户都可以通过 MsgSubmitProposal 交易提交提案。

https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/tx.proto#L42-L69

所有传递到 MsgSubmitProposal 消息的 sdk.Msgs 必须在应用的 MsgServiceRouter 中注册。这些消息必须有一个签名者,即 gov 模块账户。最后,metadata 的长度不得超过传递给 gov keeper 的 maxMetadataLen 配置值。initialDeposit 必须是严格正数,并符合 MinDeposit 参数的接受 denom。

状态修改:

  1. 生成新的 proposalID

  2. 创建新的 Proposal

  3. 初始化 Proposal 的属性。

  4. 从发送者账户减少 InitialDeposit 的余额。

  5. 如果达到了 MinDeposit

    • proposalID 推送到 ProposalProcessingQueue

  6. InitialDeposit 从提案者转移到治理模块账户 ModuleAccount

存款

一旦提案提交,如果 Proposal.TotalDeposit 小于 ActiveParam.MinDeposit,ATOM 持有者可以通过发送 MsgDeposit 交易来增加提案的存款。 存款被接受的条件是:

  • 提案存在

  • 提案不在投票期间

  • 存入的硬币符合 MinDeposit 参数接受的 denom

https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/tx.proto#L134-L147

状态修改:

  1. 减少发送者的余额,扣除存款金额

  2. 将发送者的存款添加到 proposal.Deposits

  3. 增加 proposal.TotalDeposit,加入发送者的存款

  4. 如果达到了 MinDeposit

    • proposalID 推送到 ProposalProcessingQueueEnd

  5. 将存款从提案者转移到治理模块账户 ModuleAccount

投票

一旦达到了 ActiveParam.MinDeposit,投票期开始。从此,已绑定的 Atom 持有者可以发送 MsgVote 交易,对提案进行投票。

https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/tx.proto#L92-L108

状态修改

  • 记录发送者的投票

:::note 该消息的燃气费用必须考虑到在 EndBlocker 中对投票的后续统计。:::

事件

治理模块会触发以下事件:

EndBlocker

类型
属性键
属性值

inactive_proposal

proposal_id

{proposalID}

inactive_proposal

proposal_result

{proposalResult}

active_proposal

proposal_id

{proposalID}

active_proposal

proposal_result

{proposalResult}

Handlers

MsgSubmitProposal

类型
属性键
属性值

submit_proposal

proposal_id

{proposalID}

submit_proposal [0]

voting_period_start

{proposalID}

proposal_deposit

amount

{depositAmount}

proposal_deposit

proposal_id

{proposalID}

message

module

governance

message

action

submit_proposal

message

sender

{senderAddress}

  • [0] 仅当投票期在提交过程中开始时,才会触发该事件。

MsgVote

类型
属性键
属性值

proposal_vote

option

{voteOption}

proposal_vote

proposal_id

{proposalID}

message

module

governance

message

action

vote

message

sender

{senderAddress}

MsgVoteWeighted

类型
属性键
属性值

proposal_vote

option

{weightedVoteOptions}

proposal_vote

proposal_id

{proposalID}

message

module

governance

message

action

vote

message

sender

{senderAddress}

MsgDeposit

类型
属性键
属性值

proposal_deposit

amount

{depositAmount}

proposal_deposit

proposal_id

{proposalID}

proposal_deposit [0]

voting_period_start

{proposalID}

message

module

governance

message

action

deposit

message

sender

{senderAddress}

  • [0] 只有在提交过程中投票期开始时,才会触发该事件。

参数

治理模块包含以下参数:

类型
示例

min_deposit

array (coins)

[{"denom":"uatom","amount":"10000000"}]

max_deposit_period

string (time ns)

"172800000000000" (17280s)

voting_period

string (time ns)

"172800000000000" (17280s)

quorum

string (dec)

"0.334000000000000000"

threshold

string (dec)

"0.500000000000000000"

veto

string (dec)

"0.334000000000000000"

expedited_threshold

string (time ns)

"0.667000000000000000"

expedited_voting_period

string (time ns)

"86400000000000" (8600s)

expedited_min_deposit

array (coins)

[{"denom":"uatom","amount":"50000000"}]

burn_proposal_deposit_prevote

bool

false

burn_vote_quorum

bool

false

burn_vote_veto

bool

true

min_initial_deposit_ratio

string

"0.1"

NOTE: 治理模块包含与其他模块不同的对象类型参数。如果只希望更改部分参数,只需要包含这些参数,而不必包含整个参数对象结构。

客户端

CLI

用户可以使用CLI查询和与gov模块交互。

Query

查询命令允许用户查询 gov 状态。

simd query gov --help

deposit

deposit 命令允许用户查询来自特定存款人的特定提案的存款。

simd query gov deposit [proposal-id] [depositer-addr] [flags]

示例:

simd query gov deposit 1 cosmos1..

示例输出:

amount:
- amount: "100"
  denom: stake
depositor: cosmos1..
proposal_id: "1"

deposits

The deposits 命令允许用户查询特定提案的所有存款。

simd query gov deposits [proposal-id] [flags]

示例:

simd query gov deposits 1

示例输出:

deposits:
- amount:
  - amount: "100"
    denom: stake
  depositor: cosmos1..
  proposal_id: "1"
pagination:
  next_key: null
  total: "0"

param

param 命令允许用户查询 gov 模块的特定参数。

simd query gov param [param-type] [flags]

示例:

simd query gov param voting

示例输出:

voting_period: "172800000000000"

params

params 命令允许用户查询 gov 模块的所有参数。

simd query gov params [flags]

示例:

simd query gov params

示例输出:

deposit_params:
  max_deposit_period: 172800s
  min_deposit:
  - amount: "10000000"
    denom: stake
params:
  expedited_min_deposit:
  - amount: "50000000"
    denom: stake
  expedited_threshold: "0.670000000000000000"
  expedited_voting_period: 86400s
  max_deposit_period: 172800s
  min_deposit:
  - amount: "10000000"
    denom: stake
  min_initial_deposit_ratio: "0.000000000000000000"
  proposal_cancel_burn_rate: "0.500000000000000000"
  quorum: "0.334000000000000000"
  threshold: "0.500000000000000000"
  veto_threshold: "0.334000000000000000"
  voting_period: 172800s
tally_params:
  quorum: "0.334000000000000000"
  threshold: "0.500000000000000000"
  veto_threshold: "0.334000000000000000"
voting_params:
  voting_period: 172800s

proposal

proposal 命令允许用户查询指定的提案。

simd query gov proposal [proposal-id] [flags]

示例:

simd query gov proposal 1

示例输出:

deposit_end_time: "2022-03-30T11:50:20.819676256Z"
final_tally_result:
  abstain_count: "0"
  no_count: "0"
  no_with_veto_count: "0"
  yes_count: "0"
id: "1"
messages:
- '@type': /cosmos.bank.v1beta1.MsgSend
  amount:
  - amount: "10"
    denom: stake
  from_address: cosmos1..
  to_address: cosmos1..
metadata: AQ==
status: PROPOSAL_STATUS_DEPOSIT_PERIOD
submit_time: "2022-03-28T11:50:20.819676256Z"
total_deposit:
- amount: "10"
  denom: stake
voting_end_time: null
voting_start_time: null

proposals

proposals 命令允许用户查询所有提案,并可选择使用过滤器进行筛选。

simd query gov proposals [flags]

示例:

simd query gov proposals

示例输出:

pagination:
  next_key: null
  total: "0"
proposals:
- deposit_end_time: "2022-03-30T11:50:20.819676256Z"
  final_tally_result:
    abstain_count: "0"
    no_count: "0"
    no_with_veto_count: "0"
    yes_count: "0"
  id: "1"
  messages:
  - '@type': /cosmos.bank.v1beta1.MsgSend
    amount:
    - amount: "10"
      denom: stake
    from_address: cosmos1..
    to_address: cosmos1..
  metadata: AQ==
  status: PROPOSAL_STATUS_DEPOSIT_PERIOD
  submit_time: "2022-03-28T11:50:20.819676256Z"
  total_deposit:
  - amount: "10"
    denom: stake
  voting_end_time: null
  voting_start_time: null
- deposit_end_time: "2022-03-30T14:02:41.165025015Z"
  final_tally_result:
    abstain_count: "0"
    no_count: "0"
    no_with_veto_count: "0"
    yes_count: "0"
  id: "2"
  messages:
  - '@type': /cosmos.bank.v1beta1.MsgSend
    amount:
    - amount: "10"
      denom: stake
    from_address: cosmos1..
    to_address: cosmos1..
  metadata: AQ==
  status: PROPOSAL_STATUS_DEPOSIT_PERIOD
  submit_time: "2022-03-28T14:02:41.165025015Z"
  total_deposit:
  - amount: "10"
    denom: stake
  voting_end_time: null
  voting_start_time: null

proposer

proposer 命令允许用户查询特定提案的提案人。

simd query gov proposer [proposal-id] [flags]

示例:

simd query gov proposer 1

示例输出:

proposal_id: "1"
proposer: cosmos1..

tally

tally 命令允许用户查询特定提案投票的计票结果。

simd query gov tally [proposal-id] [flags]

示例:

simd query gov tally 1

示例输出:

abstain: "0"
"no": "0"
no_with_veto: "0"
"yes": "1"

vote

vote 命令允许用户查询特定提案的投票记录。

simd query gov vote [proposal-id] [voter-addr] [flags]

示例:

simd query gov vote 1 cosmos1..

示例输出:

option: VOTE_OPTION_YES
options:
- option: VOTE_OPTION_YES
  weight: "1.000000000000000000"
proposal_id: "1"
voter: cosmos1..

votes

votes 命令允许用户查询特定提案的所有投票记录。

simd query gov votes [proposal-id] [flags]

示例:

simd query gov votes 1

示例输出:

pagination:
  next_key: null
  total: "0"
votes:
- option: VOTE_OPTION_YES
  options:
  - option: VOTE_OPTION_YES
    weight: "1.000000000000000000"
  proposal_id: "1"
  voter: cosmos1..

Transactions

tx 命令允许用户与 gov 模块交互。

simd tx gov --help

deposit

deposit 命令允许用户为指定提案存入代币。

simd tx gov deposit [proposal-id] [deposit] [flags]

示例:

simd tx gov deposit 1 10000000stake --from cosmos1..

draft-proposal

draft-proposal 命令允许用户起草任意类型的提案。该命令会生成一个 draft_proposal.json 文件,用户可在完善后通过 submit-proposal 提交。此外,draft_metadata.json 文件应上传至 IPFS 以提供元数据支持。

simd tx gov draft-proposal

submit-proposal

submit-proposal 命令允许用户提交一个治理提案,并附带一些消息和元数据。消息、元数据和存款信息都在一个 JSON 文件中定义。

simd tx gov submit-proposal [path-to-proposal-json] [flags]

示例:

simd tx gov submit-proposal /path/to/proposal.json --from cosmos1..

proposal.json 文件包含以下内容:

{
  "messages": [
    {
      "@type": "/cosmos.bank.v1beta1.MsgSend",
      "from_address": "cosmos1...", // The gov module module address
      "to_address": "cosmos1...",
      "amount":[{"denom": "stake","amount": "10"}]
    }
  ],
  "metadata": "AQ==",
  "deposit": "10stake",
  "title": "Proposal Title",
  "summary": "Proposal Summary"
}

:::note 默认情况下,metadatasummarytitle 的字符限制为 255 个字符,但可以通过应用程序开发者进行覆盖。 :::

:::tip 当未指定 metadata 时,title 的字符限制为 255 个字符,而 summary 的字符数限制为 title 长度的 40 倍。 :::

submit-legacy-proposal

submit-legacy-proposal 命令允许用户提交治理遗留提案,并附带初始存款。

simd tx gov submit-legacy-proposal [command] [flags]

示例:

simd tx gov submit-legacy-proposal --title="Test Proposal" --description="testing" --type="Text" --deposit="100000000stake" --from cosmos1..

示例 (param-change):

simd tx gov submit-legacy-proposal param-change proposal.json --from cosmos1..
{
  "title": "Test Proposal",
  "description": "testing, testing, 1, 2, 3",
  "changes": [
    {
      "subspace": "staking",
      "key": "MaxValidators",
      "value": 100
    }
  ],
  "deposit": "10000000stake"
}

cancel-proposal

一旦提案被取消,从提案的存款中,deposits * proposal_cancel_ratio 将被销毁或发送到 ProposalCancelDest 地址。如果 ProposalCancelDest 为空,则存款将被销毁。剩余的存款将返回给存款人。

simd tx gov cancel-proposal [proposal-id] [flags]

示例:

simd tx gov cancel-proposal 1 --from cosmos1...

vote

vote 命令允许用户对给定的治理提案提交投票。

simd tx gov vote [command] [flags]

示例:

simd tx gov vote 1 yes --from cosmos1..

weighted-vote

weighted-vote 命令允许用户对给定的治理提案提交加权投票。

simd tx gov weighted-vote [proposal-id] [weighted-options] [flags]

示例:

simd tx gov weighted-vote 1 yes=0.5,no=0.5 --from cosmos1..

gRPC

用户可以使用 gRPC 端点查询 gov 模块。

Proposal

TProposal 端点允许用户查询给定的提案。 使用遗留的 v1beta1:

cosmos.gov.v1beta1.Query/Proposal

示例:

grpcurl -plaintext \
    -d '{"proposal_id":"1"}' \
    localhost:9090 \
    cosmos.gov.v1beta1.Query/Proposal

示例输出:

{
  "proposal": {
    "proposalId": "1",
    "content": {"@type":"/cosmos.gov.v1beta1.TextProposal","description":"testing, testing, 1, 2, 3","title":"Test Proposal"},
    "status": "PROPOSAL_STATUS_VOTING_PERIOD",
    "finalTallyResult": {
      "yes": "0",
      "abstain": "0",
      "no": "0",
      "noWithVeto": "0"
    },
    "submitTime": "2021-09-16T19:40:08.712440474Z",
    "depositEndTime": "2021-09-18T19:40:08.712440474Z",
    "totalDeposit": [
      {
        "denom": "stake",
        "amount": "10000000"
      }
    ],
    "votingStartTime": "2021-09-16T19:40:08.712440474Z",
    "votingEndTime": "2021-09-18T19:40:08.712440474Z",
    "title": "Test Proposal",
    "summary": "testing, testing, 1, 2, 3"
  }
}

使用 v1:

cosmos.gov.v1.Query/Proposal

示例:

grpcurl -plaintext \
    -d '{"proposal_id":"1"}' \
    localhost:9090 \
    cosmos.gov.v1.Query/Proposal

示例输出:

{
  "proposal": {
    "id": "1",
    "messages": [
      {"@type":"/cosmos.bank.v1beta1.MsgSend","amount":[{"denom":"stake","amount":"10"}],"fromAddress":"cosmos1..","toAddress":"cosmos1.."}
    ],
    "status": "PROPOSAL_STATUS_VOTING_PERIOD",
    "finalTallyResult": {
      "yesCount": "0",
      "abstainCount": "0",
      "noCount": "0",
      "noWithVetoCount": "0"
    },
    "submitTime": "2022-03-28T11:50:20.819676256Z",
    "depositEndTime": "2022-03-30T11:50:20.819676256Z",
    "totalDeposit": [
      {
        "denom": "stake",
        "amount": "10000000"
      }
    ],
    "votingStartTime": "2022-03-28T14:25:26.644857113Z",
    "votingEndTime": "2022-03-30T14:25:26.644857113Z",
    "metadata": "AQ==",
    "title": "Test Proposal",
    "summary": "testing, testing, 1, 2, 3"
  }
}

Proposals

Proposals 端点允许用户查询所有提案,并可选择使用过滤器。 使用遗留的 v1beta1:

cosmos.gov.v1beta1.Query/Proposals

示例:

grpcurl -plaintext \
    localhost:9090 \
    cosmos.gov.v1beta1.Query/Proposals

示例输出:

{
  "proposals": [
    {
      "proposalId": "1",
      "status": "PROPOSAL_STATUS_VOTING_PERIOD",
      "finalTallyResult": {
        "yes": "0",
        "abstain": "0",
        "no": "0",
        "noWithVeto": "0"
      },
      "submitTime": "2022-03-28T11:50:20.819676256Z",
      "depositEndTime": "2022-03-30T11:50:20.819676256Z",
      "totalDeposit": [
        {
          "denom": "stake",
          "amount": "10000000010"
        }
      ],
      "votingStartTime": "2022-03-28T14:25:26.644857113Z",
      "votingEndTime": "2022-03-30T14:25:26.644857113Z"
    },
    {
      "proposalId": "2",
      "status": "PROPOSAL_STATUS_DEPOSIT_PERIOD",
      "finalTallyResult": {
        "yes": "0",
        "abstain": "0",
        "no": "0",
        "noWithVeto": "0"
      },
      "submitTime": "2022-03-28T14:02:41.165025015Z",
      "depositEndTime": "2022-03-30T14:02:41.165025015Z",
      "totalDeposit": [
        {
          "denom": "stake",
          "amount": "10"
        }
      ],
      "votingStartTime": "0001-01-01T00:00:00Z",
      "votingEndTime": "0001-01-01T00:00:00Z"
    }
  ],
  "pagination": {
    "total": "2"
  }
}

使用 v1:

cosmos.gov.v1.Query/Proposals

示例:

grpcurl -plaintext \
    localhost:9090 \
    cosmos.gov.v1.Query/Proposals

示例输出:

{
  "proposals": [
    {
      "id": "1",
      "messages": [
        {"@type":"/cosmos.bank.v1beta1.MsgSend","amount":[{"denom":"stake","amount":"10"}],"fromAddress":"cosmos1..","toAddress":"cosmos1.."}
      ],
      "status": "PROPOSAL_STATUS_VOTING_PERIOD",
      "finalTallyResult": {
        "yesCount": "0",
        "abstainCount": "0",
        "noCount": "0",
        "noWithVetoCount": "0"
      },
      "submitTime": "2022-03-28T11:50:20.819676256Z",
      "depositEndTime": "2022-03-30T11:50:20.819676256Z",
      "totalDeposit": [
        {
          "denom": "stake",
          "amount": "10000000010"
        }
      ],
      "votingStartTime": "2022-03-28T14:25:26.644857113Z",
      "votingEndTime": "2022-03-30T14:25:26.644857113Z",
      "metadata": "AQ==",
      "title": "Proposal Title",
      "summary": "Proposal Summary"
    },
    {
      "id": "2",
      "messages": [
        {"@type":"/cosmos.bank.v1beta1.MsgSend","amount":[{"denom":"stake","amount":"10"}],"fromAddress":"cosmos1..","toAddress":"cosmos1.."}
      ],
      "status": "PROPOSAL_STATUS_DEPOSIT_PERIOD",
      "finalTallyResult": {
        "yesCount": "0",
        "abstainCount": "0",
        "noCount": "0",
        "noWithVetoCount": "0"
      },
      "submitTime": "2022-03-28T14:02:41.165025015Z",
      "depositEndTime": "2022-03-30T14:02:41.165025015Z",
      "totalDeposit": [
        {
          "denom": "stake",
          "amount": "10"
        }
      ],
      "metadata": "AQ==",
      "title": "Proposal Title",
      "summary": "Proposal Summary"
    }
  ],
  "pagination": {
    "total": "2"
  }
}

Vote

Vote 端点允许用户查询给定提案的投票。 使用遗留的 v1beta1:

cosmos.gov.v1beta1.Query/Vote

示例:

grpcurl -plaintext \
    -d '{"proposal_id":"1","voter":"cosmos1.."}' \
    localhost:9090 \
    cosmos.gov.v1beta1.Query/Vote

示例输出:

{
  "vote": {
    "proposalId": "1",
    "voter": "cosmos1..",
    "option": "VOTE_OPTION_YES",
    "options": [
      {
        "option": "VOTE_OPTION_YES",
        "weight": "1000000000000000000"
      }
    ]
  }
}

使用 v1:

cosmos.gov.v1.Query/Vote

示例:

grpcurl -plaintext \
    -d '{"proposal_id":"1","voter":"cosmos1.."}' \
    localhost:9090 \
    cosmos.gov.v1.Query/Vote

示例输出:

{
  "vote": {
    "proposalId": "1",
    "voter": "cosmos1..",
    "option": "VOTE_OPTION_YES",
    "options": [
      {
        "option": "VOTE_OPTION_YES",
        "weight": "1.000000000000000000"
      }
    ]
  }
}

Votes

Votes 端点允许用户查询给定提案的所有投票。 使用遗留的 v1beta1:

cosmos.gov.v1beta1.Query/Votes

示例:

grpcurl -plaintext \
    -d '{"proposal_id":"1"}' \
    localhost:9090 \
    cosmos.gov.v1beta1.Query/Votes

示例输出:

{
  "votes": [
    {
      "proposalId": "1",
      "voter": "cosmos1..",
      "options": [
        {
          "option": "VOTE_OPTION_YES",
          "weight": "1000000000000000000"
        }
      ]
    }
  ],
  "pagination": {
    "total": "1"
  }
}

使用 v1:

cosmos.gov.v1.Query/Votes

示例:

grpcurl -plaintext \
    -d '{"proposal_id":"1"}' \
    localhost:9090 \
    cosmos.gov.v1.Query/Votes

示例输出:

{
  "votes": [
    {
      "proposalId": "1",
      "voter": "cosmos1..",
      "options": [
        {
          "option": "VOTE_OPTION_YES",
          "weight": "1.000000000000000000"
        }
      ]
    }
  ],
  "pagination": {
    "total": "1"
  }
}

Params

Params 端点允许用户查询 gov 模块的所有参数。 使用遗留的 v1beta1:

cosmos.gov.v1beta1.Query/Params

示例:

grpcurl -plaintext \
    -d '{"params_type":"voting"}' \
    localhost:9090 \
    cosmos.gov.v1beta1.Query/Params

示例输出:

{
  "votingParams": {
    "votingPeriod": "172800s"
  },
  "depositParams": {
    "maxDepositPeriod": "0s"
  },
  "tallyParams": {
    "quorum": "MA==",
    "threshold": "MA==",
    "vetoThreshold": "MA=="
  }
}

使用 v1:

cosmos.gov.v1.Query/Params

示例 :

grpcurl -plaintext \
    -d '{"params_type":"voting"}' \
    localhost:9090 \
    cosmos.gov.v1.Query/Params

示例输出:

{
  "votingParams": {
    "votingPeriod": "172800s"
  }
}

Deposit

Deposit 端点允许用户查询给定存款人针对给定提案的存款。 使用遗留的 v1beta1:

cosmos.gov.v1beta1.Query/Deposit

示例:

grpcurl -plaintext \
    '{"proposal_id":"1","depositor":"cosmos1.."}' \
    localhost:9090 \
    cosmos.gov.v1beta1.Query/Deposit

示例输出:

{
  "deposit": {
    "proposalId": "1",
    "depositor": "cosmos1..",
    "amount": [
      {
        "denom": "stake",
        "amount": "10000000"
      }
    ]
  }
}

使用 v1:

cosmos.gov.v1.Query/Deposit

示例:

grpcurl -plaintext \
    '{"proposal_id":"1","depositor":"cosmos1.."}' \
    localhost:9090 \
    cosmos.gov.v1.Query/Deposit

示例输出:

{
  "deposit": {
    "proposalId": "1",
    "depositor": "cosmos1..",
    "amount": [
      {
        "denom": "stake",
        "amount": "10000000"
      }
    ]
  }
}

deposits

Deposits 端点允许用户查询给定提案的所有存款。 使用遗留的 v1beta1:

cosmos.gov.v1beta1.Query/Deposits

示例:

grpcurl -plaintext \
    -d '{"proposal_id":"1"}' \
    localhost:9090 \
    cosmos.gov.v1beta1.Query/Deposits

示例输出:

{
  "deposits": [
    {
      "proposalId": "1",
      "depositor": "cosmos1..",
      "amount": [
        {
          "denom": "stake",
          "amount": "10000000"
        }
      ]
    }
  ],
  "pagination": {
    "total": "1"
  }
}

使用 v1:

cosmos.gov.v1.Query/Deposits

示例:

grpcurl -plaintext \
    -d '{"proposal_id":"1"}' \
    localhost:9090 \
    cosmos.gov.v1.Query/Deposits

示例输出:

{
  "deposits": [
    {
      "proposalId": "1",
      "depositor": "cosmos1..",
      "amount": [
        {
          "denom": "stake",
          "amount": "10000000"
        }
      ]
    }
  ],
  "pagination": {
    "total": "1"
  }
}

TallyResult

TallyResult 端点允许用户查询给定提案的计票结果。 使用遗留的 v1beta1:

cosmos.gov.v1beta1.Query/TallyResult

示例:

grpcurl -plaintext \
    -d '{"proposal_id":"1"}' \
    localhost:9090 \
    cosmos.gov.v1beta1.Query/TallyResult

示例输出:

{
  "tally": {
    "yes": "1000000",
    "abstain": "0",
    "no": "0",
    "noWithVeto": "0"
  }
}

使用 v1:

cosmos.gov.v1.Query/TallyResult

示例:

grpcurl -plaintext \
    -d '{"proposal_id":"1"}' \
    localhost:9090 \
    cosmos.gov.v1.Query/TallyResult

示例输出:

{
  "tally": {
    "yes": "1000000",
    "abstain": "0",
    "no": "0",
    "noWithVeto": "0"
  }
}

REST

用户可以使用 REST 端点查询 gov 模块。

proposal

proposals 端点允许用户查询给定的提案。 使用遗留的 v1beta1:

/cosmos/gov/v1beta1/proposals/{proposal_id}

示例:

curl localhost:1317/cosmos/gov/v1beta1/proposals/1

示例输出:

{
  "proposal": {
    "proposal_id": "1",
    "content": null,
    "status": "PROPOSAL_STATUS_VOTING_PERIOD",
    "final_tally_result": {
      "yes": "0",
      "abstain": "0",
      "no": "0",
      "no_with_veto": "0"
    },
    "submit_time": "2022-03-28T11:50:20.819676256Z",
    "deposit_end_time": "2022-03-30T11:50:20.819676256Z",
    "total_deposit": [
      {
        "denom": "stake",
        "amount": "10000000010"
      }
    ],
    "voting_start_time": "2022-03-28T14:25:26.644857113Z",
    "voting_end_time": "2022-03-30T14:25:26.644857113Z"
  }
}

使用 v1:

/cosmos/gov/v1/proposals/{proposal_id}

示例:

curl localhost:1317/cosmos/gov/v1/proposals/1

示例输出:

{
  "proposal": {
    "id": "1",
    "messages": [
      {
        "@type": "/cosmos.bank.v1beta1.MsgSend",
        "from_address": "cosmos1..",
        "to_address": "cosmos1..",
        "amount": [
          {
            "denom": "stake",
            "amount": "10"
          }
        ]
      }
    ],
    "status": "PROPOSAL_STATUS_VOTING_PERIOD",
    "final_tally_result": {
      "yes_count": "0",
      "abstain_count": "0",
      "no_count": "0",
      "no_with_veto_count": "0"
    },
    "submit_time": "2022-03-28T11:50:20.819676256Z",
    "deposit_end_time": "2022-03-30T11:50:20.819676256Z",
    "total_deposit": [
      {
        "denom": "stake",
        "amount": "10000000"
      }
    ],
    "voting_start_time": "2022-03-28T14:25:26.644857113Z",
    "voting_end_time": "2022-03-30T14:25:26.644857113Z",
    "metadata": "AQ==",
    "title": "Proposal Title",
    "summary": "Proposal Summary"
  }
}

proposals

proposals 端点还允许用户查询所有提案,并可选择使用过滤器。 使用遗留的 v1beta1:

/cosmos/gov/v1beta1/proposals

示例:

curl localhost:1317/cosmos/gov/v1beta1/proposals

示例输出:

{
  "proposals": [
    {
      "proposal_id": "1",
      "content": null,
      "status": "PROPOSAL_STATUS_VOTING_PERIOD",
      "final_tally_result": {
        "yes": "0",
        "abstain": "0",
        "no": "0",
        "no_with_veto": "0"
      },
      "submit_time": "2022-03-28T11:50:20.819676256Z",
      "deposit_end_time": "2022-03-30T11:50:20.819676256Z",
      "total_deposit": [
        {
          "denom": "stake",
          "amount": "10000000"
        }
      ],
      "voting_start_time": "2022-03-28T14:25:26.644857113Z",
      "voting_end_time": "2022-03-30T14:25:26.644857113Z"
    },
    {
      "proposal_id": "2",
      "content": null,
      "status": "PROPOSAL_STATUS_DEPOSIT_PERIOD",
      "final_tally_result": {
        "yes": "0",
        "abstain": "0",
        "no": "0",
        "no_with_veto": "0"
      },
      "submit_time": "2022-03-28T14:02:41.165025015Z",
      "deposit_end_time": "2022-03-30T14:02:41.165025015Z",
      "total_deposit": [
        {
          "denom": "stake",
          "amount": "10"
        }
      ],
      "voting_start_time": "0001-01-01T00:00:00Z",
      "voting_end_time": "0001-01-01T00:00:00Z"
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "2"
  }
}

使用 v1:

/cosmos/gov/v1/proposals

示例:

curl localhost:1317/cosmos/gov/v1/proposals

示例输出:

{
  "proposals": [
    {
      "id": "1",
      "messages": [
        {
          "@type": "/cosmos.bank.v1beta1.MsgSend",
          "from_address": "cosmos1..",
          "to_address": "cosmos1..",
          "amount": [
            {
              "denom": "stake",
              "amount": "10"
            }
          ]
        }
      ],
      "status": "PROPOSAL_STATUS_VOTING_PERIOD",
      "final_tally_result": {
        "yes_count": "0",
        "abstain_count": "0",
        "no_count": "0",
        "no_with_veto_count": "0"
      },
      "submit_time": "2022-03-28T11:50:20.819676256Z",
      "deposit_end_time": "2022-03-30T11:50:20.819676256Z",
      "total_deposit": [
        {
          "denom": "stake",
          "amount": "10000000010"
        }
      ],
      "voting_start_time": "2022-03-28T14:25:26.644857113Z",
      "voting_end_time": "2022-03-30T14:25:26.644857113Z",
      "metadata": "AQ==",
      "title": "Proposal Title",
      "summary": "Proposal Summary"
    },
    {
      "id": "2",
      "messages": [
        {
          "@type": "/cosmos.bank.v1beta1.MsgSend",
          "from_address": "cosmos1..",
          "to_address": "cosmos1..",
          "amount": [
            {
              "denom": "stake",
              "amount": "10"
            }
          ]
        }
      ],
      "status": "PROPOSAL_STATUS_DEPOSIT_PERIOD",
      "final_tally_result": {
        "yes_count": "0",
        "abstain_count": "0",
        "no_count": "0",
        "no_with_veto_count": "0"
      },
      "submit_time": "2022-03-28T14:02:41.165025015Z",
      "deposit_end_time": "2022-03-30T14:02:41.165025015Z",
      "total_deposit": [
        {
          "denom": "stake",
          "amount": "10"
        }
      ],
      "voting_start_time": null,
      "voting_end_time": null,
      "metadata": "AQ==",
      "title": "Proposal Title",
      "summary": "Proposal Summary"
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "2"
  }
}

voter vote

votes 端点允许用户查询给定提案的投票。 使用遗留的 v1beta1:

/cosmos/gov/v1beta1/proposals/{proposal_id}/votes/{voter}

示例:

curl localhost:1317/cosmos/gov/v1beta1/proposals/1/votes/cosmos1..

示例输出:

{
  "vote": {
    "proposal_id": "1",
    "voter": "cosmos1..",
    "option": "VOTE_OPTION_YES",
    "options": [
      {
        "option": "VOTE_OPTION_YES",
        "weight": "1.000000000000000000"
      }
    ]
  }
}

使用 v1:

/cosmos/gov/v1/proposals/{proposal_id}/votes/{voter}

示例:

curl localhost:1317/cosmos/gov/v1/proposals/1/votes/cosmos1..

示例输出:

{
  "vote": {
    "proposal_id": "1",
    "voter": "cosmos1..",
    "options": [
      {
        "option": "VOTE_OPTION_YES",
        "weight": "1.000000000000000000"
      }
    ],
    "metadata": ""
  }
}

votes

votes 端点允许用户查询给定提案的所有投票。 使用遗留的 v1beta1:

/cosmos/gov/v1beta1/proposals/{proposal_id}/votes

示例:

curl localhost:1317/cosmos/gov/v1beta1/proposals/1/votes

示例输出:

{
  "votes": [
    {
      "proposal_id": "1",
      "voter": "cosmos1..",
      "option": "VOTE_OPTION_YES",
      "options": [
        {
          "option": "VOTE_OPTION_YES",
          "weight": "1.000000000000000000"
        }
      ]
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

使用 v1:

/cosmos/gov/v1/proposals/{proposal_id}/votes

示例:

curl localhost:1317/cosmos/gov/v1/proposals/1/votes

示例输出:

{
  "votes": [
    {
      "proposal_id": "1",
      "voter": "cosmos1..",
      "options": [
        {
          "option": "VOTE_OPTION_YES",
          "weight": "1.000000000000000000"
        }
      ],
      "metadata": ""
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

params

params 端点允许用户查询 gov 模块的所有参数。 使用遗留的 v1beta1:

/cosmos/gov/v1beta1/params/{params_type}

示例:

curl localhost:1317/cosmos/gov/v1beta1/params/voting

示例输出:

{
  "voting_params": {
    "voting_period": "172800s"
  },
  "deposit_params": {
    "min_deposit": [
    ],
    "max_deposit_period": "0s"
  },
  "tally_params": {
    "quorum": "0.000000000000000000",
    "threshold": "0.000000000000000000",
    "veto_threshold": "0.000000000000000000"
  }
}

使用 v1:

/cosmos/gov/v1/params/{params_type}

示例:

curl localhost:1317/cosmos/gov/v1/params/voting

示例输出:

{
  "voting_params": {
    "voting_period": "172800s"
  },
  "deposit_params": {
    "min_deposit": [
    ],
    "max_deposit_period": "0s"
  },
  "tally_params": {
    "quorum": "0.000000000000000000",
    "threshold": "0.000000000000000000",
    "veto_threshold": "0.000000000000000000"
  }
}

deposits

deposits 端点允许用户查询给定存款人针对给定提案的存款。 使用遗留的 v1beta1:

/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits/{depositor}

示例:

curl localhost:1317/cosmos/gov/v1beta1/proposals/1/deposits/cosmos1..

示例输出:

{
  "deposit": {
    "proposal_id": "1",
    "depositor": "cosmos1..",
    "amount": [
      {
        "denom": "stake",
        "amount": "10000000"
      }
    ]
  }
}

使用 v1:

/cosmos/gov/v1/proposals/{proposal_id}/deposits/{depositor}

示例:

curl localhost:1317/cosmos/gov/v1/proposals/1/deposits/cosmos1..

示例输出:

{
  "deposit": {
    "proposal_id": "1",
    "depositor": "cosmos1..",
    "amount": [
      {
        "denom": "stake",
        "amount": "10000000"
      }
    ]
  }
}

proposal deposits

deposits 端点允许用户查询给定提案的所有存款。 使用遗留的 v1beta1:

/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits

示例:

curl localhost:1317/cosmos/gov/v1beta1/proposals/1/deposits

示例输出:

{
  "deposits": [
    {
      "proposal_id": "1",
      "depositor": "cosmos1..",
      "amount": [
        {
          "denom": "stake",
          "amount": "10000000"
        }
      ]
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

使用 v1:

/cosmos/gov/v1/proposals/{proposal_id}/deposits

示例:

curl localhost:1317/cosmos/gov/v1/proposals/1/deposits

示例输出:

{
  "deposits": [
    {
      "proposal_id": "1",
      "depositor": "cosmos1..",
      "amount": [
        {
          "denom": "stake",
          "amount": "10000000"
        }
      ]
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

tally

tally 端点允许用户查询给定提案的计票结果。 使用遗留的 v1beta1:

/cosmos/gov/v1beta1/proposals/{proposal_id}/tally

示例:

curl localhost:1317/cosmos/gov/v1beta1/proposals/1/tally

示例输出:

{
  "tally": {
    "yes": "1000000",
    "abstain": "0",
    "no": "0",
    "no_with_veto": "0"
  }
}

使用 v1:

/cosmos/gov/v1/proposals/{proposal_id}/tally

示例:

curl localhost:1317/cosmos/gov/v1/proposals/1/tally

示例输出:

{
  "tally": {
    "yes": "1000000",
    "abstain": "0",
    "no": "0",
    "no_with_veto": "0"
  }
}

元数据

gov 模块有两个元数据位置,用户可以在这些位置提供有关其链上操作的进一步上下文。默认情况下,所有元数据字段的长度为 255 个字符,可以以 JSON 格式存储元数据,具体存储在链上或链外,取决于所需的数据量。在这里,我们提供了关于 JSON 结构的建议以及数据应存储的位置。在做出这些建议时,有两个重要因素。首先,govgroup 模块之间需要保持一致,注意所有组所提出的提案数量可能非常庞大。其次,客户端应用程序,如区块浏览器和治理界面,需要对跨链元数据结构的一致性有信心。

提案

位置:链外,作为存储在 IPFS 上的 JSON 对象(镜像组提案)。

{
  "title": "",
  "authors": [""],
  "summary": "",
  "details": "",
  "proposal_forum_url": "",
  "vote_option_context": "",
}

:::note authors 字段是一个字符串数组,用于允许在元数据中列出多个作者。在 v0.46 中,authors 字段是一个逗号分隔的字符串。前端建议支持这两种格式,以确保向后兼容。:::

投票

位置:链上,作为 255 字符限制内的 JSON (镜像组投票)。

{
  "justification": "",
}

未来改进

当前位置文档仅描述了治理模块的最小可行产品。未来的改进可能包括:

  • BountyProposals:如果接受,BountyProposal 创建一个开放的赏金任务。BountyProposal 指定完成任务后将提供多少 Atoms,这些 Atoms 将从储备池中提取。在 BountyProposal 被治理接受后,任何人都可以提交一个 SoftwareUpgradeProposal,该提案包含代码以领取赏金。请注意,一旦 BountyProposal 被接受,储备池中的相应资金将被锁定,以确保支付始终得到履行。为了将 SoftwareUpgradeProposal 与一个开放的赏金任务关联,SoftwareUpgradeProposal 的提交者将使用 Proposal.LinkedProposal 属性。如果与开放赏金任务关联的 SoftwareUpgradeProposal 被治理接受,保留的资金将自动转移给提交者。

  • 复杂委托:委托者可以选择除其验证者之外的其他代表。最终,代表链将始终以验证者为终点,但委托者可以在继承验证者投票之前继承其选定代表的投票。换句话说,只有当他们指定的其他代表没有投票时,他们才会继承验证者的投票。

  • 更好的提案审查流程proposal.Deposit 将分为两部分,一部分用于防止垃圾邮件(与 MVP 中相同),另一部分用于奖励第三方审计员。

Last updated