Multi-signature account
This document introduces the use of multi-signature accounts, including how to create multi-signature accounts on the chain through Rooch CLI, how to initiate multi-signature transactions, how to sign transactions, and how to broadcast transactions.
Outline
Rooch As the L2 of Bitcoin, Rooch provides multi-signature functions for L1 transactions and L2 transactions. This article first demonstrates the L1 transaction, that is, the multi-signature transaction of Bitcoin's native asset BTC, and then demonstrates the L2 transaction, that is, the multi-signature transaction of Rooch's RGAS.
Prepare account public key
Next, prepare 3 accounts to demonstrate the function of multi-signature accounts.
Create an account through rooch account create, and view the public key of the corresponding account through 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 trading demo
This time we will transfer the BTC on the multi-signature address to the address tb1pmmx3fk9e2umvshm4r8j6va9xcrmp2s75r96upfxxyhp8mwyfwwssrql720.
Create multi-signature
rooch account create-multisign -t 2 -p $Pubkey1 -p $Pubkey2 -p $Pubkey3-tor--thresholdspecifies the threshold number for multi-signature. If you specify a multi-signature account generated by 3 accounts, specifying-t 2means that any 2 of the 3 accounts need to co-sign the transaction before this multi-signature transaction can be verified.-por--public-keysspecifies the public keys of accounts participating in multi-signature.
$ 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: 0x035af3f3c32cf418da0ace8df6bca9dd9e231353dcc2d53b31138b0256c897d79dAfter we claim tBTC from the multi-signature address in Discord, we transfer 100 sats of tBTC to an account with no balance. The target account demonstrated here is tb1pmmx3fk9e2umvshm4r8j6va9xcrmp2s75r96upfxxyhp8mwyfwwssrql720.
# Switch to the target address to be transferred
$ rooch account switch --address tb1pmmx3fk9e2umvshm4r8j6va9xcrmp2s75r96upfxxyhp8mwyfwwssrql720
The active account was successfully switched to `rooch1hh9p0twq7yze06tys4lp2dzh3k6s4jgrcu68vqnr5ku8cwuaprjq0y8pml`
 
# Check the balance of the target address
$ rooch account balance
                                              Coin Type                                                |      Symbol      | Decimals |             Balance     
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                               Bitcoin                                                 |       BTC        |    8     |                 0       You can see that the balance of the destination address is 0 sats.
Generate multi-signature transactions
rooch bitcoin build-tx --sender $multisign_bitcoin_address -o $to_address:amount_sats--senderspecifies the multi-signature account address.-ospecifies the transaction output, that is, the transferred Bitcoin address and the number of Bitcoins (in sats), separated by:.
$ rooch bitcoin build-tx --sender tb1przxwx6xdyehpnspdr70jaqjm4g62dedcm4gcvf62qu6xjae6e8tq4mpqvn -o tb1pmmx3fk9e2umvshm4r8j6va9xcrmp2s75r96upfxxyhp8mwyfwwssrql720:100
 
{
  "content": "70736274ff0100890200000001cc96ee0d7eb17ebc2c1087c2c06d81d2596440b61d0abac4db830461779a5fdd0100000000fdffffff026400000000000000225120decd14d8b95736c85f7519e5a674a6c0f61543d41975c0a4c625c27db88973a19082010000000000225120baa81b54db8e891daf5c763fb7a5123b50d9a69cf19253f80c23287314fec7db000000000001012ba086010000000000225120baa81b54db8e891daf5c763fb7a5123b50d9a69cf19253f80c23287314fec7db2206022a88ddcf585a398e62be5d4d47d4f5ae5e818febaf04bfa465fd6a83c7aa6b9f0400000000000000",
  "output_type": "psbt",
  "path": "/tmp/305da9d77a2af176.psbt"
}At this time, this multi-signature transaction is stored in the file /tmp/305da9d77a2af176.psbt. Next, we will use the account of the multi-signature participant to sign this transaction.
signature transaction
rooch bitcoin sign-tx -s $Pubkey1_address /tmp/xxxxx.psbt
rooch bitcoin sign-tx -s $Pubkey2_address /tmp/xxxxx.psbt-sSpecify the address of the multi-signature participant's public key.
The first participant, here is 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"
}The second participant, here is 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"
}When the multi-signature transaction meets the threshold number, we can broadcast the multi-signature transaction and the transaction will be uploaded to the chain.
Broadcast the tx
rooch bitcoin broadcast-tx /tmp/xxxxx.txAfter the multi-signature participant signs the multi-signature transaction, a .tx file will be generated in the same directory, here is /tmp/305da9d77a2af176.tx. This file stores the content of the multi-signature transaction. We will Once it is broadcast, it will be uploaded to the chain.
[joe@mx ~]$ rooch bitcoin broadcast-tx /tmp/305da9d77a2af176.tx
"59142915d9a1f301dcd26120fe747a18a9e577cb9d357eae76f12a7ad7a95d30"Next, we check the balance of the target account:
$ rooch account balance
                                              Coin Type                                                |      Symbol      | Decimals |             Balance     
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                               Bitcoin                                                 |       BTC        |    8     |                100      Currently, our target account already has 100 sats of BTC.
L2 Transaction Demo
This time we transfer the RGAS on the multi-signature address to the address tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg. At this time, there is no coin on this address:
$ rooch account balance --address tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg
 
                                              Coin Type                                                |      Symbol      | Decimals |             Balance     
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                               Bitcoin                                                 |       BTC        |    8     |                 0       We will demonstrate transferring 5000 RGAS from a multi-signature account to the account above.
Create multi-signature
Note: If it has already been generated above, you can skip this step!
$ 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: 0x035af3f3c32cf418da0ace8df6bca9dd9e231353dcc2d53b31138b0256c897d79dGenerate multi-signature transactions
$ 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.rtdThe L2 transaction is constructed here, and the content is stored in the file /tmp/b034cf66a671f0f7.rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty.rtd.
Signature transaction
We sign the L2 multi-signature transaction constructed above.
The first participant, here is 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`When the first participant signs, another file will be generated, located at /tmp/b034cf66a671f0f7.1.psrt, and the subsequent signers must sign this new file.
The second participant, here is 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`Here you will be prompted how many signatures have been collected and whether to sign the transaction.
After the signature is completed, you will get a completed transaction file /tmp/b034cf66a671f0f7.rooch1vrg7lzdml74mvhnpke9mfrvgn0esnedf3l6sn52t29qs2j5zy35s6qdlty.srt. The command line will print a prompt to submit the transaction to the Rooch chain.
Submit transaction
Just submit the multi-signature transaction just now to the chain:
$ 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!
    }
  },
...After seeing the successful execution message, it means that our multi-signature transaction has been successfully executed!
Let’s check the account:
$ rooch account balance --address tb1p488sz4vv4rnc267hd0m7st5dufpmtzv4nw70r7exyfwz60s3rhsqca94sg
                                              Coin Type                                                |      Symbol      | Decimals |             Balance     
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                               Bitcoin                                                 |       BTC        |    8     |                 0       
                                         0x3::gas_coin::RGas                                           |       RGAS       |    8     |                5000     Our target account already has the 5000 RGAS we just transferred.
This is the specific process of L2 multi-signature transaction. It is very similar to L1 transaction. During the signing process, you need to pay attention to the command and the file name passed.
Summary
At this point, I believe you are already familiar with the overall process of how Rooch sends multi-signature transactions under the command line!