Skip to content
🎉 Welcome to the new Aptos Docs! Click here to submit feedback!
BuildCLIWorking With Move ContractsMultisig Governance Tutorial

多签治理教程

背景

这部分内容是以JSON 中的参数教程为基础展开的。如果你尚未完成那个教程,请先行阅读并实践它。

此外,这个教程也会用到 CliArgs 示例包

ℹ️

如果你准备学习这一部分,那么请确保你已经按照JSON 中的参数教程的步骤进行了学习。

在本例中,Ace 和 Bee 将通过一个 2-of-2 形式的“多签版本 2 (multisig v2)”账户来执行治理操作。所谓 “2-of-2”,意味着需要至少两个账户的签名才能完成操作,这一账户类型是按照 multisig_account.move 文件中定义的。

创建账户

既然 Ace 的账户已经在 JSON 中的参数教程中创建,我们接下来为 Bee 也生成一个个性化地址(vanity address)账户吧:

Terminal
aptos key generate \
    --vanity-prefix 0xbee \
    --output-file bee.key
Output
Terminal
{
  "Result": {
    "PublicKey Path": "bee.key.pub",
    "PrivateKey Path": "bee.key",
    "Account Address:": "0xbeec980219d246581cef5166dc6ba5fb1e090c7a7786a5176d111a9029b16ddc"
  }
}
ℹ️

The exact account address should vary for each run, though the vanity prefix should not. 每次生成的确切账户地址会有所不同,但是个性化(vanity)的前缀部分将保持不变。

把 Bee 的地址存入一个 shell 变量里,便于你之后直接使用这个变量进行操作:

Terminal
# Your exact address should vary
bee_addr=0xbeec980219d246581cef5166dc6ba5fb1e090c7a7786a5176d111a9029b16ddc

通过水龙头(faucet)为 Bee 的账户打入资金:

Terminal
aptos account fund-with-faucet --account $bee_addr
Output
Terminal
{
  "Result": "Added 100000000 Octas to account beec980219d246581cef5166dc6ba5fb1e090c7a7786a5176d111a9029b16ddc"
}

此时,Ace 可以创建一个多重签名账户:

Terminal
aptos multisig create \
    --additional-owners $bee_addr \
    --num-signatures-required 2 \
    --private-key-file ace.key \
    --assume-yes
Output
Terminal
{
  "Result": {
    "multisig_address": "57478da34604655c68b1dcb89e4f4a9124b6c0ecc1c59a0931d58cc4e60ac5c5",
    "transaction_hash": "0x849cc756de2d3b57210f5d32ae4b5e7d1f80e5d376233885944b6f3cc2124a05",
    "gas_used": 1524,
    "gas_unit_price": 100,
    "sender": "acef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46",
    "sequence_number": 5,
    "success": true,
    "timestamp_us": 1685078644186194,
    "version": 528428043,
    "vm_status": "Executed successfully"
  }
}

把这个多重签名账户的地址也保存到一个 shell 变量中:

Terminal
# Your address should vary
multisig_addr=0x57478da34604655c68b1dcb89e4f4a9124b6c0ecc1c59a0931d58cc4e60ac5c5

检查多重签名账户

利用 multisig_account.move view 函数来详细了解这个多重签名账户的情况:

需要提供的签名数
aptos move view \
    --function-id 0x1::multisig_account::num_signatures_required \
    --args \
        address:"$multisig_addr"
Output
Terminal
{
  "Result": [
    "2"
  ]
}
Owners
aptos move view \
    --function-id 0x1::multisig_account::owners \
    --args \
        address:"$multisig_addr"
Output
Terminal
{
  "Result": [
    [
      "0xbeec980219d246581cef5166dc6ba5fb1e090c7a7786a5176d111a9029b16ddc",
      "0xacef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46"
    ]
  ]
}
最后解决的序号
aptos move view \
    --function-id 0x1::multisig_account::last_resolved_sequence_number \
    --args \
        address:"$multisig_addr"
Output
Terminal
{
  "Result": [
    "0"
  ]
}
下一个序号
aptos move view \
    --function-id 0x1::multisig_account::next_sequence_number \
    --args \
        address:"$multisig_addr"
Output
Terminal
{
  "Result": [
    "1"
  ]
}

提交一个发布交易的队列(enqueued)

第一个排队的多签交易将是一个为了发布 CliArgs 示例包 的交易。

首先创建一个包含发布信息的 JSON 文件:

Command
aptos move build-publish-payload \
    --named-addresses test_account=$multisig_addr \
    --json-output-file publication.json \
    --assume-yes
Output
Terminal
{
  "Result": "Publication payload entry function JSON file saved to publication.json"
}

接着让 Ace 提议从多签账户发布这个包,但链上只记录(payload)相关信息的哈希值:

Command
aptos multisig create-transaction \
    --multisig-address $multisig_addr \
    --json-file publication.json \
    --store-hash-only \
    --private-key-file ace.key \
    --assume-yes
Output
Terminal
{
  "Result": {
    "transaction_hash": "0x70c75903f8e1b1c0069f1e84ef9583ad8000f24124b33a746c88d2b031f7fe2c",
    "gas_used": 510,
    "gas_unit_price": 100,
    "sender": "acef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46",
    "sequence_number": 6,
    "success": true,
    "timestamp_us": 1685078836492390,
    "version": 528429447,
    "vm_status": "Executed successfully"
  }
}

注意目前最新完成的交易序列号仍为 0,因为还没有任何交易完成处理:

最后解决的序号
aptos move view \
    --function-id 0x1::multisig_account::last_resolved_sequence_number \
    --args \
        address:"$multisig_addr"
Output
Terminal
{
  "Result": [
    "0"
  ]
}

然而,由于已经提交了一个交易至处理队列,下一个序列号已经增加:

下一个序号
aptos move view \
    --function-id 0x1::multisig_account::next_sequence_number \
    --args \
        address:"$multisig_addr"
Output
Terminal
{
  "Result": [
    "2"
  ]
}

现在,我们可以检查已提交至链上的多签交易了:

获取交易
aptos move view \
    --function-id 0x1::multisig_account::get_transaction \
    --args \
        address:"$multisig_addr" \
        String:1
Output
Terminal
{
  "Result": [
    {
      "creation_time_secs": "1685078836",
      "creator": "0xacef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46",
      "payload": {
        "vec": []
      },
      "payload_hash": {
        "vec": [
          "0x62b91159c1428c1ef488c7290771de458464bd665691d9653d195bc28e0d2080"
        ]
      },
      "votes": {
        "data": [
          {
            "key": "0xacef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46",
            "value": true
          }
        ]
      }
    }
  ]
}

从结果可见,交易相关的具体内容未在链上保存,并且 Ace 在提交提议的时候隐式地批准了交易(即投票赞成)。

治理参数交易队列(Enqueue)

接下来由 Bee 队列(enqueue)一个治理参数设置的交易,并把整个交易的详细信息直接保存(payload)在区块链上:

Command
aptos multisig create-transaction \
    --multisig-address $multisig_addr \
    --function-id $multisig_addr::cli_args::set_vals \
    --type-args \
        0x1::account::Account \
        0x1::chain_id::ChainId \
    --args \
        u8:123 \
        "bool:[false, true, false, false]" \
        'address:[["0xace", "0xbee"], ["0xcad"], []]' \
    --private-key-file bee.key \
    --assume-yes
Output
Terminal
{
  "Result": {
    "transaction_hash": "0xd0a348072d5bfc5a2e5d444f92f0ecc10b978dad720b174303bc6d91342f27ec",
    "gas_used": 511,
    "gas_unit_price": 100,
    "sender": "beec980219d246581cef5166dc6ba5fb1e090c7a7786a5176d111a9029b16ddc",
    "sequence_number": 0,
    "success": true,
    "timestamp_us": 1685078954841650,
    "version": 528430315,
    "vm_status": "Executed successfully"
  }
}

注意,交易队列的序号又增加了:

下一个序号
aptos move view \
    --function-id 0x1::multisig_account::next_sequence_number \
    --args \
        address:"$multisig_addr"
Output
Terminal
{
  "Result": [
    "3"
  ]
}

目前,包发布交易和治理参数设置交易都已提交,正处于待执行的状态:

获取待处理的交易
aptos move view \
    --function-id 0x1::multisig_account::get_pending_transactions \
    --args \
        address:"$multisig_addr"
Output
Terminal
{
  "Result": [
    [
      {
        "creation_time_secs": "1685078836",
        "creator": "0xacef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46",
        "payload": {
          "vec": []
        },
        "payload_hash": {
          "vec": [
            "0x62b91159c1428c1ef488c7290771de458464bd665691d9653d195bc28e0d2080"
          ]
        },
        "votes": {
          "data": [
            {
              "key": "0xacef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46",
              "value": true
            }
          ]
        }
      },
      {
        "creation_time_secs": "1685078954",
        "creator": "0xbeec980219d246581cef5166dc6ba5fb1e090c7a7786a5176d111a9029b16ddc",
        "payload": {
          "vec": [
            "0x0057478da34604655c68b1dcb89e4f4a9124b6c0ecc1c59a0931d58cc4e60ac5c508636c695f61726773087365745f76616c7302070000000000000000000000000000000000000000000000000000000000000001076163636f756e74074163636f756e740007000000000000000000000000000000000000000000000000000000000000000108636861696e5f696407436861696e49640003017b0504000100006403020000000000000000000000000000000000000000000000000000000000000ace0000000000000000000000000000000000000000000000000000000000000bee010000000000000000000000000000000000000000000000000000000000000cad00"
          ]
        },
        "payload_hash": {
          "vec": []
        },
        "votes": {
          "data": [
            {
              "key": "0xbeec980219d246581cef5166dc6ba5fb1e090c7a7786a5176d111a9029b16ddc",
              "value": true
            }
          ]
        }
      }
    ]
  ]
}

执行包发布的交易

因为只有 Ace 对包发布的交易进行了投票(他在提交提议时就默认同意了),所以这个交易目前还不能执行:

是否可以被执行
aptos move view \
    --function-id 0x1::multisig_account::can_be_executed \
    --args \
        address:"$multisig_addr" \
        String:1
Output
Terminal
{
  "Result": [
    false
  ]
}

不过,在 Bee 投票前,她先核对了链上存储的哈希值与包发布的 JSON 文件是否一致:

验证交易提案
aptos multisig verify-proposal \
    --multisig-address $multisig_addr \
    --json-file publication.json \
    --sequence-number 1
Output
Terminal
{
  "Result": {
    "Status": "Transaction match",
    "Multisig transaction": {
      "creation_time_secs": "1685078836",
      "creator": "0xacef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46",
      "payload": {
        "vec": []
      },
      "payload_hash": {
        "vec": [
          "0x62b91159c1428c1ef488c7290771de458464bd665691d9653d195bc28e0d2080"
        ]
      },
      "votes": {
        "data": [
          {
            "key": "0xacef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46",
            "value": true
          }
        ]
      }
    }
  }
}

验证无误后,Bee 确信链上记录的哈希与她本地编译的包发布的 JSON 文件相符,于是她投了赞成票:

批准交易
aptos multisig approve \
    --multisig-address $multisig_addr \
    --sequence-number 1 \
    --private-key-file bee.key \
    --assume-yes
Output
Terminal
{
  "Result": {
    "transaction_hash": "0xa5fb49f1077de6aa6d976e6bcc05e4c50c6cd061f1c87e8f1ea74e7a04a06bd1",
    "gas_used": 6,
    "gas_unit_price": 100,
    "sender": "beec980219d246581cef5166dc6ba5fb1e090c7a7786a5176d111a9029b16ddc",
    "sequence_number": 1,
    "success": true,
    "timestamp_us": 1685079892130861,
    "version": 528437204,
    "vm_status": "Executed successfully"
  }
}

现在,这个交易已经被执行了:

是否能够被执行
aptos move view \
    --function-id 0x1::multisig_account::can_be_executed \
    --args \
        address:"$multisig_addr" \
        String:1
Output
Terminal
{
  "Result": [
    true
  ]
}

此时,无论是 Ace 还是 Bee 都有权利通过多重签名账户发起包发布交易,但是需要提交完整的交易详情,因为在区块链上仅记录了这些详情的哈希值:

Publication
aptos multisig execute-with-payload \
    --multisig-address $multisig_addr \
    --json-file publication.json \
    --private-key-file bee.key \
    --max-gas 10000 \
    --assume-yes
ℹ️

由于#8304问题尚未解决,导致用于估算 Gas 费用的交易模拟器(transaction simulator)目前无法使用,所以执行交易时你需要手动设置一个最大的 Gas 使用量。

Output

此外,受同一问题#8304影响,使用命令行界面(CLI)成功执行多签的包发布交易后,如果链上只有哈希值而没有详细信息,则会显示一个 API 错误,不过你可以用区块链浏览器来手动检查交易情况。

执行治理参数的交易

目前只有 Bee 对这项治理参数交易投了票(她在提出这个提议时就表达了支持),所以现在还不能执行交易:

是否能否被执行
aptos move view \
    --function-id 0x1::multisig_account::can_be_executed \
    --args \
        address:"$multisig_addr" \
        String:2
Output
Terminal
{
  "Result": [
    false
  ]
}

然而,在 Ace 投票之前,他会核实链上记录的交易信息是否与他所预期要处理的功能参数一致:

验证交易提案
aptos multisig verify-proposal \
    --multisig-address $multisig_addr \
    --function-id $multisig_addr::cli_args::set_vals \
    --type-args \
        0x1::account::Account \
        0x1::chain_id::ChainId \
    --args \
        u8:123 \
        "bool:[false, true, false, false]" \
        'address:[["0xace", "0xbee"], ["0xcad"], []]' \
    --sequence-number 2
Output
Terminal
{
  "Result": {
    "Status": "Transaction match",
    "Multisig transaction": {
      "creation_time_secs": "1685078954",
      "creator": "0xbeec980219d246581cef5166dc6ba5fb1e090c7a7786a5176d111a9029b16ddc",
      "payload": {
        "vec": [
          "0x0057478da34604655c68b1dcb89e4f4a9124b6c0ecc1c59a0931d58cc4e60ac5c508636c695f61726773087365745f76616c7302070000000000000000000000000000000000000000000000000000000000000001076163636f756e74074163636f756e740007000000000000000000000000000000000000000000000000000000000000000108636861696e5f696407436861696e49640003017b0504000100006403020000000000000000000000000000000000000000000000000000000000000ace0000000000000000000000000000000000000000000000000000000000000bee010000000000000000000000000000000000000000000000000000000000000cad00"
        ]
      },
      "payload_hash": {
        "vec": []
      },
      "votes": {
        "data": [
          {
            "key": "0xbeec980219d246581cef5166dc6ba5fb1e090c7a7786a5176d111a9029b16ddc",
            "value": true
          }
        ]
      }
    }
  }
}

需要注意的是,一旦 Ace 更改任何一个参数,那么核实过程将不会通过:

由于修改了 u8 类型数据,交易验证失败。
aptos multisig verify-proposal \
    --multisig-address $multisig_addr \
    --function-id $multisig_addr::cli_args::set_vals \
    --type-args \
        0x1::account::Account \
        0x1::chain_id::ChainId \
    --args \
        u8:200 \
        "bool:[false, true, false, false]" \
        'address:[["0xace", "0xbee"], ["0xcad"], []]' \
    --sequence-number 2
Output
Terminal
{
  "Error": "Unexpected error: Transaction mismatch: The transaction you provided has a payload hash of 0xe494b0072d6f940317344967cf0e818c80082375833708c773b0275f3ad07e51, but the on-chain transaction proposal you specified has a payload hash of 0x070ed7c3f812f25f585461305d507b96a4e756f784e01c8c59901871267a1580. For more info, see https://aptos.dev/move/move-on-aptos/cli#multisig-governance"
}

Ace 对这次交易表示了支持:

批准交易
aptos multisig approve \
    --multisig-address $multisig_addr \
    --sequence-number 2 \
    --private-key-file ace.key \
    --assume-yes
Output
Terminal
{
  "Result": {
    "transaction_hash": "0x233427d95832234fa13dddad5e0b225d40168b4c2c6b84f5255eecc3e68401bf",
    "gas_used": 6,
    "gas_unit_price": 100,
    "sender": "acef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46",
    "sequence_number": 7,
    "success": true,
    "timestamp_us": 1685080266378400,
    "version": 528439883,
    "vm_status": "Executed successfully"
  }
}

由于交易信息已经保存在链上,就不必执行那些待处理的交易了:

Execution
aptos multisig execute \
    --multisig-address $multisig_addr \
    --private-key-file ace.key \
    --max-gas 10000 \
    --assume-yes
Output
Terminal
{
  "Result": {
    "transaction_hash": "0xbc99f929708a1058b223aa880d04607a78ebe503367ec4dab23af4a3bdb541b2",
    "gas_used": 505,
    "gas_unit_price": 100,
    "sender": "acef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46",
    "sequence_number": 8,
    "success": true,
    "timestamp_us": 1685080344045461,
    "version": 528440423,
    "vm_status": "Executed successfully"