Sign with a multisig account
A multisig account is a Terra account with a special key that can require more than one signature to sign transactions. This can be useful for increasing the security of the account or for requiring the consent of multiple parties to make transactions. Multisig accounts can be created by specifying:
- threshold number of signatures required
- the public keys involved in signing
To sign with a multisig account, the transaction must be signed individually by the different keys specified for the account. Then, the signatures will be combined into a multisignature which can be used to sign the transaction. If fewer than the threshold number of signatures needed are present, the resultant multisignature is considered invalid.
Generate a Multisig key
_1terrad keys add --multisig=name1,name2,name3[...] --multisig-threshold=K new_key_name
K
is the minimum number of private keys that must have signed the transactions that carry the public key's address as signer.
The --multisig
flag must contain the name of public keys that will be combined into a public key that will be generated and stored as new_key_name
in the local database. All names supplied through --multisig
must already exist in the local database.
Unless the flag --nosort
is set, the order in which the keys are supplied on the command line does not matter, i.e. the following commands generate two identical keys:
_2terrad keys add --multisig=p1,p2,p3 --multisig-threshold=2 multisig_address_2terrad keys add --multisig=p2,p3,p1 --multisig-threshold=2 multisig_address
Multisig addresses can also be generated on-the-fly and printed through the which command:
_1terrad keys show --multisig-threshold=K name1 name2 name3 [...]
Signing a transaction
This example uses test1
, test2
, test3
keys from LocalTerra. Import them into your Terrad keystore to follow along.
Step 1: Create the multisig key
As an example, assume that test1
and test2
want to make a multisig account with test3
.
First, import the public keys of test3
into your keyring:
_3terrad keys add \_3 test3 \_3 --pubkey=terrapub1addwnpepqgcxazmq6wgt2j4rdfumsfwla0zfk8e5sws3p3zg5dkm9007hmfysxas0u2
Generate the multisig key with 2/3 threshold:
_4terrad keys add \_4 multi \_4 --multisig=test1,test2,test3 \_4 --multisig-threshold=2
You can see its address and details:
_9terrad keys show multi_9_9- name: multi_9 type: multi_9 address: terra1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m_9 pubkey: terrapub1ytql0csgqgfzd666axrjzq3mxw59ys6yqcd3ydjvhgs0uzs6kdk5fp4t73gmkl8t6y02yfq7tvfzd666axrjzq3sd69kp5usk492x6nehqjal67ynv0nfqapzrzy3gmdk27la0kjfqfzd666axrjzq6utqt639ka2j3xkncgk65dup06t297ccljmxhvhu3rmk92u3afjuyz9dg9_9 mnemonic: ""_9 threshold: 0_9 pubkeys: []
Then, add 10 LUNA to the multisig wallet:
_8terrad tx bank send \_8 test1 \_8 terra1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m \_8 10000000uluna \_8 --chain-id=localterra \_8 --gas=auto \_8 --fees=100000uluna \_8 --broadcast-mode=block
Step 2: Create the multisig transaction
Send 5 LUNA from your multisig account to terra1fmcjjt6yc9wqup2r06urnrd928jhrde6gcld6n
.
_8terrad tx bank send \_8 terra1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m \_8 terra1fmcjjt6yc9wqup2r06urnrd928jhrde6gcld6n \_8 5000000uluna \_8 --gas=200000 \_8 --fees=100000uluna \_8 --chain-id=localterra \_8 --generate-only > unsignedTx.json
The file unsignedTx.json
contains the unsigned transaction encoded in JSON.
_21{_21 "type": "core/StdTx",_21 "value": {_21 "msg": [_21 {_21 "type": "bank/MsgSend",_21 "value": {_21 "from_address": "terra1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m",_21 "to_address": "terra1fmcjjt6yc9wqup2r06urnrd928jhrde6gcld6n",_21 "amount": [{ "denom": "uluna", "amount": "5000000" }]_21 }_21 }_21 ],_21 "fee": {_21 "amount": [{ "denom": "uluna", "amount": "100000" }],_21 "gas": "200000"_21 },_21 "signatures": null,_21 "memo": ""_21 }_21}
Step 3: Sign individually
Sign with test1
and test2
and create individual signatures.
_6terrad tx sign \_6 unsignedTx.json \_6 --multisig=terra1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m \_6 --from=test1 \_6 --output-document=test1sig.json \_6 --chain-id=localterra
_6terrad tx sign \_6 unsignedTx.json \_6 --multisig=terra1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m \_6 --from=test2 \_6 --output-document=test2sig.json \_6 --chain-id=localterra
Step 4: Create multisignature
Combine signatures to sign transaction.
_5terrad tx multi-sign \_5 unsignedTx.json \_5 multi \_5 test1sig.json test2sig.json \_5 --chain-id=localterra > signedTx.json
The TX is now signed:
_45{_45 "type": "core/StdTx",_45 "value": {_45 "msg": [_45 {_45 "type": "bank/MsgSend",_45 "value": {_45 "from_address": "terra1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m",_45 "to_address": "terra1fmcjjt6yc9wqup2r06urnrd928jhrde6gcld6n",_45 "amount": [{ "denom": "uluna", "amount": "5000000" }]_45 }_45 }_45 ],_45 "fee": {_45 "amount": [{ "denom": "uluna", "amount": "100000" }],_45 "gas": "200000"_45 },_45 "signatures": [_45 {_45 "pub_key": {_45 "type": "tendermint/PubKeyMultisigThreshold",_45 "value": {_45 "threshold": "2",_45 "pubkeys": [_45 {_45 "type": "tendermint/PubKeySecp256k1",_45 "value": "AjszqFJDRAYbEjZMuiD+ChqzbUSGq/RRu3zr0R6iJB5b"_45 },_45 {_45 "type": "tendermint/PubKeySecp256k1",_45 "value": "AjBui2DTkLVKo2p5uCXf68SbHzSDoRDESKNtsr3+vtJI"_45 },_45 {_45 "type": "tendermint/PubKeySecp256k1",_45 "value": "A1xYF6iW3VSia08ItqjeBfpai+xj8tmuy/Ij3YquR6mX"_45 }_45 ]_45 }_45 },_45 "signature": "CgUIAxIBoBJA6oiaOabR1jBIbDyFj/1sYjMbYNxe+BSTnp0XYM+frC8fHxXStJ+Tl5Hf+3BsyBg1wvX1pDFsTHI7nMKNlJkKfRJAAt2cOJuViJvtwVRGwhNDORmekDSbcodnyMHTwz2Ve4db7B9m/CjYZmJtilV7zk8RWVX6Agjrl/0K5PSQZv29/A=="_45 }_45 ],_45 "memo": ""_45 }_45}
Step 5: Broadcast transaction
_3terrad tx broadcast signedTx.json \_3 --chain-id=localterra \_3 --broadcast-mode=block