开发
多签账户

多签账户

本文档介绍多签账户的使用,包括如何通过 Rooch CLI 在链上创建多签账户,以及如何发起多签交易,如何签名交易,如何广播交易。

概述

Rooch 作为 Bitcoin 的 L2,Rooch 提供了 L1 交易和 L2 交易的多签功能。本文首先演示 L1 交易,即演示 Bitcoin 的原生资产 BTC 的多签交易,然后演示 L2 交易,即演示 Rooch 的 RGAS 的多签交易。

准备账户公钥

接下来准备 3 个账户来演示多签账户的功能。

通过 rooch account create 创建好账户,通过 rooch account list --json 可以查看对应账户的公钥。

$ rooch account list --json

{
  "account1": {
    "address": "rooch1hh9p0twq7yze06tys4lp2dzh3k6s4jgrcu68vqnr5ku8cwuaprjq0y8pml",
    "hex_address": "0xbdca17adc0f10597e964857e1534578db50ac903c734760263a5b87c3b9d08e4",
    "bitcoin_address": "tb1pmmx3fk9e2umvshm4r8j6va9xcrmp2s75r96upfxxyhp8mwyfwwssrql720",
    "nostr_public_key": "npub1ttel8sev7svd5zkw3hmte2wanc33x57uct2nkvgn3vp9djyh67wswma74z",
    "public_key": "0x035af3f3c32cf418da0ace8df6bca9dd9e231353dcc2d53b31138b0256c897d79d",    <= Note here!
    "has_session_key": false,
    "active": false
  },
  "account0": {
    "address": "rooch1r2xgp9uyf7elphd39mssdtf8s99wgjm3fywazgfcdf7pzhnx637skura9n",
    "hex_address": "0x1a8c8097844fb3f0ddb12ee106ad27814ae44b71491dd121386a7c115e66d47d",
    "bitcoin_address": "tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg",
    "nostr_public_key": "npub15te2hf6a65zs8jgu83l33mskc99sm98m8vu4rfsjmujjg7y0xc5sf0u9uy",
    "public_key": "0x02a2f2aba75dd50503c91c3c7f18ee16c14b0d94fb3b3951a612df2524788f3629",    <= Note here!
    "has_session_key": false,
    "active": false
  },
  "default": {
    "address": "rooch1qe8s8rkcds2q0xxq9xhjmfq2mxgs4zmjvlle7dmtnrthndzes0uqmhwzzr",
    "hex_address": "0x064f038ed86c140798c029af2da40ad9910a8b7267ff9f376b98d779b45983f8",
    "bitcoin_address": "tb1ph25pk4xm36y3mt6uwclm0fgj8dgdnf5u7xf987qvyv58x987cldsefe2dh",
    "nostr_public_key": "npub192ydmn6ctgucuc47t4x504844e0grrlt4uztlfr9l44g83a2dw0se6k3p8",
    "public_key": "0x022a88ddcf585a398e62be5d4d47d4f5ae5e818febaf04bfa465fd6a83c7aa6b9f",    <= Note here!
    "has_session_key": false,
    "active": true
  }
}

L1 交易演示

这次我们将多签地址上的 BTC 转移到 tb1pmmx3fk9e2umvshm4r8j6va9xcrmp2s75r96upfxxyhp8mwyfwwssrql720 这个地址。

创建多签

rooch account create-multisign -t 2 -p $Pubkey1 -p $Pubkey2 -p $Pubkey3
  • -t--threshold 指定多签的门限数。假如,指定 3 个账户生成的多签账户,指定 -t 2 则表示 3 个账户中需要任意 2 个账户共同签名交易,这笔多签交易才能够验证。
  • -p--public-keys 指定参与多签的账户公钥。
$ rooch account create-multisign -t 2 -p 0x022a88ddcf585a398e62be5d4d47d4f5ae5e818febaf04bfa465fd6a83c7aa6b9f -p 0x02a2f2aba75dd50503c91c3c7f18ee16c14b0d94fb3b3951a612df2524788f3629 -p 0x035af3f3c32cf418da0ace8df6bca9dd9e231353dcc2d53b31138b0256c897d79d

MulitsignAddress: rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty
Multisign Bitcoin Address: tb1przxwx6xdyehpnspdr70jaqjm4g62dedcm4gcvf62qu6xjae6e8tq4mpqvn
Threshold: 2
Participants: 3
Participant 0 Address: rooch1qe8s8rkcds2q0xxq9xhjmfq2mxgs4zmjvlle7dmtnrthndzes0uqmhwzzr
Participant 0 Bitcoin Address: tb1ph25pk4xm36y3mt6uwclm0fgj8dgdnf5u7xf987qvyv58x987cldsefe2dh
Participant 0 Public Key: 0x022a88ddcf585a398e62be5d4d47d4f5ae5e818febaf04bfa465fd6a83c7aa6b9f
Participant 1 Address: rooch1r2xgp9uyf7elphd39mssdtf8s99wgjm3fywazgfcdf7pzhnx637skura9n
Participant 1 Bitcoin Address: tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg
Participant 1 Public Key: 0x02a2f2aba75dd50503c91c3c7f18ee16c14b0d94fb3b3951a612df2524788f3629
Participant 2 Address: rooch1hh9p0twq7yze06tys4lp2dzh3k6s4jgrcu68vqnr5ku8cwuaprjq0y8pml
Participant 2 Bitcoin Address: tb1pmmx3fk9e2umvshm4r8j6va9xcrmp2s75r96upfxxyhp8mwyfwwssrql720
Participant 2 Public Key: 0x035af3f3c32cf418da0ace8df6bca9dd9e231353dcc2d53b31138b0256c897d79d

我们在 Discord 给多签地址领取 tBTC 后,将 100 sats 的 tBTC 转账到一个没有余额的账户,这里演示的目标账户为 tb1pmmx3fk9e2umvshm4r8j6va9xcrmp2s75r96upfxxyhp8mwyfwwssrql720

# 切换到要转账的目标地址
$ rooch account switch --address tb1pmmx3fk9e2umvshm4r8j6va9xcrmp2s75r96upfxxyhp8mwyfwwssrql720
The active account was successfully switched to `rooch1hh9p0twq7yze06tys4lp2dzh3k6s4jgrcu68vqnr5ku8cwuaprjq0y8pml`
 
# 查看目标地址的余额
$ rooch account balance
                                              Coin Type                                                |      Symbol      | Decimals |             Balance     
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                               Bitcoin                                                 |       BTC        |    8     |                 0       

可以看到目标地址的余额为 0 sats。

生成多签交易

rooch bitcoin build-tx --sender $multisign_bitcoin_address -o $to_address:amount_sats
  • --sender 指定多签账户地址。
  • -o 指定交易输出,即转账的比特币地址和比特币的数量(单位为 sats),这里使用 : 分隔。
$ rooch bitcoin build-tx --sender tb1przxwx6xdyehpnspdr70jaqjm4g62dedcm4gcvf62qu6xjae6e8tq4mpqvn -o tb1pmmx3fk9e2umvshm4r8j6va9xcrmp2s75r96upfxxyhp8mwyfwwssrql720:100
 
{
  "content": "70736274ff0100890200000001cc96ee0d7eb17ebc2c1087c2c06d81d2596440b61d0abac4db830461779a5fdd0100000000fdffffff026400000000000000225120decd14d8b95736c85f7519e5a674a6c0f61543d41975c0a4c625c27db88973a19082010000000000225120baa81b54db8e891daf5c763fb7a5123b50d9a69cf19253f80c23287314fec7db000000000001012ba086010000000000225120baa81b54db8e891daf5c763fb7a5123b50d9a69cf19253f80c23287314fec7db2206022a88ddcf585a398e62be5d4d47d4f5ae5e818febaf04bfa465fd6a83c7aa6b9f0400000000000000",
  "output_type": "psbt",
  "path": "/tmp/305da9d77a2af176.psbt"
}

此时这笔多签交易存放在 /tmp/305da9d77a2af176.psbt 这个文件里,接下来我们会使用多签参与者的账户来对这笔交易进行签名。

签名交易

rooch bitcoin sign-tx -s $Pubkey1_address /tmp/xxxxx.psbt
rooch bitcoin sign-tx -s $Pubkey2_address /tmp/xxxxx.psbt
  • -s 指定多签参与者公钥的地址。

第一个参与者,这里为 tb1ph25pk4xm36y3mt6uwclm0fgj8dgdnf5u7xf987qvyv58x987cldsefe2dh

$ rooch bitcoin sign-tx -s tb1ph25pk4xm36y3mt6uwclm0fgj8dgdnf5u7xf987qvyv58x987cldsefe2dh /tmp/305da9d77a2af176.psbt
Transaction details before signing:
  Version: 2
  Lock time: 0
  Inputs:
    Input 0:
      Previous output: dd5f9a77610483dbc4ba0a1db6406459d2816dc0c287102cbc7eb17e0dee96cc:1
      Sequence: 4294967293
      Script pubkey: OP_PUSHNUM_1 OP_PUSHBYTES_32 baa81b54db8e891daf5c763fb7a5123b50d9a69cf19253f80c23287314fec7db
  Outputs:
    Output 0:
      Value: 0.00000100 BTC
      Script pubkey: OP_PUSHNUM_1 OP_PUSHBYTES_32 decd14d8b95736c85f7519e5a674a6c0f61543d41975c0a4c625c27db88973a1
    Output 1:
      Value: 0.00098960 BTC
      Script pubkey: OP_PUSHNUM_1 OP_PUSHBYTES_32 baa81b54db8e891daf5c763fb7a5123b50d9a69cf19253f80c23287314fec7db
 
Do you want to sign this transaction? [yes/no] >
yes
{
  "content": "02000000000101cc96ee0d7eb17ebc2c1087c2c06d81d2596440b61d0abac4db830461779a5fdd0100000000fdffffff026400000000000000225120decd14d8b95736c85f7519e5a674a6c0f61543d41975c0a4c625c27db88973a19082010000000000225120baa81b54db8e891daf5c763fb7a5123b50d9a69cf19253f80c23287314fec7db0140ac2f1e5e911948450ce37e4033b502edf0750ae04078231f13d382d0efdec3ca1368b9bea7f0bb92d3053baa61ead56ed71796886a57721cc2b2c4acd9412ebb00000000",
  "output_type": "tx",
  "path": "/tmp/305da9d77a2af176.tx"
}

第二个参与者,这里为 tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg

$ rooch bitcoin sign-tx -s tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg /tmp/305da9d77a2af176.psbt
Transaction details before signing:
  Version: 2
  Lock time: 0
  Inputs:
    Input 0:
      Previous output: dd5f9a77610483dbc4ba0a1db6406459d2816dc0c287102cbc7eb17e0dee96cc:1
      Sequence: 4294967293
      Script pubkey: OP_PUSHNUM_1 OP_PUSHBYTES_32 baa81b54db8e891daf5c763fb7a5123b50d9a69cf19253f80c23287314fec7db
  Outputs:
    Output 0:
      Value: 0.00000100 BTC
      Script pubkey: OP_PUSHNUM_1 OP_PUSHBYTES_32 decd14d8b95736c85f7519e5a674a6c0f61543d41975c0a4c625c27db88973a1
    Output 1:
      Value: 0.00098960 BTC
      Script pubkey: OP_PUSHNUM_1 OP_PUSHBYTES_32 baa81b54db8e891daf5c763fb7a5123b50d9a69cf19253f80c23287314fec7db
 
Do you want to sign this transaction? [yes/no] >
yes
{
  "content": "02000000000101cc96ee0d7eb17ebc2c1087c2c06d81d2596440b61d0abac4db830461779a5fdd0100000000fdffffff026400000000000000225120decd14d8b95736c85f7519e5a674a6c0f61543d41975c0a4c625c27db88973a19082010000000000225120baa81b54db8e891daf5c763fb7a5123b50d9a69cf19253f80c23287314fec7db0140ed98589b4abc20b02f9cb66492cddc02239b36712d53d3c88ac61ff67ddb0b9b748aeb270d8857a7229b8268bce4de073d328514246619117ff9cf998067bf5e00000000",
  "output_type": "tx",
  "path": "/tmp/305da9d77a2af176.tx"
}

当多签交易满足门限数后,我们就可以将这笔多签交易广播出去,交易就会上链了。

广播交易

rooch bitcoin broadcast-tx /tmp/xxxxx.tx

多签参与者对多签的交易签名后,会在相同的目录生成一个 .tx 文件,此处为 /tmp/305da9d77a2af176.tx,这个文件存放着这笔多签交易的内容,我们将这笔交易广播出去,就会上链了。

[joe@mx ~]$ rooch bitcoin broadcast-tx /tmp/305da9d77a2af176.tx
"59142915d9a1f301dcd26120fe747a18a9e577cb9d357eae76f12a7ad7a95d30"

接下来,我们检查一下目标账户的余额:

$ rooch account balance
                                              Coin Type                                                |      Symbol      | Decimals |             Balance     
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                               Bitcoin                                                 |       BTC        |    8     |                100      

目前,我们的目标账户已经有了 100 sats 的 BTC 了。

L2 交易演示

这次我们将多签地址上的 RGAS 转移到 tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg 这个地址上,此时这个地址上还没有这个币:

$ rooch account balance --address tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg
 
                                              Coin Type                                                |      Symbol      | Decimals |             Balance     
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                               Bitcoin                                                 |       BTC        |    8     |                 0       

我们将演示从多签账户转 5000 RGAS 到上面这个账户。

创建多签

注意:如果上面已经生成过了,可以跳过这一步!

$ rooch account create-multisign -t 2 -p 0x022a88ddcf585a398e62be5d4d47d4f5ae5e818febaf04bfa465fd6a83c7aa6b9f -p 0x02a2f2aba75dd50503c91c3c7f18ee16c14b0d94fb3b3951a612df2524788f3629 -p 0x035af3f3c32cf418da0ace8df6bca9dd9e231353dcc2d53b31138b0256c897d79d
 
MulitsignAddress: rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty
Multisign Bitcoin Address: tb1przxwx6xdyehpnspdr70jaqjm4g62dedcm4gcvf62qu6xjae6e8tq4mpqvn
Threshold: 2
Participants: 3
Participant 0 Address: rooch1qe8s8rkcds2q0xxq9xhjmfq2mxgs4zmjvlle7dmtnrthndzes0uqmhwzzr
Participant 0 Bitcoin Address: tb1ph25pk4xm36y3mt6uwclm0fgj8dgdnf5u7xf987qvyv58x987cldsefe2dh
Participant 0 Public Key: 0x022a88ddcf585a398e62be5d4d47d4f5ae5e818febaf04bfa465fd6a83c7aa6b9f
Participant 1 Address: rooch1r2xgp9uyf7elphd39mssdtf8s99wgjm3fywazgfcdf7pzhnx637skura9n
Participant 1 Bitcoin Address: tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg
Participant 1 Public Key: 0x02a2f2aba75dd50503c91c3c7f18ee16c14b0d94fb3b3951a612df2524788f3629
Participant 2 Address: rooch1hh9p0twq7yze06tys4lp2dzh3k6s4jgrcu68vqnr5ku8cwuaprjq0y8pml
Participant 2 Bitcoin Address: tb1pmmx3fk9e2umvshm4r8j6va9xcrmp2s75r96upfxxyhp8mwyfwwssrql720
Participant 2 Public Key: 0x035af3f3c32cf418da0ace8df6bca9dd9e231353dcc2d53b31138b0256c897d79d

生成多签交易

$ rooch tx build --sender tb1przxwx6xdyehpnspdr70jaqjm4g62dedcm4gcvf62qu6xjae6e8tq4mpqvn --function 0x3::transfer::transfer_coin --args address:tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg --args u256:5000 --type-args 0x3::gas_coin::RGas
 
Build transaction succeeded write to file: /tmp/b034cf66a671f0f7.rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty.rtd

这里构建好了 L2 交易,内容存放在 /tmp/b034cf66a671f0f7.rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty.rtd 这个文件里。

签名交易

我们对上面构建好的 L2 多签交易进行签名。

第一个参与者,这里为 tb1ph25pk4xm36y3mt6uwclm0fgj8dgdnf5u7xf987qvyv58x987cldsefe2dh

$ rooch tx sign -s tb1ph25pk4xm36y3mt6uwclm0fgj8dgdnf5u7xf987qvyv58x987cldsefe2dh /tmp/b034cf66a671f0f7.rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty.rtd
 
Transaction data:
 Sender: rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty
 Sequence number: 2
 Chain id: 2
 Max gas amount: 100000000
 Action: MoveAction::FunctionCall( function_id: 0x0000000000000000000000000000000000000000000000000000000000000003::transfer::transfer_coin,  type_args: [Struct(StructTag { address: 0000000000000000000000000000000000000000000000000000000000000003, module: Identifier("gas_coin"), name: Identifier("RGas"), type_params: [] })], args: ["0x1a8c8097844fb3f0ddb12ee106ad27814ae44b71491dd121386a7c115e66d47d", "0x8813000000000000000000000000000000000000000000000000000000000000"])
 Transaction hash: 0xb034…67f8
 
Do you want to sign this transaction? [yes/no] >
yes
Partially signed transaction is written to "/tmp/b034cf66a671f0f7.1.psrt"
You can send the partially signed transaction to other signers, and sign it later with `rooch tx sign /tmp/b034cf66a671f0f7.1.psrt`

当第一个参与者签名后,会生成另外一个文件,位于 /tmp/b034cf66a671f0f7.1.psrt,接下来的签名者必须对这个新的文件签名。

第二个参与者,这里为 tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg

$ rooch tx sign -s tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg /tmp/b034cf66a671f0f7.1.psrt
 
Partially signed transaction data:
 Sender: rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty
 Sequence number: 2
 Chain id: 2
 Max gas amount: 100000000
 Action: MoveAction::FunctionCall( function_id: 0x0000000000000000000000000000000000000000000000000000000000000003::transfer::transfer_coin,  type_args: [Struct(StructTag { address: 0000000000000000000000000000000000000000000000000000000000000003, module: Identifier("gas_coin"), name: Identifier("RGas"), type_params: [] })], args: ["0x1a8c8097844fb3f0ddb12ee106ad27814ae44b71491dd121386a7c115e66d47d", "0x8813000000000000000000000000000000000000000000000000000000000000"])
 Transaction hash: 0xb034…67f8
 
 Collected signatures: 1/2
Do you want to sign this transaction? [yes/no] >
yes
Signed transaction is written to "/tmp/b034cf66a671f0f7.rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty.srt"
You can submit the transaction with `rooch tx submit /tmp/b034cf66a671f0f7.rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty.srt`

这里会提示已经收集了多少个签名,以及是否签名这笔交易。

签名结束后,会得到一个已经完成多多签的交易文件 /tmp/b034cf66a671f0f7.rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty.srt,命令行会打印将交易提交到 Rooch 链上的提示。

提交交易

只需将刚才的多签交易提交到链上即可:

$ rooch tx submit /tmp/b034cf66a671f0f7.rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty.srt
 
{
  "sequence_info": {
    "tx_order": "55757601",
    "tx_order_signature": "0x01659cbc0c376a49722732f1cf23688d14f824ce39054eb9bd60023cf03a10a2be56558b8312ac2fcd882b1f47275372b11e342e1947f1cebbe92e7355853fc601026c9e5a00643a706d3826424f766bbbb08adada4dc357c1b279ad4662d2fd1e2e",
    "tx_accumulator_root": "0xa88717a0f1717d85f5cadf526eb3d6f3c13e21fbdb66e0ffd3968bf3ed635d43",
    "tx_timestamp": "1728726645361"
  },
  "execution_info": {
    "tx_hash": "0xb034cf66a671f0f74a790933a033303fe59c94c49eb9c0bd01f6cf2d7df367f8",
    "state_root": "0x967b8237c0b106fbf5ec8d2caa0cea3379dcc61294085fc4d6a7d7be2656306c",
    "event_root": "0x709227a91a0227c892255be1c80583253c132b915c4c870c03e9024a0127f830",
    "gas_used": "1021873",
    "status": {
      "type": "executed"    <= Note here!
    }
  },
...

看到执行成功的信息后,说明我们的多签交易已经执行成功!

我们查询一下账户:

$ rooch account balance --address tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg
                                              Coin Type                                                |      Symbol      | Decimals |             Balance     
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                               Bitcoin                                                 |       BTC        |    8     |                 0       
                                         0x3::gas_coin::RGas                                           |       RGAS       |    8     |                5000     

我们的目标账户已经拥有了刚才转账的 5000 RGAS 了。

这个就是 L2 多签交易的具体流程了,跟 L1 交易很相似,签名过程中需要注意命令和传递的文件名。

总结

至此,相信你已经熟悉 Rooch 在命令行下如何发送多签交易的整体流程了!