Cosmos SDK Multisigs

Jake Hartnell
4 min readApr 27, 2021
A Ledger Device.

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. 🎉

--

--