Multsignature
Learn how to generate, sign, and broadcast transactions using keyring multisig.
Multi-signature account is a Dst account with a special key that requires multiple signatures to sign transactions. This is useful for increasing the security of an account or requiring multiple parties to agree to a transaction. A multi-signature account can be created by specifying:
- Threshold number of required signatures
- The public key involved in the signature
To be signed with a multisig account, the transaction must be signed individually by a different key specified for that account. The signatures are then combined into a multisig that can be used to sign transactions. If the number of signatures present is less than the required threshold number, the resulting multisig is considered invalid.
Generate a multi-signature key pair
stcd keys add --multisig=name1,name2,name3[...] --multisig-threshold=K new_key_name
K
is the minimum number of private keys that must sign a transaction with a public key address as a signer.
The --multisig
flag must contain the names of the public keys that will be combined into a single public key that will be generated and stored in the local database as new_key_name
.
All names provided via --multisig
must already exist in the local database.
The order in which keys are provided on the command line does not matter unless the flag --nosort
is set, i.e. the following command produces two identical keys:
stcd keys add --multisig=p1,p2,p3 --multisig-threshold=2 multisig_address
stcd keys add --multisig=p2,p3,p1 --multisig-threshold=2 multisig_address
Multisig addresses can also be generated on the fly and printed via the which command:
stcd keys show --multisig-threshold=K name1 name2 name3 [...]
Sign transaction
Step 1: Create a multi-signature key
Suppose you have test1
and test2
and want to create a multisignature account using test3
.
First import the public key of test3
into your keyring.
stcd keys add \
test3\
--pubkey=dstpub1addwnpepqgcxazmq6wgt2j4rdfumsfwla0zfk8e5sws3p3zg5dkm9007hmfysxas0u2
Generate a multi-signature key with a 2/3 threshold.
stcd keys add \
multi \
--multisig=test1,test2,test3 \
--multisig-threshold=2
You can see its address and details:
stcd keys show multi
- name: multi
type: multi
address: dst1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m
pubkey: dstpub1ytql0csgqgfzd666axrjzq3mxw59ys6yqcd3ydjvhgs0uzs6kdk5fp4t73gmkl8t6y02yfq7tvfzd666axrjzq3sd69kp5usk492x6nehqjal67ynv0nfqapzrz y3gmdk27la0kjfqfzd666axrjzq6utqt639ka2j3xkncgk65dup06t297ccljmxhvhu3rmk92u3afjuyz9dg9
mnemonic: ""
threshold: 0
pubkeys: []
Let's add 10 DST to the multisig wallet:
stcd tx bank send \
test1\
dst1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m\
100000000000000000000dst\
--chain-id=daodst_7000-1 \
--gas=auto \
--fees=1000000dst \
--broadcast-mode=block
Step 2: Create a multi-signature transaction
We want to send 5 DST from our multisig account to dst1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft
.
stcd tx bank send \
dst1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft\
dst157g6rn6t6k5rl0dl57zha2wx72t633axqyvvwq \
50000000000000000000dst \
--gas=200000 \
--fees=1000000dst \
--chain-id=daodst_7000-1 \
--generate-only > unsignedTx.json
The file unsignedTx.json
contains unsigned transactions encoded in JSON.
{
"body": {
"messages": [
{
"@type": "/cosmos.bank.v1beta1.MsgSend",
"from_address": "dst1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft",
"to_address": "dst157g6rn6t6k5rl0dl57zha2wx72t633axqyvvwq",
"amount": [
{
"denom": "dst",
"amount": "5000000000000000000"
}
]
}
],
"memo": "",
"timeout_height": "0",
"extension_options": [],
"non_critical_extension_options": []
},
"auth_info": {
"signer_infos": [],
"fee": {
"amount": [
{
"denom": "dst",
"amount": "1000000"
}
],
"gas_limit": "200000",
"payer": "",
"granter": ""
}
},
"signatures": []
}
Step 3: Sign alone
Sign with test1
and test2
and create individual signatures.
stcd tx sign \
unsignedTx.json \
--multisig=dst1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m \
--from=test1 \
--output-document=test1sig.json\
--chain-id=daodst_7000-1
stcd tx sign \
unsignedTx.json \
--multisig=dst1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m\
--from=test2 \
--output-document=test2sig.json\
--chain-id=daodst_7000-1
Step 4: Create Multisig
Combined with the signature to sign the transaction.
stcd tx multisign \
unsignedTx.json \
multi \
test1sig.json test2sig.json\
--output-document=signedTx.json\
--chain-id=daodst_7000-1
TX is now signed:
{
"body": {
"messages": [
{
"@type": "/cosmos.bank.v1beta1.MsgSend",
"from_address": "dst1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft",
"to_address": "dst157g6rn6t6k5rl0dl57zha2wx72t633axqyvvwq",
"amount": [
{
"denom": "dst",
"amount": "5000000000000000000"
}
]
}
],
"memo": "",
"timeout_height": "0",
"extension_options": [],
"non_critical_extension_options": []
},
"auth_info": {
"signer_infos": [
{
"public_key": {
"@type": "/cosmos.crypto.multisig.LegacyAminoPubKey",
"threshold": 2,
"public_keys": [
{
"@type": "/cosmos.crypto.secp256k1.PubKey",
"key": "ApCzSG8k7Tr4aM6e4OJRExN7cNtvH21L9azbh+uRrvt4"
},
{
"@type": "/cosmos.crypto.secp256k1.PubKey",
"key": "Ah91erz8ChNanqLe9ea948rvAiXMCRlR5Ka7EE/c0xUK"
},
{
"@type": "/cosmos.crypto.secp256k1.PubKey",
"key": "A0OjtIUCFJM3AobJ9HJTWKP9RZV2+WPcwVjLgsAidrZ/"
}
]
},
"mode_info": {
"multi": {
"bitarray": {
"extra_bits_stored": 3,
"elems": "wA=="
},
"mode_infos": [
{
"single": {
"mode": "SIGN_MODE_LEGACY_AMINO_JSON"
}
},
{
"single": {
"mode": "SIGN_MODE_LEGACY_AMINO_JSON"
}
}
]
}
},
"sequence": "1"
}
],
"fee": {
"amount": [
{
"denom": "dst",
"amount": "1000000"
}
],
"gas_limit": "200000",
"payer": "",
"granter": ""
}
},
"signatures": [
"CkCEeIbeGc+I1ipZuhp/0KhVNnWAv2tTlvgo5x61lzk1KHmLPV38m/YFurrFt5cm5+fqIXrn+FlOjrJuzBhw8ogYCkCawm9mpXsBHk0CFsE5618fVnvScEkfrzW0c2jCcjqV8EPuj3ut74UWzZyQkwtJGxUWtro9EgnGsB7Di1Gzizst"
]
}
Step 5: broadcast transaction
stcd tx broadcast signedTx.json \
--chain-id=daodst_7000-1 \
--broadcast-mode=block