Skip to content

与民主预编译交互

Democracy Moonbeam Banner

概览

作为波卡(Polkadot)的平行链和去中心化网络,Moonbeam具有原生链上治理功能,使利益相关者能够参与网络的发展方向。要了解有关治理的更多信息,例如相关术语、原则、机制等的概述,请参阅Moonbeam治理页面。

随着OpenGov(最初称为 Governance v2)的推出,对治理流程进行了多项修改。 OpenGov已经在Moonriver上线,经过严格测试后,将提出在Moonbeam上线的提案。在那之前,Moonbeam仍然使用Goverance v1。民主预编译适用于Governance v1,因此,本指南仅适用于Moonbeam。如果您希望与Moonriver上的治理功能进行交互,您应该查看与OpenGov相关的预编译:原像预编译公投预编译信念投票预编译

Moonbeam的链上治理系统得益于Substrate民主pallet。民主pallet使用Rust语言实现,无法直接从Moonbeam的以太坊API交互。然而,民主预编译让您能够直接通过Solidity接口直接访问Substrate民主pallet的治理功能。除此之外,这将能够大幅度改进终端用户的操作体验。举例而言,Token持有者将能够直接使用MetaMask进行公投,无需将账户导入Polkadot.js App后使用复杂的界面进行操作。

民主预编译目前在OpenGov(仅存在Moonriver和Moonbase Alpha上)中可用。 如果您正在寻找仍在Governance v1上的Moonbeam的类似功能,您可以参考Democracy Precompile文档。

民主预编译位于以下地址:

0x0000000000000000000000000000000000000803

注意事项

在Moonbeam使用预编译合约时,可能会出现一些意想不到的后果。 请参阅安全注意事项 页面了解更多信息。

民主预编译Solidity接口

DemocracyInterface.sol是一个能够用于Solidity合约与民主pallet交互的接口。预编译的精妙之处在于您无需学习Substrate API,就可以使用熟悉的以太坊界面与质押功能交互。

接口包含以下函数:

  • publicPropCount() —— 获取过去和现在提案总数的只读函数。调用民主pallet的publicPropCount方法
  • depositOf(uint256 propIndex) —— 获取提案中锁定Token总数量的只读函数。调用民主pallet的depositOf方法
  • lowestUnbaked() —— 获取当前公投中索引排序最低的公投的只读函数。详细来说,Baked Referendum为已结束(或是已通过和已制定执行日期)的公投。Unbaked Referendum则为正在进行中的公投。调用民主pallet的lowestUnbaked方法
  • ongoingReferendumInfo(uint256 refIndex) —— 返回特定进行中公投的以元组形式表达的只读函数,内容包含以下:
    • 公投结束区块(uint256
    • 提案哈希(bytes32
    • the biasing mechanism0为SuperMajorityApprove,1为SuperMajorityAgainst,2为SimpleMajority (uint256)
    • 执行延迟时间(uint256
    • 总同意票数,包含Token锁定时间参数(Conviction)(uint256
    • 总反对票数,包含Token锁定时间参数(uint256
    • 当前投票结果,不包含Token锁定时间参数(uint256
  • finishedReferendumInfo(uint256 refIndex) —— 返回公投是否通过以及结束区块信息的只读函数
  • propose(bytes32 proposalHash, uint256 value) —— 通过提交哈希和锁定的Token数量提交提案。调用民主pallet的propose方法
  • second(uint256 propIndex, uint256 secondsUpperBound) —— 通过提供提案索引编码和大于或等于现有附议此提案的数字以附议一个提案(必须计算权重)。不需要数量,因为附议这个动作需要具有与原先提案者锁定相同的数量。调用民主pallet的second方法
  • standardVote(uint256 refIndex, bool aye, uint256 voteAmount, uint256 conviction) )—— 通过提供提案索引编号、投票趋向(true为执行此提案,false为保持现状)、锁定的Token数量以及“信念值”,来进行投票。“信念值”为06之间的一个数字,0代表没有锁定时间,而6代表最大锁定时间。调用民主pallet的vote方法
  • removeVote(uint256 refIndex) —— 此函数用于在逾期的民主锁定之前于特定公投上移除投票。请注意,移除投票不能在提案投票进行中时撤销或是取消
  • delegate(address representative, uint256 candidateCount, uint256 amount) —— 通过提供需要被委托的特定账户信息、用于所有委托投票的Token锁定之间函数以及用于委托的Token数量的“信念值”系数,以委托其投票权力至其他账户。调用民主pallet的delegate方法
  • unDelegate() —— 为委托人用于解除投票权力的函数。在原先委托指令中的Token锁定时间参数被解除后,Token将会解锁并能够领取。调用民主pallet的undelegate方法
  • unlock(address target) —— 解锁逾期锁定的Token。在使用unlock之前,您必须为各个提案所锁定的Token调用removeVote,不然这些Token将会保持锁定。这个函数能够被任何账户调用。调用民主pallet的unlock方法
  • notePreimage(bytes encodedProposal) —— 为即将到来的提案注册一个原像(Preimage)。此函数不需要提案处于调度队列中,但需要押金以进行操作,押金将会在提案生效后返还。调用民主pallet的notePreimage方法
  • noteImminentPreimage(bytes encodedProposal) —— 为即将到来的提案注册一个原像(Preimage)。此函数需要提案处在调度队列中,同时不需要任何押金。当调用成功,例如:原像(Preimage)尚未被上传且与近期的提案相匹配,不支付任何费用。调用民主pallet的noteImminentPreimage 方法

此接口也包含以下事件:

  • Proposed(uint32 indexed proposalIndex, uint256 deposit) - 在提议动议时发出
  • Seconded(uint32 indexed proposalIndex, address seconder) - 当账户附议提案时发出
  • StandardVote(uint32 indexed referendumIndex, address voter, bool aye, uint256 voteAmount, uint8 conviction) - 当账户进行标准投票时发出
  • Delegated(address indexed who, address target) - 当一个账户将一些投票权委托给另一个账户时发出
  • Undelegated(address indexed who) - 当一个账户从另一个账户取消了他们的部分投票权时发出

与Solidity接口交互

查看先决条件

以下为在Moonbase Alpha网络的操作演示,然而,您能够在Moonbeam和Moonriver采用类似的步骤。

在进入操作接口之前,您可以先熟悉在Moonbeam上如何提案如何投票

除此之外,您还需要:

设置Remix

  1. 点击File explorer标签
  2. 复制DemocracyInterface.sol并粘贴至命名为Democracy.solRemix文件中

Copying and Pasting the Democracy Interface into Remix

编译合约

  1. 点击位于由上至下第二个的Compile标签

  2. 然后编译接口,点击Compile Democracy.sol

Compiling DemocracyInteface.sol

获取合约

  1. 点击位于Remix的Compile标签正下方的Deploy and Run标签。请注意:您并不是在此部署合约,您是在获取一个已经部署的预编译合约
  2. 确认在ENVIRONMENT下拉菜单中的Injected Provider - Metamask已被选取
  3. 确保Democracy.sol已在CONTRACT下拉菜单中被选去。由于此为预编译合约,并不需要进行部署,您需要的是在At Address中提供预编译合约的地址
  4. 为Moonbase Alpha提供民主预编译的地址:0x0000000000000000000000000000000000000803 并点击At Address
  5. 此民主预编译将会出现在Deployed Contracts列表中

Provide the address

提交提案

如果您有提案的原像哈希,您可以通过民主预编译propose函数提交提案。但是,在提交提案之前,您首先需要通过将编码的提案数据传递给notePreimage函数来提交原像,该函数现在属于原像Pallet

在本节中,您将获得提案的原像哈希和编码后的提案数据。要获取原像哈希,您首先需要导航至Polkadot.js AppsPreimage页面:

  1. 导航至Governance 标签页
  2. 从下拉菜单里选择Preimages
  3. Preimages页面点击+ Add preimage

Add a new preimage

然后执行以下步骤:

  1. 选取一个账户(任何账户皆可,因为您不需要提交任何交易)
  2. 选取您希望交互的pallet以及可调度的函数(或是动作)以进行提案。您选取的动作将会决定您随后的操作步骤。在此例子中,此为system pallet和remark函数
  3. 输入remark函数的内容,确保其为独特的。重复的提案如“Hello World!”将不会被接受
  4. 复制原像哈希,这代表着此提案。您将会在通过民主预编译提交提案时使用此哈希
  5. 点击Submit preimage按钮,但请不要在下一页签署和确认此交易

Get the proposal hash

在下个页面,根据以下步骤进行操作:

  1. 点击三角形图像以显示字节状态下带编码的提案
  2. 复制带编码的提案——您将在随后步骤中使用notePreimage时用到它

Get the encoded proposal

注意事项

不要在此签署和提交交易。您将会在随后步骤中通过notePreimage提交此信息。

在此步骤,您将会使用您在Polkadot.JS Apps获得的编码后的提案,并通过民主预编译中的notePreimage函数提交。尽管其名称,即原像(Preimage)并不需要在提案之前提交。然而,提交原像仍然需要在提案能够执行前进行提交。请跟随以下步骤通过notePreimage函数提交原像:

  1. 展开民主预编译合约以查看可用函数
  2. 找到notePreimage函数并点击按钮以展开区块
  3. 复制您在先前获得的编码后的提案。请注意,编码后的提案与原像(Preimage)哈希不同。请确认您输入的是正确的数值
  4. 点击transact并在MetaMask确认交易

Submit the preimage

接下来您可以通过以下步骤调用Solidity接口的propose函数:

  1. 展开民主预编译合约以查看可用函数
  2. 寻找propose函数并点击按钮展开区块
  3. 输入提案哈希
  4. 输入以Wei为单位的Token数值来绑定。最低绑定数量为400 GLMR,4 MOVR或是4 DEV。以此例而言为4 DEV或是已经输入的4000000000000000000
  5. 点击transact并在MetaMask确认交易

Call the propose function

在您交易确认后您可以回到Polkadot.JS AppsDemocracy页面中确认您的提案是否在提案列表当中。

附议提案

附议提案将能够使其进入公投阶段,但需要绑定与先前提案者相同的Token数量。被附议的提案转移至公投需要一定时间,在Moonbase Alpha为1日,在Moonriver为1日,在Moonbeam为7日。

首先,您将需要获得您希望支持的提案的相关信息。当您在先前的步骤中提交提案,其将会有至少一个提案处于列表当中。您可以跟随以下步骤在Polkadot.js Apps中获得提案的索引编码:

  1. 导向至Governance标签
  2. 点击Democracy
  3. 寻找Proposals区块并点击三角形图示查看提案的更多细节
  4. 记录提案号码,此为您需要的首个参数
  5. 记录已附议的数字。如果并没有任何支持,此区块将会保持空白

Get the proposal information

现在,您可以回到Remix以通过民主预编译附议提案,请跟随以下步骤进行操作:

  1. 如其尚未展开,展开民主预编译合约以查看可用函数
  2. 寻找second函数并点击按钮以展开区块
  3. 输入提案编码以附议
  4. 虽然您要支持的提案编码已经记录如上,此时仍然需要参数上线。为避免出现gas预计错误,您需要输入明显大于附议数量的数字,在此例中输入的数字为10
  5. 点击transact并在MetaMask确认此交易

恭喜您已成功!如需查看您支持的提案,您可以返回Polkadot.js Apps并查看您的账户是否出现在支持列表当中

Second via the precompile

注意事项

提案编码与公投编码不同。当提案进入公投状态,其将会获得新的公投索引编码。

在公投中进行投票

获得附议的提案转移至公投状态需要一定时间,在Moonbeam为7日,在Moonriver为1,在Moonbase为1。如果在Moonbase Alpha中没有正在进行中的公投,您可能需要等待启用阶段以度过您支持提案的转移时间,方能进入公投阶段。

首先,如果您希望进行投票,您需要获得公投的编码。记住,提案编码与公投编码两者不同。您可以跟随以下步骤在Polkadot.js Apps上获得公投编码:

  1. 导向至Governance标签
  2. 点击Democracy
  3. 查看Referenda区块,并点击三角形图示以查看更多关于公投的信息。如果并没有看见三角形图示,这代表仅仅有提案哈希,提案的原像(Preimage)并没有被提交
  4. 记录公投编码

Get the referendum index

现在,您可以准备返回至Remix以通过民主预编译在公投进行投票,请跟随以下步骤进行操作:

  1. 展开民主预编译合约以查看可用函数
  2. 寻找standardVote函数并点击按钮以查看区块
  3. 输入公投编码以进行投票
  4. 将此字段留空表示否定(Nay)或输入1表示赞成(Aye)。在公投的背景下,"Nay"是保持现状不变的投票,"Aye"是通过公投提议
  5. 输入以Wei表示的Token数量,避免输入您的全部余额,因为您仍然需要支付交易费用
  6. 输入位于0-6之间的Token锁定时间参数,这代表您希望锁定用以投票的Token的时间,0代表无锁定时间,6代表最大锁定时间。关于更多锁定时间的信息,请查看如何投票教程。
  7. 点击transact并在MetaMask确认此交易

Call the vote function

恭喜,您已完成在民主预编译教程中的全部步骤。除此之外,仍有数个函数被记录与DemocracyInterface.sol当中,如果您对于那些函数或是民主预编译有任何问题,欢迎至我们官方Discord询问。

Last update: March 27, 2023
| Created: February 14, 2022