如果你已经准备好提案的最终草稿并打算提交,你可能会希望先在测试网上发布提案。以下是在链上发布提案的三个主要步骤。 要通过命令行与 Cosmos Hub 交互以执行查询或提交提案,需要满足以下几个前提条件:
  • 你需要从源码编译 gaiad,生成可由你的操作系统执行的二进制文件,例如 MacOS、Windows、Linux
  • 你需要指明要查询的是哪条链,目前应使用 --chain-id cosmoshub-4
  • 你需要连接到一个全节点。你可以在 Chain Registry 的 API 部分 找到可用的 Cosmos Hub 端点列表。
  • 更多信息请参见“操作示例”部分。
运行全节点对不熟悉技术的人来说可能比较困难,因此你也可以选择使用第三方的全节点。在这种情况下,主要的安全风险是审查:这会成为你接入网络的单一入口,而任何通过不受信任节点提交的消息都有可能被审查。

托管补充材料

通常我们会尽量减少推送到区块链上的数据量。因此,提案的详细文档通常会托管在独立的、具备抗审查能力的数据托管平台上,例如 IPFS。 当你完成提案草拟后,理想情况下是一个 Markdown 文件,你可以将其上传到 IPFS 网络:
  1. 通过运行 IPFS 节点并使用 IPFS 软件,或
  2. 通过使用诸如 Link 之类的服务
请确保对该文件执行“pin”操作,以便它能持续在网络中可用。你应当会得到一个像这样的 URL:链接 QmbkQNtCAdR1CNbFE8ujub2jcpwUcmSRpSCg8gVWrTHSWD 这个值称为文件的 CID,本质上它就是该文件的哈希。 如果你上传的是 Markdown 文件,可以使用 IPFS Markdown 查看器来渲染文档,以获得更好的阅读体验。Markdown 查看器的链接格式如下:https://ipfs.io/ipfs/QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/example#/ipfs/<CID>,其中 <CID> 是你的 CID。例如,上面的链接将会是:链接 将该 URL 分享给其他人,并确认你的文件可以被公开访问。 我们使用 IPFS 的原因在于,它是一种去中心化的存储方式,能够抵抗审查和单点故障。这会提高该文件未来持续可用的可能性。

为治理提案格式化 JSON 文件

在发送将提案提交上链的交易之前,你必须先创建一个 JSON 文件。该文件将包含会作为治理提案存储在链上的信息。先创建一个新的文本(.txt)文件来填写这些信息。你可以参考这些最佳实践来编写提案内容。完成后,将文件保存为 .json 文件。 每种提案类型对应的 JSON 格式都不相同。 请查看与你正在起草的提案类型对应的相关章节: 一旦上链,大多数人会依赖区块浏览器通过图形用户界面(GUI)来解读这些信息。

发送提交治理提案的交易

关于如何使用 gaiad(命令行接口)通过治理模块提交链上提案,请参阅 Cosmos Hub 文档中的 gaiad CLI 教程。

提案类型

有 2 种提案类型可以提交到 CosmosHub 治理模块。

旧版提案(cosmos-sdk < v0.47)

这些提案可以使用 gaiad tx gov submit-legacy-proposal 提交。 可通过该 Tx 提交的提案包括:
  • cancel-software-upgrade
  • change-reward-denoms
  • consumer-addition
  • consumer-removal
  • ibc-upgrade
  • param-change(对标准 cosmos-sdk 模块无效,可用于 IBC 和 ICS 模块)
  • software-upgrade
  • update-client
你可以在 cosmos-sdk 文档 中进一步了解如何提交旧版提案。

提案(cosmos-sdk >= v0.47)

这些提案可以使用 gaiad tx gov submit-proposal 提交。 使用 gaiad tx gov draft-proposal 可以帮助准备提案。该工具会创建一个包含指定提案消息的文件,同时也会帮助填写所有必需的提案字段。 你在使用 draft-proposal 创建文件后,始终都可以再编辑它。 大多数 cosmos-sdk 模块都允许通过 MsgUpdateParams 来修改其受治理控制的参数,这是一种更新治理参数的新方式。需要特别注意的是,MsgUpdateParams 要求在提案消息中指定全部参数。 你可以在 cosmos-sdk 文档 中进一步了解如何提交提案。

最低初始存款金额

请注意,cosmoshub-4 使用最低初始存款金额要求。
如果不提供最低初始存款,提案将无法成功提交。实际上,这意味着你提案中的 deposit 字段必须满足 min_initial_deposit 治理参数。 最低存款金额等于 min_deposit * min_initial_deposit_ratio。目前仅支持使用 uatom 作为存款面额。
// checking the min_initial_deposit
gaiad q gov params -o json
{
   ...
   "params": {
      ...
      "min_deposit": [
         {
               "denom": "stake",
               "amount": "10000000"
         }
      ],
      "min_initial_deposit_ratio": "0.000000000000000000"
}

操作示例(修改 x/staking 参数)

下面我们以修改 x/staking 参数为例进行说明。 该模块具有以下参数(这些值不代表链上的真实值):
gaiad q staking params -o json
{
    "unbonding_time": "86400s",
    "max_validators": 100,
    "max_entries": 7,
    "historical_entries": 10000,
    "bond_denom": "stake",
    "min_commission_rate": "0.000000000000000000",
    "validator_bond_factor": "-1.000000000000000000",
    "global_liquid_staking_cap": "1.000000000000000000",
    "validator_liquid_staking_cap": "1.000000000000000000"
}
我们将使用 draft-proposal 来帮助创建稍后要提交的提案文件。
gaiad tx gov draft-proposal
// running the command will start a terminal applet allowing you to choose the proposal type

// 1st screen
Use the arrow keys to navigate: ↓ ↑ → ←
? Select proposal type:
    text
    community-pool-spend
    software-upgrade
    cancel-software-upgrade
  ▸ other // choose this

// 2nd screen
✔ other
Use the arrow keys to navigate: ↓ ↑ → ←
? Select proposal message type::
↑   /cosmos.staking.v1beta1.MsgUndelegate
  ▸ /cosmos.staking.v1beta1.MsgUpdateParams // choose this option
    /cosmos.staking.v1beta1.MsgValidatorBond
    /cosmos.upgrade.v1beta1.MsgCancelUpgrade
↓   /cosmos.upgrade.v1beta1.MsgSoftwareUpgrade
在选择 /cosmos.staking.v1beta1.MsgUpdateParams 消息后,该交互程序会允许你设置消息字段以及其他一些提案细节。 完成后,提案文件会出现在你执行 gaiad 命令的目录中,文件名为 draft_proposal.json。 下面是 draft_proposal.json 文件的一个示例:
{
  "messages": [
  {
  "@type": "/cosmos.staking.v1beta1.MsgUpdateParams",
  "authority": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn",
  "params": {
  "unbonding_time": "86400s",
  "max_validators": 100,
    "max_entries": 7,
    "historical_entries": 10000,
    "bond_denom": "uatom",
  "min_commission_rate": "0.050000000000000000",  // we are changing this from 0.000000000000000000
    "validator_bond_factor": "-1.000000000000000000",
  "global_liquid_staking_cap": "1.000000000000000000",
  "validator_liquid_staking_cap": "1.000000000000000000"
   }
  }
 ],
 "metadata": "ipfs://CID",
  "deposit": "1000000uatom",
  "title": "Updating the staking params (min_comission_rate)",
  "summary": "This proposal will attempt to update the min_commission_rate staking parameter. During proposal creation and submission **all** proposal fields must be specified. Pay attention that you don't unintentionally specify different values for fields that you did not intend to change."
}
最后,我们提交提案:
gaiad tx gov submit-proposal <path_to_proposal.json>
   --from <submitter address> \
   --chain-id cosmoshub-4 \
   --gas <max gas allocated> \
   --fees <fees allocated> \
   --node <node address> \
使用 gaiad tx gov --help 可以获取更多 CLI 选项信息,下面我们会解释其中的一些选项:
  1. --from 是支付交易手续费和存款金额的账户密钥。该账户密钥必须已经保存在你设备的 keyring 中,并且必须是你控制的地址(例如 --from hypha-dev-wallet)。
  2. --gas 是处理该交易所允许使用的最大 gas 数量(例如 --gas 500000)。
    • 你的提案描述内容越多,交易消耗的 gas 就越多
    • 如果该数值不够高,交易在处理时 gas 不足,就会失败。
    • 交易只会消耗处理该交易实际所需的 gas 数量。
  3. --fees 是给予验证者处理该交易的固定费率激励。
    • 许多节点会设置最低手续费,以抑制垃圾交易。
    • 7500uatom 等于 0.0075 ATOM。
  4. --node 表示使用一个已建立的节点将交易发送到 Cosmos Hub 4 网络。可用节点请查看 Chain Registry。
注意:请谨慎设置 --fees。这里的失误可能会导致你意外花费数百甚至数千个 ATOM,而且无法追回。

验证你的交易

在发布交易后,命令行接口(gaiad)会返回该交易的哈希。你可以使用 gaiad 进行查询,或者在 Mintscan 中搜索该交易哈希。哈希看起来大致如下:0506447AE8C7495DE970736474451CF23536DF8EA837FAF1CF6286565589AB57。 或者,你也可以使用以下命令检查你的 Tx 状态和信息:
gaiad q tx <hash>

排查失败的交易

交易失败的原因可能有很多。下面是两个示例:
  1. Gas 不足 - 交易中包含的数据越多,处理时所需的 gas 就越多。如果你没有指定足够的 gas,交易就会失败。
  2. 面额不正确 - 你可能填写了 utom 或 atom,而不是 uatom,从而导致交易失败。
如果你遇到问题,请先尝试自行排查,然后再到 Cosmos Hub 论坛寻求帮助:链接。我们可以从失败的尝试中学习,并据此不断改进本指南。

提案提交后追加存款

有时,提案在尚未存入最低代币数量的情况下就已经提交。在这种情况下,你可能需要追加更多代币,使提案进入投票阶段。要存入代币,你需要在提交提案后知道该提案的 ID。你可以通过以下命令查询所有提案:
gaiad q gov proposals
如果链上已经有很多提案,你也可以按自己的地址进行筛选。对于上面的提案,对应命令如下:
gaiad q gov proposals --depositor cosmos1hxv7mpztvln45eghez6evw2ypcw4vjmsmr8cdx
拿到提案 ID 后,可以使用以下命令追加存入代币:
gaiad tx gov deposit <proposal-id> <deposit_amount> --from <name>
每次存款的金额等于 min_deposit * min_deposit_ratio。存款面额仅支持 uatom。当 deposit_amount < (min_deposit * min_deposit_ratio) 时,交易会被拒绝。

将提案提交到测试网

提交到测试网与提交到主网基本相同,只有少数几点不同:
  1. 链 ID 是 theta-testnet-001。
  2. 可用端点列表可在这里查看。
  3. 你需要测试网代币,而不是 ATOM。开发者 Discord 中提供了水龙头。
出于多种原因,你可能会希望先将提案提交到测试网,再提交到主网:
  1. 查看提案描述最终会如何显示。
  2. 传递你的提案即将在主网上线的信号。
  3. 提前向相关方分享提案的展示效果。
  4. 测试治理功能是否正常。

If you have a final draft of your proposal ready to submit, you may want to push your proposal live on the testnet first. These are the three primary steps to getting your proposal live on-chain. Interacting with the Cosmos Hub via the command line in order to run queries or submit proposals has several prerequisites:
  • You will need to compile gaiad from source into a binary file executable by your operating system eg. MacOS, Windows, Linux
  • You will need to indicate which chain you are querying, and currently this is --chain-id cosmoshub-4
  • You will need to connect to a full node. You can find a list of available Cosmos Hub endpoints under the API section in the Chain Registry.
  • More info is in the Walkthrough Example section.
Running a full node can be difficult for those not technically-inclined, so you may choose to use a third-party’s full node. In this case, the primary security risk is that of censorship: it’s the single place where you have a single gateway to the network, and any messages submitted through an untrusted node could be censored.

Hosting supplementary materials

In general we try to minimize the amount of data pushed to the blockchain. Hence, detailed documentation about a proposal is usually hosted on a separate censorship resistant data-hosting platform, like IPFS. Once you have drafted your proposal, ideally as a Markdown file, you can upload it to the IPFS network:
  1. By running an IPFS node and the IPFS software, or
  2. By using a service such as Link
Ensure that you “pin” the file so that it continues to be available on the network. You should get a URL like this: Link The value QmbkQNtCAdR1CNbFE8ujub2jcpwUcmSRpSCg8gVWrTHSWD is called the CID of your file - it is effectively the file’s hash. If you uploaded a markdown file, you can use the IPFS markdown viewer to render the document for better viewing. Links for the markdown viewer look like https://ipfs.io/ipfs/QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/example#/ipfs/<CID>, where <CID> is your CID. For instance the link above would be: Link Share the URL with others and verify that your file is publicly accessible. The reason we use IPFS is that it is a decentralized means of storage, making it resistant to censorship or single points of failure. This increases the likelihood that the file will remain available in the future.

Formatting the JSON file for the governance proposal

Prior to sending the transaction that submits your proposal on-chain, you must create a JSON file. This file will contain the information that will be stored on-chain as the governance proposal. Begin by creating a new text (.txt) file to enter this information. Use these best practices as a guide for the contents of your proposal. When you’re done, save the file as a .json file. Each proposal type is unique in how the JSON should be formatted. See the relevant section for the type of proposal you are drafting: Once on-chain, most people will rely upon block explorers to interpret this information with a graphical user interface (GUI).

Sending the transaction that submits your governance proposal

For information on how to use gaiad (the command line interface) to submit an on-chain proposal through the governance module, please refer to the gaiad CLI tutorials for the Cosmos Hub documentation.

Proposal types

There are 2 proposal types that can be submitted to the CosmosHub governance module.

Legacy proposals (cosmos-sdk < v0.47)

These proposals can be submitted using gaiad tx gov submit-legacy-proposal. Available proposals that can be submitted using this Tx are:
  • cancel-software-upgrade
  • change-reward-denoms
  • consumer-addition
  • consumer-removal
  • ibc-upgrade
  • param-change (does not work for standard cosmos-sdk modules, works on IBC and ICS modules)
  • software-upgrade
  • update-client
You can read more about submitting a legacy proposal in the cosmos-sdk docs

Proposals (cosmos-sdk >= v0.47)

These proposals can be submitted using gaiad tx gov submit-proposal. Using gaiad tx gov draft-proposal can help prepare a proposal. The tool will create a file containing the specified proposal message and it also helps with populating all the required proposal fields. You can always edit the file after you create it using draft-proposal Most cosmos-sdk modules allow changing their governance gated parameters using a MsgUpdateParams which is a new way of updating governance parameters. It is important to note that MsgUpdateParams requires all parameters to be specified in the proposal message. You can read more about submitting a proposal in the cosmos-sdk docs

Minimal Deposit amount

Please note that cosmoshub-4 uses a minimum initial deposit amount.
Proposals cannot be submitted successfully without providing a minimum initial deposit. In practice, this means that the deposit field in your proposal has to meet the min_initial_deposit governance parameter. The minimum deposit is equal to min_deposit * min_initial_deposit_ratio. Only uatom is supported as deposit denom.
// checking the min_initial_deposit
gaiad q gov params -o json
{
   ...
   "params": {
      ...
      "min_deposit": [
         {
               "denom": "stake",
               "amount": "10000000"
         }
      ],
      "min_initial_deposit_ratio": "0.000000000000000000"
}

Walkthrough example (changing x/staking params)

Let’s illustrate how to change the x/staking parameters. The module has the following parameters (values don’t reflect actual on-chain values):
gaiad q staking params -o json
{
    "unbonding_time": "86400s",
    "max_validators": 100,
    "max_entries": 7,
    "historical_entries": 10000,
    "bond_denom": "stake",
    "min_commission_rate": "0.000000000000000000",
    "validator_bond_factor": "-1.000000000000000000",
    "global_liquid_staking_cap": "1.000000000000000000",
    "validator_liquid_staking_cap": "1.000000000000000000"
}
We will use draft-proposal to help us create a proposal file that we will later submit.
gaiad tx gov draft-proposal
// running the command will start a terminal applet allowing you to choose the proposal type

// 1st screen
Use the arrow keys to navigate: ↓ ↑ → ←
? Select proposal type:
    text
    community-pool-spend
    software-upgrade
    cancel-software-upgrade
  ▸ other // choose this

// 2nd screen
✔ other
Use the arrow keys to navigate: ↓ ↑ → ←
? Select proposal message type::
↑   /cosmos.staking.v1beta1.MsgUndelegate
  ▸ /cosmos.staking.v1beta1.MsgUpdateParams // choose this option
    /cosmos.staking.v1beta1.MsgValidatorBond
    /cosmos.upgrade.v1beta1.MsgCancelUpgrade
↓   /cosmos.upgrade.v1beta1.MsgSoftwareUpgrade
After choosing the /cosmos.staking.v1beta1.MsgUpdateParams message, the applet will allow you to set the message fields and some other proposal details. Upon completion, the proposal will be available in the directory where you called the gaiad command inside the draft_proposal.json file. Here is an example of the draft_proposal.json file:
{
  "messages": [
  {
  "@type": "/cosmos.staking.v1beta1.MsgUpdateParams",
  "authority": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn",
  "params": {
  "unbonding_time": "86400s",
  "max_validators": 100,
    "max_entries": 7,
    "historical_entries": 10000,
    "bond_denom": "uatom",
  "min_commission_rate": "0.050000000000000000",  // we are changing this from 0.000000000000000000
    "validator_bond_factor": "-1.000000000000000000",
  "global_liquid_staking_cap": "1.000000000000000000",
  "validator_liquid_staking_cap": "1.000000000000000000"
   }
  }
 ],
 "metadata": "ipfs://CID",
  "deposit": "1000000uatom",
  "title": "Updating the staking params (min_comission_rate)",
  "summary": "This proposal will attempt to update the min_commission_rate staking parameter. During proposal creation and submission **all** proposal fields must be specified. Pay attention that you don't unintentionally specify different values for fields that you did not intend to change."
}
Finally, we submit the proposal:
gaiad tx gov submit-proposal <path_to_proposal.json>
   --from <submitter address> \
   --chain-id cosmoshub-4 \
   --gas <max gas allocated> \
   --fees <fees allocated> \
   --node <node address> \
Use gaiad tx gov --help to get more info about the CLI options, we will explain some options below:
  1. --from is the account key that pays the transaction fee and deposit amount. This account key must be already saved in the keyring on your device and it must be an address you control (e.g. --from hypha-dev-wallet).
  2. --gas is the maximum amount of gas permitted to be used to process the transaction (e.g. --gas 500000).
    • The more content there is in the description of your proposal, the more gas your transaction will consume
    • If this number isn’t high enough and there isn’t enough gas to process your transaction, the transaction will fail.
    • The transaction will only use the amount of gas needed to process the transaction.
  3. --fees is a flat-rate incentive for a validator to process your transaction.
    • Many nodes use a minimum fee to disincentivize transaction spamming.
    • 7500uatom is equal to 0.0075 ATOM.
  4. --node is using an established node to send the transaction to the Cosmos Hub 4 network. For available nodes, please look at the Chain Registry.
Note: be careful what you use for --fees. A mistake here could result in spending hundreds or thousands of ATOMs accidentally, which cannot be recovered.

Verifying your transaction

After posting your transaction, your command line interface (gaiad) will provide you with the transaction’s hash, which you can either query using gaiad or by searching the transaction hash using Mintscan. The hash should look something like this: 0506447AE8C7495DE970736474451CF23536DF8EA837FAF1CF6286565589AB57. Alternatively, you can check your Tx status and information using:
gaiad q tx <hash>

Troubleshooting a failed transaction

There are a number of reasons why a transaction may fail. Here are two examples:
  1. Running out of gas - The more data there is in a transaction, the more gas it will need to be processed. If you don’t specify enough gas, the transaction will fail.
  2. Incorrect denomination - You may have specified an amount in ‘utom’ or ‘atom’ instead of ‘uatom’, causing the transaction to fail.
If you encounter a problem, try to troubleshoot it first, and then ask for help on the Cosmos Hub forum: Link. We can learn from failed attempts and use them to improve upon this guide.

Depositing funds after a proposal has been submitted

Sometimes a proposal is submitted without having the minimum token amount deposited yet. In these cases you would want to be able to deposit more tokens to get the proposal into the voting stage. In order to deposit tokens, you’ll need to know what your proposal ID is after you’ve submitted your proposal. You can query all proposals by the following command:
gaiad q gov proposals
If there are a lot of proposals on the chain already, you can also filter by your own address. For the proposal above, that would be:
gaiad q gov proposals --depositor cosmos1hxv7mpztvln45eghez6evw2ypcw4vjmsmr8cdx
Once you have the proposal ID, this is the command to deposit extra tokens:
gaiad tx gov deposit <proposal-id> <deposit_amount> --from <name>
The amount per deposit is equal to min_deposit * min_deposit_ratio. Only uatom is supported as deposit denom. Transactions where deposit_amount < (min_deposit * min_deposit_ratio) will be rejected.

Submitting your proposal to the testnet

Submitting to the testnet is identical to mainnet submissions aside from a few changes:
  1. The chain-id is theta-testnet-001.
  2. The list of usable endpoints can be found here.
  3. You will need testnet tokens, not ATOM. There is a faucet available in the Developer Discord.
You may want to submit your proposal to the testnet chain before the mainnet for a number of reasons:
  1. To see what the proposal description will look like.
  2. To signal that your proposal is about to go live on the mainnet.
  3. To share what the proposal will look like in advance with stakeholders.
  4. To test the functionality of the governance features.