Skip to main content

多重签名

Sui 支持多重签名(multisig)交易,这需要多个密钥进行授权,而不是单一的、单密钥签名。在技术术语中,Sui 支持 kn 多重签名交易,其中 k 是阈值,n 是所有参与方的总权重。最大参与方数量为 10。要了解 Sui 支持的单密钥签名,详见签名

多重签名的有效参与密钥是纯 Ed25519、ECDSA Secp256k1 和 ECDSA Secp256r1。每个参与密钥都设置一个 u8 权重,阈值可以设置为 u16。如果序列化的多重签名包含足够数量的有效签名,其权重之和超过阈值,Sui 将视为多重签名有效,并执行交易。

多重签名的应用

Sui 允许你在单个多重签名帐户中混合和匹配密钥方案。例如,你可以选择一个基于单个 Ed25519 助记词的密钥和两个 ECDSA secp256r1 密钥,以创建一个多重签名帐户,始终需要 Ed25519 密钥,但也需要其中一个 ECDSA secp256r1 密钥进行签名。你可以将此结构用于将移动安全区存储的密钥用作双因素身份验证。

info

目前,iPhone 和高端 Android 设备仅支持 ECDSA secp256r1 安全区存储的密钥。

与阈值签名相比,多重签名帐户通常更灵活、更容易实现和使用,无需复杂的多方计算(MPC)帐户设置仪式和相关软件,也无需依赖阈值密码提供者。此外,除了能够混合和匹配密钥方案和为每个密钥设置不同的权重(这在阈值密码学中较为复杂)之外,多重签名帐户还是“可核实”和“透明”的设计,因为参与方和观察者都可以看到谁签署了每个交易。另一方面,阈值签名提供了隐藏阈值策略的好处,但也导致单个签名负载,使其与单一密钥帐户无法区分。

Sui 多重签名中支持的结构 Sui 中支持的多重签名结构。

示例工作流

以下步骤演示如何创建多重签名交易,然后使用 Sui CLI 将其提交到本地网络。交易可以是对象的转移、包的发布或升级、对 SUI 的支付等。要了解如何设置本地网络,请参见连接到本地网络

第 1 步:创建密钥

使用以下命令生成每种支持的密钥方案的 Sui 地址和密钥,并将其添加到 sui.keystore,然后列出这些密钥。

使用 sui client 来创建不同密钥方案的 Sui 地址。

sui client new-address ed25519
sui client new-address secp256k1
sui client new-address secp256r1

第 2 步:将密钥添加到 Sui 密钥库

使用 sui keytool 列出上一步中创建的签名。

sui keytool list

回应类似于以下内容,但显示的是实际的地址、密钥和对等标识符:

╭────────────────────────────────────────────────────────────────────────────────────────────╮
│ ╭─────────────────┬──────────────────────────────────────────────────────────────────────╮ │
│ │ suiAddress │ <SUI-ADDRESS> │ │
│ │ publicBase64Key │ <PUBLIC-KEY> │ │
│ │ keyScheme │ ed25519 │ │
│ │ flag │ 0 │ │
│ │ peerId │ <PEER-ID> │ │
│ ╰─────────────────┴──────────────────────────────────────────────────────────────────────╯ │
│ ╭─────────────────┬──────────────────────────────────────────────────────────────────────╮ │
│ │ suiAddress │ <SUI-ADDRESS> │ │
│ │ publicBase64Key │ <PUBLIC-KEY> │ │
│ │ keyScheme │ secp256k1 │ │
│ │ flag │ 0 │ │
│ │ peerId │ <PEER-ID> │ │
│ ╰─────────────────┴──────────────────────────────────────────────────────────────────────╯ │
│ ╭─────────────────┬──────────────────────────────────────────────────────────────────────╮ │
│ │ suiAddress │ <SUI-ADDRESS> │ │
│ │ publicBase64Key │ <PUBLIC-KEY> │ │
│ │ keyScheme │ secp256r1 │ │
│ │ flag │ 0 │ │
│ │ peerId │ <PEER-ID> │ │
│ ╰─────────────────┴──────────────────────────────────────────────────────────────────────╯ │
╰────────────────────────────────────────────────────────────────────────────────────────────╯

第 3 布:创建多重签名地址

为了创建一个多重签名地址,请输入用于多重签名地址的公钥列表、它们对应的权重列表和阈值(用实际的值替换 <VARIABLES>)。

sui keytool multi-sig-address --pks <PUBLIC-KEY-ED25519> <PUBLIC-KEY-SECPK1> <PUBLIC-KEY-SECP256R1> --weights 1 2 3 --threshold 3

回应类似于以下内容:

╭─────────────────┬────────────────────────────────────────────────────────────────────────────────────╮
│ multisigAddress │ <MULTISIG-ADDRESS> │
│ multisig │ ╭────────────────────────────────────────────────────────────────────────────────╮ │
│ │ │ ╭─────────────────┬──────────────────────────────────────────────────────────╮ │ │
│ │ │ │ address │ <SUI-ADDRESS> │ │ │
│ │ │ │ publicBase64Key │ <PUBLIC-KEY> │ │ │
│ │ │ │ weight │ 1 │ │ │
│ │ │ ╰─────────────────┴──────────────────────────────────────────────────────────╯ │ │
│ │ │ ╭─────────────────┬──────────────────────────────────────────────────────────╮ │ │
│ │ │ │ address │ <SUI-ADDRESS> │ │ │
│ │ │ │ publicBase64Key │ <PUBLIC-KEY> │ │ │
│ │ │ │ weight │ 2 │ │ │
│ │ │ ╰─────────────────┴──────────────────────────────────────────────────────────╯ │ │
│ │ │ ╭─────────────────┬──────────────────────────────────────────────────────────╮ │ │
│ │ │ │ address │ <SUI-ADDRESS> │ │ │
│ │ │ │ publicBase64Key │ <PUBLIC-KEY> │ │ │
│ │ │ │ weight │ 3 │ │ │
│ │ │ ╰─────────────────┴──────────────────────────────────────────────────────────╯ │ │
│ │ ╰────────────────────────────────────────────────────────────────────────────────╯ │
╰─────────────────┴────────────────────────────────────────────────────────────────────────────────────╯

第4步:向多重签名地址发送对象

此示例使用默认 URL 从本地网络请求 gas,遵循 连接到本地网络 中的指导。如果在跟随进行操作,请确保用前一步中获得的地址替换 <MULTISIG-ADDR>

curl --location --request POST 'http://127.0.0.1:9123/gas' --header 'Content-Type: application/json' --data-raw "{ \"FixedAmountRequest\": { \"recipient\": \"<MULTISIG-ADDR>\" } }"

响应类似于以下内容:

{"transferred_gas_objects":[{"amount":200000,"id":"<OBJECT-ID>", ...}]}

步骤5:序列化任何交易

本节演示如何使用属于多签地址的对象,并将要签名的转账序列化。tx_bytes 值可以是任何序列化的交易数据,其中发送者是多签地址。在sui client -h的支持命令中(publishupgradecalltransfertransfer-suipaypay-all-suipay-suisplitmerge-coin),使用--serialize-unsigned-transaction标志以输出Base64编码的交易字节。

sui client transfer --to <SUI-ADDRESS> --object-id <OBJECT-ID> --gas-budget <GAS-AMOUNT> --serialize-unsigned-transaction

Raw tx_bytes to execute: <TX_BYTES>

步骤6:使用两个密钥签名交易

使用以下代码示例,使用sui.keystore中的两个密钥对交易进行签名。只要将其序列化为flag || sig || pk,你可以使用其他工具完成此操作。

sui keytool sign --address <SUI-ADDRESS> --data <TX_BYTES>

Raw tx_bytes to execute: <TX_BYTES>
Serialized signature (`flag || sig || pk` in Base64): $SIG_1

sui keytool sign --address <SUI-ADDRESS> --data <TX_BYTES>

Raw tx_bytes to execute: <TX_BYTES>
Serialized signature (`flag || sig || pk` in Base64): $SIG_2

步骤7:将单个签名合并为多签名

此示例演示如何将两个签名合并:

sui keytool multi-sig-combine-partial-sig --pks <PUBLIC-KEY-1> <PUBLIC-KEY-2> <PUBLIC-KEY-3> --weights 1 2 3 --threshold 3 --sigs <SIGNATURE-1> <SIGNATURE-2>

multisig address: <MULTISIG-ADDRESS> # Informational
multisig parsed: <HUMAN-READABLE-STRUCT> # Informational
multisig serialized: <SERIALIZED-MULTISIG>

你只需要参与签名的签署者的签名,其权重总和>=k。你必须提供所有公钥及其权重,以及定义多签地址的阈值。

步骤8:使用多签执行交易

使用sui client来执行使用多签的交易:

sui client execute-signed-tx --tx-bytes <TX_BYTES> --signatures <SERIALIZED-MULTISIG>