Cosmos SDK Multisigs
Multisig transactions with the Cosmos SDK are a built in feature and pretty easy to preform. There are extremely useful for sharing funds or an important on-chain account with a group of people.
We recently had to create some multisigs for the Stargaze blockchain, so I figured I would share a quick tutorial.
Here are all the steps, in tl;dr
format:
# Add keys for multisig
starsd keys add alice-ledger --pubkey <alice-pubkey-here>
starsd keys add bob-ledger --pubkey <bob-pubkey-here># Create multisig
starsd keys add alice-bob-multisig --multisig alice-ledger,bob-ledger --multisig-threshold 2# Generate TX
starsd tx bank send $(starsd keys show alice-bob-multisig -a) stars123408YOURDestinationAddress 10000000ustarx --generate-only --chain-id localnet-1 > tx.json# Alice signs
starsd tx sign --from $(starsd keys show -a alice-ledger) --multisig $(starsd keys show -a alice-bob-multisig) tx.json --sign-mode amino-json --chain-id localnet-1 >> tx-signed-alice.json# Bob signs
starsd tx sign --from $(starsd keys show -a bob-ledger) --multisig $(starsd keys show -a alice-bob-multisig) tx.json --sign-mode amino-json --chain-id localnet-1 >> tx-signed-bob.json# Combine signatures into single tx
starsd tx multisign --from alice-bob-multisig tx.json alice-bob-multisig tx-signed-alice.json tx-signed-bob.json --chain-id localnet-1 > tx_ms.json# Broadcast tx
starsd tx broadcast ms/tx_ms.json --chain-id localnet-1
To use a different Cosmos SDK chain, you would obviously replace starsd
with the name of your chain’s binary and localnet-1
with the correct chain-id
.
If you’re still confused, fear not! I’ll walk you through it step by step with a bit more context.
First, Alice and Bob generate their keys on their own devices; for example, using a ledger or a securely stored filed. They make note of their public keys.
On a shared machine they add their public keys to the keyring using the --pubkey
flag.
starsd keys add alice-ledger --pubkey <alice-pubkey-here>
starsd keys add bob-ledger --pubkey <bob-pubkey-here>
Alice and Bob’s private keys are not stored on this shared device… just the public keys. These are used to create the multisig.
starsd keys add alice-bob-multisig --multisig alice-ledger,bob-ledger --multisig-threshold 2
Note the --multisig-threshold
flag. This controls how many of the keys have to sign in order for a transaction to be valid. If the alice-bob-multisig
account had a threshold of 1, either Alice or Bob could sign for the multisig all by themselves. However, the threshold is 2, so the both have to sign.
For larger multisigs (more than 3 people), it may make sense to not to have to require everyone to sign, but rather some majority of key holders. Think about this number before you set it.
Great! Alice and Bob have created a multisig account. This account will have an address associated with it and can receive funds.
Let’s say Alice and Bob want to send some of their new funds to a developer friend of theirs who’s working on flashy new website for them.
They don’t have their private keys on their shared machine, so they have to use the --generate-only
tx flag when making the transaction. This will not submit the transaction to the chain, but rather generate a JSON file for Alice and Bob to sign on their respective machines.
starsd tx bank send $(starsd keys show alice-bob-multisig -a) stars123408YOURDestinationAddress 10000000ustarx --generate-only --chain-id localnet-1 > tx.json
Alice and Bob both take that tx.json
file and sign it on their own machines with their private keys. The both specify the address of the multisig account using the --multisig
flag.
Alice:
starsd tx sign --from $(starsd keys show -a alice-ledger) --multisig $(starsd keys show -a alice-bob-multisig) tx.json --sign-mode amino-json --chain-id localnet-1 >> tx-signed-alice.json
Bob:
starsd tx sign --from $(starsd keys show -a bob-ledger) --multisig $(starsd keys show -a alice-bob-multisig) tx.json --sign-mode amino-json --chain-id localnet-1 >> tx-signed-bob.json
Alice and Bob take their respective JSON files and use them to create a single transaction JSON file containing both of their signatures.
starsd tx multisign --from alice-bob-multisig tx.json alice-bob-multisig tx-signed-alice.json tx-signed-bob.json --chain-id localnet-1 > tx_ms.json
Finally, one of them broadcasts the transaction to the chain!
starsd tx broadcast ms/tx_ms.json --chain-id localnet-1
Alice and Bob just sent their developer friend funds from their Multisig. 🎉