x/gov概览本文对CosmosSDK的治理模块进行了详细说明。治理模块在2016年的Cosmos白皮书中首次提出CosmosWhitepaper。此模块让以CosmosSDK为基础的区块链支持链上治理系统。在治理系统中,此链的原生代币持有者可以以1:1(原生代币:投票)的比例对提案进行
x/gov
本文对Cosmos SDK的治理模块进行了详细说明。治理模块在2016年的Cosmos白皮书中首次提出Cosmos Whitepaper。
此模块让以Cosmos SDK为基础的区块链支持链上治理系统。在治理系统中,此链的原生代币持有者可以以1:1(原生代币:投票)的比例对提案进行投票。以下为此模块目前支持的特性列表:
此模块已被Cosmos Hub使用 (a.k.a gaia).
以下说明均以ATOM作为原生质押代币。对于任意的PWS区块链,可以用该链的原生质押代币对ATOM进行替换。
治理的步骤分为以下几步:
MinDeposit
),提案就会被确认并且进入投票阶段。Atom的持有者便可以通过发送TxGovVote
交易来对提案进行投票。每个账号都可以通过发送MsgSubmitProposal
交易来提交提案。一旦提案被提交,提案便有一个proposalID
作为它的唯一标识。
一个提案里包含了一个sdk.Msg
消息的数组,如果提案通过,这些消息就会被执行。执行消息的是治理模块ModuleAccount
自身。如果模块例如x/upgrade
想要允许某些特定的消息在满足阈值时被治理模块执行,只需要在各自的消息服务中加一个白名单来授予治理模块执行的权限。治理模块使用消息服务路由MsgServiceRouter
来检查消息的构造的正确性并且有独立的路由去执行,但不会对消息做完整的校验。
:::注意
总之,治理模块能够执行任意提案,即使他们本意不是由治理模块来执行(例如没有设置authority)。消息不设置authority是为了指定由用户来执行。在提案中使用MsgSudoExec
来让治理模块执行任意消息,这实际上也就是让治理模块成为超级用户。
:::
为了防止产生垃圾提案,提交提案必须质押MinDeposit
参数指定的最小数量的代币。
当提交一个提案时,质押的代币数量必须为正数,但是可以小于MinDeposit
指定的数量,提案提交者不需要自己全部质押MinDeposit
所指定的最小质押量的代币。新创建的提案被存储在未激活提案队列直到它的代币质押量达到最小质押量。只有代币持有者通过发送Deposit
交易来增加提案的质押代币。如果在有效期期间提案的质押量未达到最小质押量(过了有效期无法再进行质押),提案便会被销毁:提案从状态树中移除并且提案质押的代币会被燃烧掉(详细请查阅 x/gov EndBlocker
)。当一个提案的质押量在有效期内达到了最小质押量阈值MinDeposit
,提案会被移到已激活提案队列(active proposal queue)并且开启投票阶段。
在提案最终确认前(通过或者被拒绝),提案质押的代币会被保管在由治理模块掌管的ModuleAccount
第三方账户里。
When a proposal is finalized, the coins from the deposit are either refunded or burned according to the final tally of the proposal:
ModuleAccount
).ModuleAccount
and the proposal information along with its deposit
information will be removed from state.Participants are users that have the right to vote on proposals. On the Cosmos Hub, participants are bonded Atom holders. Unbonded Atom holders and other users do not get the right to participate in governance. However, they can submit and deposit on proposals.
Note that when participants have bonded and unbonded Atoms, their voting power is calculated from their bonded Atom holdings only.
Once a proposal reaches MinDeposit
, it immediately enters Voting period
. We
define Voting period
as the interval between the moment the vote opens and
the moment the vote closes. The initial value of Voting period
is 2 weeks.
The option set of a proposal refers to the set of choices a participant can choose from when casting its vote.
The initial option set includes the following options:
Yes
/ Option 1
Abstain
/ Option 2
No
/ Option 3
NoWithVeto
/ Option 4
Spam
/ Option Spam
NoWithVeto
counts as No
but also adds a Veto
vote. Abstain
option
allows voters to signal that they do not intend to vote in favor or against the
proposal but accept the result of the vote.
Note: from the UI, for urgent proposals we should maybe add a ‘Not Urgent’ option that casts a NoWithVeto
vote.
ADR-037 introduces the weighted vote feature which allows a staker to split their votes into several voting options. For example, it could use 70% of its voting power to vote Yes and 30% of its voting power to vote No.
Often times the entity owning that address might not be a single individual. For example, a company might have different stakeholders who want to vote differently, and so it makes sense to allow them to split their voting power. Currently, it is not possible for them to do "passthrough voting" and giving their users voting rights over their tokens. However, with this system, exchanges can poll their users for voting preferences, and then vote on-chain proportionally to the results of the poll.
To represent weighted vote on chain, we use the following Protobuf message.
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
For a weighted vote to be valid, the options
field must not contain duplicate vote options, and the sum of weights of all options must be equal to 1.
The maximum number of weighted vote options can be limited by the developer via a config parameter, named MaxVoteOptionsLen
, which gets passed into the gov keeper.
Quorum is defined as the minimum percentage of voting power that needs to be cast on a proposal for the result to be valid.
Expedited Quorum is defined as the minimum percentage of voting power that needs to be cast on an expedited proposal for the result to be valid.
Yes quorum is a more restrictive quorum that is used to determine if a proposal passes.
It is defined as the minimum percentage of voting power that needs to have voted Yes
for the proposal to pass.
It differs from Threshold
as it takes the whole voting power into account, not only Yes
and No
votes.
By default, YesQuorum
is set to 0, which means no minimum.
Proposal types have been introduced in ADR-069.
A standard proposal is a proposal that can contain any messages. The proposal follows the standard governance flow and governance parameters.
A proposal can be expedited, making the proposal use shorter voting duration and a higher tally threshold by its default. If an expedited proposal fails to meet the threshold within the scope of shorter voting duration, the expedited proposal is then converted to a regular proposal and restarts voting under regular voting conditions.
An optimistic proposal is a proposal that passes unless a threshold a NO votes is reached. Voter can only vote NO on the proposal. If the NO threshold is reached, the optimistic proposal is converted to a standard proposal.
That threshold is defined by the optimistic_rejected_threshold
governance parameter.
A chain can optionally set a list of authorized addresses that can submit optimistic proposals using the optimistic_authorized_addresses
governance parameter.
A multiple choice proposal is a proposal where the voting options can be defined by the proposer. The number of voting options is limited to a maximum of 4. Multiple choice proposals, contrary to any other proposal type, cannot have messages to execute. They are only text proposals.
Threshold is defined as the minimum proportion of Yes
votes (excluding
Abstain
votes) for the proposal to be accepted.
Initially, the threshold is set at 50% of Yes
votes, excluding Abstain
votes. A possibility to veto exists if more than 1/3rd of all votes are
NoWithVeto
votes. Note, both of these values are derived from the TallyParams
on-chain parameter, which is modifiable by governance.
This means that proposals are accepted iff:
Abstain
votes is inferior to 1/1.NoWithVeto
votes is inferior to 1/3, including
Abstain
votes.Yes
votes, excluding Abstain
votes, at the end of
the voting period is superior to 1/2.For expedited proposals, by default, the threshold is higher than with a normal proposal, namely, 66.7%.
If a delegator does not vote, it will inherit its validator vote.
At present, validators are not punished for failing to vote.
Later, we may add permissioned keys that could only sign txs from certain modules. For the MVP, the Governance address
will be the main validator address generated at account creation. This address corresponds to a different PrivKey than the CometBFT PrivKey which is responsible for signing consensus messages. Validators thus do not have to sign governance transactions with the sensitive CometBFT PrivKey.
There are three parameters that define if the deposit of a proposal should be burned or returned to the depositors.
BurnVoteVeto
burns the proposal deposit if the proposal gets vetoed.BurnVoteQuorum
burns the proposal deposit if the proposal deposit if the vote does not reach quorum.BurnProposalDepositPrevote
burns the proposal deposit if it does not enter the voting phase.Note: These parameters are modifiable via governance.
Execution is the process of executing the messages contained in a proposal. The execution phase will commence after the proposal has been accepted by the network. The messages contained in the proposal will be executed in the order they were submitted.
Execution has a upper limit on how much gas can be consumed in a single block. This limit is defined by the ProposalExecutionGas
parameter.
Constitution
is found in the genesis state. It is a string field intended to be used to describe the purpose of a particular blockchain, and its expected norms. A few examples of how the constitution field can be used:
Since this is more of a social feature than a technical feature, we'll now get into some items that may have been useful to have in a genesis constitution:
This genesis entry, "constitution" hasn't been designed for existing chains, who should likely just ratify a constitution using their governance system. Instead, this is for new chains. It will allow for validators to have a much clearer idea of purpose and the expectations placed on them while operating their nodes. Likewise, for community members, the constitution will give them some idea of what to expect from both the "chain team" and the validators, respectively.
This constitution is designed to be immutable, and placed only in genesis, though that could change over time by a pull request to the cosmos-sdk that allows for the constitution to be changed by governance. Communities whishing to make amendments to their original constitution should use the governance mechanism and a "signaling proposal" to do exactly that.
Ideal use scenario for a cosmos chain constitution
As a chain developer, you decide that you'd like to provide clarity to your key user groups:
You use the constitution to immutably store some Markdown in genesis, so that when difficult questions come up, the constutituon can provide guidance to the community.
Proposal
objects are used to tally votes and generally track the proposal's state.
They contain an array of arbitrary sdk.Msg
's which the governance module will attempt
to resolve and then execute if the proposal passes. Proposal
's are identified by a
unique id and contains a series of timestamps: submit_time
, deposit_end_time
,
voting_start_time
, voting_end_time
which track the lifecycle of a proposal
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L51-L99
A proposal will generally require more than just a set of messages to explain its
purpose but need some greater justification and allow a means for interested participants
to discuss and debate the proposal.
In most cases, it is encouraged to have an off-chain system that supports the on-chain governance process.
To accommodate for this, a proposal contains a special metadata
field, a string,
which can be used to add context to the proposal. The metadata
field allows custom use for networks,
however, it is expected that the field contains a URL or some form of CID using a system such as
IPFS. To support the case of
interoperability across networks, the SDK recommends that the metadata
represents
the following JSON
template:
{
"title": "...",
"description": "...",
"forum": "...", // a link to the discussion platform (i.e. Discord)
"other": "..." // any extra data that doesn't correspond to the other fields
}
This makes it far easier for clients to support multiple networks.
Fields metadata, title and summary have a maximum length that is chosen by the app developer, and passed into the gov keeper as a config. The default maximum length are: for the title 255 characters, for the metadata 255 characters and for summary 10200 characters (40 times the one of the title).
There are many aspects of a chain, or of the individual modules that you may want to
use governance to perform such as changing various parameters. This is very simple
to do. First, write out your message types and MsgServer
implementation. Add an
authority
field to the keeper which will be populated in the constructor with the
governance module account: govKeeper.GetGovernanceAccount().GetAddress()
. Then for
the methods in the msg_server.go
, perform a check on the message that the signer
matches authority
. This will prevent any user from executing that message.
:::warning
Note, any message can be executed by governance if embedded in MsgSudoExec
.
:::
Parameters
define the rules according to which votes are run. There can only
be one active parameter set at any given time. If governance wants to change a
parameter set, either to modify a value or add/remove a parameter field, a new
parameter set has to be created and the previous one rendered inactive.
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L152-L162
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L164-L168
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L170-L182
Parameters are stored in a global GlobalParams
KVStore.
Additionally, we introduce some basic types:
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
)
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L38-L49
This type is used in a temp map when tallying
type ValidatorGovInfo struct {
Minus sdk.Dec
Vote Vote
}
:::note Stores are KVStores in the multi-store. The key to find the store is the first parameter in the list :::
We will use one KVStore Governance
to store four mappings:
proposalID|'proposal'
to Proposal
.proposalID|'addresses'|address
to Vote
. This mapping allows
us to query all addresses that voted on the proposal along with their vote by
doing a range query on proposalID:addresses
.ParamsKey|'Params'
to Params
. This map allows to query all
x/gov params.For pseudocode purposes, here are the two function we will use to read or write in stores:
load(StoreKey, Key)
: Retrieve item stored at key Key
in store found at key StoreKey
in the multistorestore(StoreKey, Key, value)
: Write value Value
at key Key
in store found at key StoreKey
in the multistoreStore:
ProposalProcessingQueue
: A queue queue[proposalID]
containing all the
ProposalIDs
of proposals that reached MinDeposit
. During each EndBlock
,
all the proposals that have reached the end of their voting period are processed.
To process a finished proposal, the application tallies the votes, computes the
votes of each validator and checks if every validator in the validator set has
voted. If the proposal is accepted, deposits are refunded. Finally, the proposal
content Handler
is executed.:::warning Legacy proposals are deprecated. Use the new proposal flow by granting the governance module the right to execute the message. :::
A legacy proposal is the old implementation of governance proposal. Contrary to proposal that can contain any messages, a legacy proposal allows to submit a set of pre-defined proposals. These proposals are defined by their types and handled by handlers that are registered in the gov v1beta1 router.
More information on how to submit proposals in the client section.
Proposals can be submitted by any account via a MsgSubmitProposal
or a MsgSubmitMultipleChoiceProposal
transaction.
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/tx.proto#L42-L69
:::note A multiple choice proposal is a proposal where the voting options can be defined by the proposer. It cannot have messages to execute. It is only a text proposal. :::
:::warning
Submitting a multiple choice proposal using MsgSubmitProposal
is invalid, as vote options cannot be defined.
:::
All sdk.Msgs
passed into the messages
field of a MsgSubmitProposal
message
must be registered in the app's MsgServiceRouter
. Each of these messages must
have one signer, namely the gov module account. And finally, the metadata length
must not be larger than the maxMetadataLen
config passed into the gov keeper.
The initialDeposit
must be strictly positive and conform to the accepted denom of the MinDeposit
param.
State modifications:
proposalID
Proposal
Proposal
's attributesInitialDeposit
MinDeposit
is reached:
proposalID
in ProposalProcessingQueue
InitialDeposit
from the Proposer
to the governance ModuleAccount
Once a proposal is submitted, if Proposal.TotalDeposit < ActiveParam.MinDeposit
, Atom holders can send
MsgDeposit
transactions to increase the proposal's deposit.
A deposit is accepted iff:
MinDeposit
paramhttps://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/tx.proto#L134-L147
State modifications:
deposit
deposit
of sender in proposal.Deposits
proposal.TotalDeposit
by sender's deposit
MinDeposit
is reached:
proposalID
in ProposalProcessingQueueEnd
Deposit
from the proposer
to the governance ModuleAccount
Once ActiveParam.MinDeposit
is reached, voting period starts. From there,
bonded Atom holders are able to send MsgVote
transactions to cast their
vote on the proposal.
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/tx.proto#L92-L108
State modifications:
Vote
of sender:::note Gas cost for this message has to take into account the future tallying of the vote in EndBlocker. :::
The governance module emits the following events:
Type | Attribute Key | Attribute Value |
---|---|---|
inactive_proposal | proposal_id | {proposalID} |
inactive_proposal | proposal_result | {proposalResult} |
active_proposal | proposal_id | {proposalID} |
active_proposal | proposal_result | {proposalResult} |
Type | Attribute Key | Attribute Value |
---|---|---|
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} |
Type | Attribute Key | Attribute Value |
---|---|---|
proposal_vote | option | {voteOption} |
proposal_vote | proposal_id | {proposalID} |
message | module | governance |
message | action | vote |
message | sender | {senderAddress} |
Type | Attribute Key | Attribute Value |
---|---|---|
proposal_vote | option | {weightedVoteOptions} |
proposal_vote | proposal_id | {proposalID} |
message | module | governance |
message | action | vote |
message | sender | {senderAddress} |
Type | Attribute Key | Attribute Value |
---|---|---|
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} |
The governance module contains the following parameters:
Key | Type | Example |
---|---|---|
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" |
yes_quorum | string (dec) | "0.4" |
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"}] |
expedited_quorum | string (dec) | "0.5" |
burn_proposal_deposit_prevote | bool | false |
burn_vote_quorum | bool | false |
burn_vote_veto | bool | true |
min_initial_deposit_ratio | string | "0.1" |
proposal_cancel_ratio | string (dec) | "0.5" |
proposal_cancel_dest | string (address) | "cosmos1.." or empty for burn |
proposal_cancel_max_period | string (dec) | "0.5" |
optimistic_rejected_threshold | string (dec) | "0.1" |
optimistic_authorized_addresses | array (addresses) | [] |
NOTE: The governance module contains parameters that are objects unlike other modules. If only a subset of parameters are desired to be changed, only they need to be included and not the entire parameter object structure.
In addition to the parameters above, the governance module can also be configured to have different parameters for a given proposal message.
Key | Type | Example |
---|---|---|
voting_period | string (time ns) | "172800000000000" (17280s) |
yes_quorum | string (dec) | "0.4" |
quorum | string (dec) | "0.334000000000000000" |
threshold | string (dec) | "0.500000000000000000" |
veto | string (dec) | "0.334000000000000000" |
If configured, these params will take precedence over the global params for a specific proposal.
:::warning Currently, messaged based parameters limit the number of messages that can be included in a proposal to 1 if a messaged based parameter is configured. :::
A user can query and interact with the gov
module using the CLI.
The query
commands allow users to query gov
state.
simd query gov --help
The deposit
command allows users to query a deposit for a given proposal from a given depositor.
simd query gov deposit [proposal-id] [depositer-addr] [flags]
Example:
simd query gov deposit 1 cosmos1..
Example Output:
amount:
- amount: "100"
denom: stake
depositor: cosmos1..
proposal_id: "1"
The deposits
command allows users to query all deposits for a given proposal.
simd query gov deposits [proposal-id] [flags]
Example:
simd query gov deposits 1
Example Output:
deposits:
- amount:
- amount: "100"
denom: stake
depositor: cosmos1..
proposal_id: "1"
pagination:
next_key: null
total: "0"
The params
command allows users to query all parameters for the gov
module.
simd query gov params [flags]
Example:
simd query gov params
Example Output:
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
The proposal
command allows users to query a given proposal.
simd query gov proposal [proposal-id] [flags]
Example:
simd query gov proposal 1
Example Output:
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
The proposals
command allows users to query all proposals with optional filters.
simd query gov proposals [flags]
Example:
simd query gov proposals
Example Output:
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
The proposer
command allows users to query the proposer for a given proposal.
simd query gov proposer [proposal-id] [flags]
Example:
simd query gov proposer 1
Example Output:
proposal_id: "1"
proposer: cosmos1..
The tally
command allows users to query the tally of a given proposal vote.
simd query gov tally [proposal-id] [flags]
Example:
simd query gov tally 1
Example Output:
abstain: "0"
"no": "0"
no_with_veto: "0"
"yes": "1"
The vote
command allows users to query a vote for a given proposal.
simd query gov vote [proposal-id] [voter-addr] [flags]
Example:
simd query gov vote 1 cosmos1..
Example Output:
option: VOTE_OPTION_YES
options:
- option: VOTE_OPTION_YES
weight: "1.000000000000000000"
proposal_id: "1"
voter: cosmos1..
The votes
command allows users to query all votes for a given proposal.
simd query gov votes [proposal-id] [flags]
Example:
simd query gov votes 1
Example Output:
pagination:
next_key: null
total: "0"
votes:
- option: VOTE_OPTION_YES
options:
- option: VOTE_OPTION_YES
weight: "1.000000000000000000"
proposal_id: "1"
voter: cosmos1..
The tx
commands allow users to interact with the gov
module.
simd tx gov --help
The deposit
command allows users to deposit tokens for a given proposal.
simd tx gov deposit [proposal-id] [deposit] [flags]
Example:
simd tx gov deposit 1 10000000stake --from cosmos1..
The draft-proposal
command allows users to draft any type of proposal.
The command returns a draft_proposal.json
, to be used by submit-proposal
after being completed.
The draft_metadata.json
is meant to be uploaded to IPFS.
simd tx gov draft-proposal
The submit-proposal
command allows users to submit a governance proposal along with some messages and metadata.
Messages, metadata and deposit are defined in a JSON file.
simd tx gov submit-proposal [path-to-proposal-json] [flags]
Example:
simd tx gov submit-proposal /path/to/proposal.json --from cosmos1..
where proposal.json
contains:
{
"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 By default the metadata, summary and title are both limited by 255 characters, this can be overridden by the application developer. :::
:::tip When metadata is not specified, the title is limited to 255 characters and the summary 40x the title length. :::
The submit-legacy-proposal
command allows users to submit a governance legacy proposal along with an initial deposit.
simd tx gov submit-legacy-proposal [command] [flags]
Example:
simd tx gov submit-legacy-proposal --title="Test Proposal" --description="testing" --type="Text" --deposit="100000000stake" --from cosmos1..
Example (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"
}
Once proposal is canceled, from the deposits of proposal deposits * proposal_cancel_ratio
will be burned or sent to ProposalCancelDest
address , if ProposalCancelDest
is empty then deposits will be burned. The remaining deposits
will be sent to depositers.
simd tx gov cancel-proposal [proposal-id] [flags]
Example:
simd tx gov cancel-proposal 1 --from cosmos1...
The vote
command allows users to submit a vote for a given governance proposal.
simd tx gov vote [command] [flags]
Example:
simd tx gov vote 1 yes --from cosmos1..
The weighted-vote
command allows users to submit a weighted vote for a given governance proposal.
simd tx gov weighted-vote [proposal-id] [weighted-options] [flags]
Example:
simd tx gov weighted-vote 1 yes=0.5,no=0.5 --from cosmos1..
A user can query the gov
module using gRPC endpoints.
The Proposal
endpoint allows users to query a given proposal.
Using legacy v1beta1:
cosmos.gov.v1beta1.Query/Proposal
Example:
grpcurl -plaintext \
-d '{"proposal_id":"1"}' \
localhost:9090 \
cosmos.gov.v1beta1.Query/Proposal
Example Output:
{
"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"
}
}
Using v1:
cosmos.gov.v1.Query/Proposal
Example:
grpcurl -plaintext \
-d '{"proposal_id":"1"}' \
localhost:9090 \
cosmos.gov.v1.Query/Proposal
Example Output:
{
"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"
}
}
The Proposals
endpoint allows users to query all proposals with optional filters.
Using legacy v1beta1:
cosmos.gov.v1beta1.Query/Proposals
Example:
grpcurl -plaintext \
localhost:9090 \
cosmos.gov.v1beta1.Query/Proposals
Example Output:
{
"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"
}
}
Using v1:
cosmos.gov.v1.Query/Proposals
Example:
grpcurl -plaintext \
localhost:9090 \
cosmos.gov.v1.Query/Proposals
Example Output:
{
"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"
}
}
The Vote
endpoint allows users to query a vote for a given proposal.
Using legacy v1beta1:
cosmos.gov.v1beta1.Query/Vote
Example:
grpcurl -plaintext \
-d '{"proposal_id":"1","voter":"cosmos1.."}' \
localhost:9090 \
cosmos.gov.v1beta1.Query/Vote
Example Output:
{
"vote": {
"proposalId": "1",
"voter": "cosmos1..",
"option": "VOTE_OPTION_YES",
"options": [
{
"option": "VOTE_OPTION_YES",
"weight": "1000000000000000000"
}
]
}
}
Using v1:
cosmos.gov.v1.Query/Vote
Example:
grpcurl -plaintext \
-d '{"proposal_id":"1","voter":"cosmos1.."}' \
localhost:9090 \
cosmos.gov.v1.Query/Vote
Example Output:
{
"vote": {
"proposalId": "1",
"voter": "cosmos1..",
"option": "VOTE_OPTION_YES",
"options": [
{
"option": "VOTE_OPTION_YES",
"weight": "1.000000000000000000"
}
]
}
}
The Votes
endpoint allows users to query all votes for a given proposal.
Using legacy v1beta1:
cosmos.gov.v1beta1.Query/Votes
Example:
grpcurl -plaintext \
-d '{"proposal_id":"1"}' \
localhost:9090 \
cosmos.gov.v1beta1.Query/Votes
Example Output:
{
"votes": [
{
"proposalId": "1",
"voter": "cosmos1..",
"options": [
{
"option": "VOTE_OPTION_YES",
"weight": "1000000000000000000"
}
]
}
],
"pagination": {
"total": "1"
}
}
Using v1:
cosmos.gov.v1.Query/Votes
Example:
grpcurl -plaintext \
-d '{"proposal_id":"1"}' \
localhost:9090 \
cosmos.gov.v1.Query/Votes
Example Output:
{
"votes": [
{
"proposalId": "1",
"voter": "cosmos1..",
"options": [
{
"option": "VOTE_OPTION_YES",
"weight": "1.000000000000000000"
}
]
}
],
"pagination": {
"total": "1"
}
}
The Params
endpoint allows users to query all parameters for the gov
module.
Using legacy v1beta1:
cosmos.gov.v1beta1.Query/Params
Example:
grpcurl -plaintext \
-d '{"params_type":"voting"}' \
localhost:9090 \
cosmos.gov.v1beta1.Query/Params
Example Output:
{
"votingParams": {
"votingPeriod": "172800s"
},
"depositParams": {
"maxDepositPeriod": "0s"
},
"tallyParams": {
"quorum": "MA==",
"threshold": "MA==",
"vetoThreshold": "MA=="
}
}
Using v1:
cosmos.gov.v1.Query/Params
Example:
grpcurl -plaintext \
-d '{"params_type":"voting"}' \
localhost:9090 \
cosmos.gov.v1.Query/Params
Example Output:
{
"votingParams": {
"votingPeriod": "172800s"
}
}
The Deposit
endpoint allows users to query a deposit for a given proposal from a given depositor.
Using legacy v1beta1:
cosmos.gov.v1beta1.Query/Deposit
Example:
grpcurl -plaintext \
'{"proposal_id":"1","depositor":"cosmos1.."}' \
localhost:9090 \
cosmos.gov.v1beta1.Query/Deposit
Example Output:
{
"deposit": {
"proposalId": "1",
"depositor": "cosmos1..",
"amount": [
{
"denom": "stake",
"amount": "10000000"
}
]
}
}
Using v1:
cosmos.gov.v1.Query/Deposit
Example:
grpcurl -plaintext \
'{"proposal_id":"1","depositor":"cosmos1.."}' \
localhost:9090 \
cosmos.gov.v1.Query/Deposit
Example Output:
{
"deposit": {
"proposalId": "1",
"depositor": "cosmos1..",
"amount": [
{
"denom": "stake",
"amount": "10000000"
}
]
}
}
The Deposits
endpoint allows users to query all deposits for a given proposal.
Using legacy v1beta1:
cosmos.gov.v1beta1.Query/Deposits
Example:
grpcurl -plaintext \
-d '{"proposal_id":"1"}' \
localhost:9090 \
cosmos.gov.v1beta1.Query/Deposits
Example Output:
{
"deposits": [
{
"proposalId": "1",
"depositor": "cosmos1..",
"amount": [
{
"denom": "stake",
"amount": "10000000"
}
]
}
],
"pagination": {
"total": "1"
}
}
Using v1:
cosmos.gov.v1.Query/Deposits
Example:
grpcurl -plaintext \
-d '{"proposal_id":"1"}' \
localhost:9090 \
cosmos.gov.v1.Query/Deposits
Example Output:
{
"deposits": [
{
"proposalId": "1",
"depositor": "cosmos1..",
"amount": [
{
"denom": "stake",
"amount": "10000000"
}
]
}
],
"pagination": {
"total": "1"
}
}
The TallyResult
endpoint allows users to query the tally of a given proposal.
Using legacy v1beta1:
cosmos.gov.v1beta1.Query/TallyResult
Example:
grpcurl -plaintext \
-d '{"proposal_id":"1"}' \
localhost:9090 \
cosmos.gov.v1beta1.Query/TallyResult
Example Output:
{
"tally": {
"yes": "1000000",
"abstain": "0",
"no": "0",
"noWithVeto": "0",
"option_one_count": "1000000",
"option_two_count": "0",
"option_three_count": "0",
"option_four_count": "0",
"spam_count": "0"
}
}
Using v1:
cosmos.gov.v1.Query/TallyResult
Example:
grpcurl -plaintext \
-d '{"proposal_id":"1"}' \
localhost:9090 \
cosmos.gov.v1.Query/TallyResult
Example Output:
{
"tally": {
"yes": "1000000",
"abstain": "0",
"no": "0",
"noWithVeto": "0"
}
}
A user can query the gov
module using REST endpoints.
The proposals
endpoint allows users to query a given proposal.
Using legacy v1beta1:
/cosmos/gov/v1beta1/proposals/{proposal_id}
Example:
curl localhost:1317/cosmos/gov/v1beta1/proposals/1
Example Output:
{
"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"
}
}
Using v1:
/cosmos/gov/v1/proposals/{proposal_id}
Example:
curl localhost:1317/cosmos/gov/v1/proposals/1
Example Output:
{
"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"
}
}
The proposals
endpoint also allows users to query all proposals with optional filters.
Using legacy v1beta1:
/cosmos/gov/v1beta1/proposals
Example:
curl localhost:1317/cosmos/gov/v1beta1/proposals
Example Output:
{
"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"
}
}
Using v1:
/cosmos/gov/v1/proposals
Example:
curl localhost:1317/cosmos/gov/v1/proposals
Example Output:
{
"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"
}
}
The votes
endpoint allows users to query a vote for a given proposal.
Using legacy v1beta1:
/cosmos/gov/v1beta1/proposals/{proposal_id}/votes/{voter}
Example:
curl localhost:1317/cosmos/gov/v1beta1/proposals/1/votes/cosmos1..
Example Output:
{
"vote": {
"proposal_id": "1",
"voter": "cosmos1..",
"option": "VOTE_OPTION_YES",
"options": [
{
"option": "VOTE_OPTION_YES",
"weight": "1.000000000000000000"
}
]
}
}
Using v1:
/cosmos/gov/v1/proposals/{proposal_id}/votes/{voter}
Example:
curl localhost:1317/cosmos/gov/v1/proposals/1/votes/cosmos1..
Example Output:
{
"vote": {
"proposal_id": "1",
"voter": "cosmos1..",
"options": [
{
"option": "VOTE_OPTION_YES",
"weight": "1.000000000000000000"
}
],
"metadata": ""
}
}
The votes
endpoint allows users to query all votes for a given proposal.
Using legacy v1beta1:
/cosmos/gov/v1beta1/proposals/{proposal_id}/votes
Example:
curl localhost:1317/cosmos/gov/v1beta1/proposals/1/votes
Example Output:
{
"votes": [
{
"proposal_id": "1",
"voter": "cosmos1..",
"option": "VOTE_OPTION_YES",
"options": [
{
"option": "VOTE_OPTION_YES",
"weight": "1.000000000000000000"
}
]
}
],
"pagination": {
"next_key": null,
"total": "1"
}
}
Using v1:
/cosmos/gov/v1/proposals/{proposal_id}/votes
Example:
curl localhost:1317/cosmos/gov/v1/proposals/1/votes
Example Output:
{
"votes": [
{
"proposal_id": "1",
"voter": "cosmos1..",
"options": [
{
"option": "VOTE_OPTION_YES",
"weight": "1.000000000000000000"
}
],
"metadata": ""
}
],
"pagination": {
"next_key": null,
"total": "1"
}
}
The params
endpoint allows users to query all parameters for the gov
module.
<!-- TODO: #10197 Querying governance params outputs nil values -->
Using legacy v1beta1:
/cosmos/gov/v1beta1/params/{params_type}
Example:
curl localhost:1317/cosmos/gov/v1beta1/params/voting
Example Output:
{
"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"
}
}
Using v1:
/cosmos/gov/v1/params/{params_type}
Example:
curl localhost:1317/cosmos/gov/v1/params/voting
Example Output:
{
"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"
}
}
The deposits
endpoint allows users to query a deposit for a given proposal from a given depositor.
Using legacy v1beta1:
/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits/{depositor}
Example:
curl localhost:1317/cosmos/gov/v1beta1/proposals/1/deposits/cosmos1..
Example Output:
{
"deposit": {
"proposal_id": "1",
"depositor": "cosmos1..",
"amount": [
{
"denom": "stake",
"amount": "10000000"
}
]
}
}
Using v1:
/cosmos/gov/v1/proposals/{proposal_id}/deposits/{depositor}
Example:
curl localhost:1317/cosmos/gov/v1/proposals/1/deposits/cosmos1..
Example Output:
{
"deposit": {
"proposal_id": "1",
"depositor": "cosmos1..",
"amount": [
{
"denom": "stake",
"amount": "10000000"
}
]
}
}
The deposits
endpoint allows users to query all deposits for a given proposal.
Using legacy v1beta1:
/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits
Example:
curl localhost:1317/cosmos/gov/v1beta1/proposals/1/deposits
Example Output:
{
"deposits": [
{
"proposal_id": "1",
"depositor": "cosmos1..",
"amount": [
{
"denom": "stake",
"amount": "10000000"
}
]
}
],
"pagination": {
"next_key": null,
"total": "1"
}
}
Using v1:
/cosmos/gov/v1/proposals/{proposal_id}/deposits
Example:
curl localhost:1317/cosmos/gov/v1/proposals/1/deposits
Example Output:
{
"deposits": [
{
"proposal_id": "1",
"depositor": "cosmos1..",
"amount": [
{
"denom": "stake",
"amount": "10000000"
}
]
}
],
"pagination": {
"next_key": null,
"total": "1"
}
}
The tally
endpoint allows users to query the tally of a given proposal.
Using legacy v1beta1:
/cosmos/gov/v1beta1/proposals/{proposal_id}/tally
Example:
curl localhost:1317/cosmos/gov/v1beta1/proposals/1/tally
Example Output:
{
"tally": {
"yes": "1000000",
"abstain": "0",
"no": "0",
"no_with_veto": "0"
}
}
Using v1:
/cosmos/gov/v1/proposals/{proposal_id}/tally
Example:
curl localhost:1317/cosmos/gov/v1/proposals/1/tally
Example Output:
{
"tally": {
"yes": "1000000",
"abstain": "0",
"no": "0",
"no_with_veto": "0"
}
}
The gov module has two locations for metadata where users can provide further context about the on-chain actions they are taking. By default all metadata fields have a 255 character length field where metadata can be stored in json format, either on-chain or off-chain depending on the amount of data required. Here we provide a recommendation for the json structure and where the data should be stored. There are two important factors in making these recommendations. First, that the gov and group modules are consistent with one another, note the number of proposals made by all groups may be quite large. Second, that client applications such as block explorers and governance interfaces have confidence in the consistency of metadata structure across chains.
Location: off-chain as json object stored on IPFS (mirrors group proposal)
{
"title": "",
"authors": [""],
"summary": "",
"details": "",
"proposal_forum_url": "",
"vote_option_context": "",
}
:::note
The authors
field is an array of strings, this is to allow for multiple authors to be listed in the metadata.
In v0.46, the authors
field is a comma-separated string. Frontends are encouraged to support both formats for backwards compatibility.
:::
Location: on-chain as json within 255 character limit (mirrors group vote)
{
"justification": "",
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!