Skip to content

与团体预编译交互

Precomiled Contracts Banner

概览

团体预编译能够使用户直接从Solidity接口与Substrate的团体pallet交互。

团体是一个群组,其成员负责具体的民主相关行动,例如提议、投票、执行、结束提案。每位成员都能够执行不同来源的不同动作。因此,可以创建具有特定范围的团体。举例来说,Moonbeam有三个团体:理事会团体、技术委员会团体和财政库委员会团体。因此,每个团体都有一个预编译。关于理事会和技术委员会的更多信息,请参阅Moonbeam治理页面,关于财政库委员会的更多信息,请参阅Moonbeam财政库页面。

本教程将向您展示如何使用团体预编译进行提议、投票、结束提案。

团体预编译位于以下地址:

团体 地址
理事会 0x000000000000000000000000000000000000080e
技术委员会 0x000000000000000000000000000000000000080f
财政库委员会 0x0000000000000000000000000000000000000810
团体 地址
理事会 0x000000000000000000000000000000000000080e
技术委员会 0x000000000000000000000000000000000000080f
财政库委员会 0x0000000000000000000000000000000000000810
团体 地址
理事会 0x000000000000000000000000000000000000080e
技术委员会 0x000000000000000000000000000000000000080f
财政库委员会 0x0000000000000000000000000000000000000810

注意事项

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

团体Solidity接口

Collective.sol是一个Solidity接口,允许开发者与预编译的5个方式进行交互。

接口包含以下函数:

  • execute(bytes memory proposal) - 作为团体内的单个成员执行提案。发送者必须为团体中的成员。如果Substrate提案已派送但失败,将不会恢复
  • propose(uint32 threshold, bytes memory proposal) - 增加一个要投票的新提案。发送者必须为团体中的成员。若数值小于2,则提案者将作为派送者直接派送并执行提案。若达到设定的数值,则返回新提案的索引
  • vote(bytes32 proposalHash, uint32 proposalIndex, bool approve) - 为提案进行投票。发送者必须为团体中的成员
  • close(bytes32 proposalHash, uint32 proposalIndex, uint64 proposalWeightBound, uint32 lengthBound) - 结束提案。投票达到足够的数量后可由任何人调用。返回一个布尔值,表示提案被执行或移除
  • proposalHash(bytes memory proposal) - 计算提案的哈希

其中需要提供的输入值可以定义为如下:

  • proposal - SCALE编码的Substrate调用,此调用用于提议动作
  • threshold - 派送提案所需的成员数量
  • proposalHash - 提案的哈希
  • proposalIndex - 提案的索引
  • approve - 投票赞成/否决提案
  • proposalWeightBound - 提案可以使用的最大Substrate权重值。如果提案调用使用更多,调用将恢复
  • lengthBound - 大于或等于SCALE编码提案长度的值(以字节为单位)

接口包含以下事件:

  • Executed(bytes32 proposalHash) - 提案执行时触发
  • Proposed(address indexed who, uint32 indexed proposalIndex, bytes32 indexed proposalHash, uint32 threshold) - 提案成功提交并可执行或投票时触发
  • Voted(address indexed who, bytes32 indexed proposalHash, bool voted) - 提案投票时触发
  • Closed(bytes32 indexed proposalHash) 提案结束时触发

与Solidity接口交互

此部分示例将向您展示如何使用财政库委员会团体预编译提交财政库提案。因此,该提案将需要满足财政库委员会的投票要求。财政库提案至少需要3/5的财政库委员会投票才能通过。另一方面,需要至少1/2的财政库委员会投票才能拒绝提案。另外请注意,您必须是财政库委员会的一员才能提议和投票提案。

如果您不是Moonbeam、Moonriver或Moonbase Alpha财政库委员会的一员,您可以使用Moonbeam开发节点测试团体预编译的功能。Moonbeam开发节点将会自带10个预注资的账户,其中Baltathar、Charleth和Dorothy被自动设置为财政库委员会团体的成员。您可以使用这三个账号的任何一个来完成以下教程。

查看先决条件

此教程的示例将在Moonbeam开发节点上进行操作,但这也同样适用于其他任何基于Moonbeam的网络。

开始操作之前,您将需要准备以下内容:

  • 安装MetaMask并连接至基于Moonbeam的网络
  • 准备一个拥有资金的账户。如果使用的是Moonbeam开发节点,则开发账户已经注入资金。如果使用的是Moonbeam、Moonriver或Moonbase Alpha,您将需要充值一定资金到您的账户。 您可以每24小时一次从Moonbase Alpha水龙头上获取DEV代币以在Moonbase Alpha上进行测试

如果您使用的是Moonbeam开发节点和开发账户,您将需要完成以下操作:

Remix设置

  1. 获取Collective.sol的副本
  2. 将文件内容复制并粘贴至名为Collective.solRemix文件

Copying and Pasting the Collective Interface into Remix

编译合约

  1. 点击Compile标签(从上至下第二个)
  2. 编译接口,点击Compile Collective.sol

Compiling Collective.sol

访问合约

  1. 点击Remix中Compile正下方的Deploy and Run标签。请注意,您不是在此处部署合约,而是访问已经部署的预编译合约
  2. 确保在ENVIRONMENT下拉菜单中选择Injected Provider - Metamask
  3. 确保在CONTRACT下拉菜单中选择Collective - Collective.sol。因为这是一个预编译合约,因此无需部署,相反您需要在At Address字段中提供预编译的地址
  4. 提供团体预编译的地址0x0000000000000000000000000000000000000810并点击At Address
  5. 团体预编译将出现在Deployed Contracts列表中

Access the precompile contract

创建提案

要提交需要通过财政库委员会团体投票的提案,您首先必须创建一个财政库提案。如果您想要投票的财政库提案已经存在且已经拥有提案的索引,您可以跳过此步骤直接进入下一部分。

要提交财政库提案,您可以用过Polkadot.js Apps的财政库页面来完成。在本示例中,您可以创建一个简单的提案,即向Alith发送10个DEV Token用于主办社群活动。为此,点击Submit proposal,并填写以下内容:

  1. submit with account下拉菜单中,选择您想要用于提交提案的账户。提案所需的保证金将从此账户提取
  2. 选择beneficiary,在本示例中为Alith
  3. value一栏输入10
  4. 点击Submit proposal后签署并提交提案

Submit a treasury proposal

您将在proposals部分看到您创建的提案出现。如果这是您创建的首个提案,则提案的索引为0(这将用于下一部分)。要查看所有的提案,您可以导向至Developer标签,选择Chain State并执行以下步骤:

  1. selected state query下拉菜单中选择treasury
  2. 选择proposals extrinsic
  3. include option滑块关闭
  4. 点击+提交查询
  5. 结果将在下方显示,包括提案索引和提案详情

View all treasury proposals

现在您已经拥有提案及其索引,您可以使用团体预编译在下一部分批准提案。

提出提案

要使用团体预编译提出提案以便对应团体可以投票,您将需要获取调用的编码调用数据,以通过提案执行。您可以从Polkadot.js Apps得到编码的调用数据。在此示例中,您需要提议treasury pallet的approveProposal extrinsic。为此,导向至Developer标签,选择Extrinsics,然后执行以下步骤:

  1. 选择一个账号(任何一个账号即可,您不会在此处用该账号提交任何交易)
  2. 选择treasury pallet
  3. 选择approveProposal extrinsic
  4. 输入提案索引,以便团体投票批准
  5. 为提案复制encoded call data(编码的调用数据)

Get encoded proposal

在本示例中,提案的extrinsic编码调用数据为0x110200

使用编码后的提案,您可以返回Remix并在Deployed Contracts部分展开COLLECTIVE预编译合约。确保您已连接至您的账户,且此账户为财政库委员会成员,并执行以下步骤提出批准:

  1. 展开propose函数
  2. 输入threshold。请注意财政库提案通过至少需要3/5的财政库委员会投票通过。因此,在本示例中您可以将其设为2
  3. proposal字段,您可以复制从Polkadot.js Apps检索获得的编码提案
  4. 点击transact
  5. MetaMask将会跳出弹窗要求您确认交易

Propose the approval

为提案进行投票

要为提案进行投票,您需要将编码后的提案传入到proposalHash函数来获取提案哈希。

Get the proposal hash

获取提案哈希之后,请确保您已经连接至财政库委员会成员的账号,然后执行以下步骤:

  1. 在Remix中展开vote函数
  2. 输入proposalHash
  3. 输入proposalIndex
  4. approve字段输入true
  5. 点击transact
  6. MetaMask将会跳出弹窗要求您确认交易

Vote on the proposal

将阈值设置为2后,您需要在MetaMask将账号切换成另一个财政库委员会团体成员并重复上述步骤投票以达到阈值。当达到阈值后,您可以结束提案,这意味着提案将自动执行。如果获得批准,提案会进入费用支出的等待列队,提案申请的金额将分配给受益人。在本示例中,当提案进入费用支出期,10个DEV Token将返还给Alith。

结束提案

如果提案拥有足够的投票,任何人可以结束提案。您无需成为财政库委员会成员以结束提案。要结束提案,您需要执行以下步骤:

  1. 展开close函数
  2. 输入proposalHash
  3. 输入proposalIndex
  4. 输入proposalWeightBound,在本示例中可以设为1000000000
  5. 输入lengthBound,此数值可以大于或等于提案编码调用数据的长度。在本示例中,编码调用数据为0x110200,因此您可以将此数值设置为8
  6. 点击transact
  7. MetaMask将会跳出弹窗要求您确认交易

Close the proposal

您可以使用Polkadot.js Apps验证提案是否通过。在Developer标签处选择Chain State,并执行以下步骤:

  1. 选择treasury pallet
  2. 选择approvals extrinsic
  3. 点击+以提交查询
  4. 提案将会出现在批准列表中

Review the treasury approvals

当提案进入费用支出期,提案申请的金额将分配给受益人,初始的保证金将返还给提案者。若财政库用完所有的资金,已批准的提案将一直保存到下一个支出期,即当财政库再次拥有足够的资金。