Skip to main content

Multisig

To create a multisig account on Humans.ai, you'll need to specify a threshold number of signatures required and the public keys involved in signing. This type of account can enhance security by requiring multiple parties to approve transactions.

To sign a transaction with a multisig account, each key specified for the account must sign the transaction individually. Then, the signatures are combined into a multi-signature, which is used to sign the transaction. If fewer than the threshold number of signatures are present, the multi-signature is considered invalid.

Generate a Multisig key

humansd keys add --multisig=name1,name2,name3[...] --multisig-threshold=K new_key_name

The minimum number of private keys required to sign transactions that contain the public key's address as a signer is K.

The --multisig flag must include the names of the public keys that will be combined into a single public key, which will be generated and stored as new_key_name in the local database. All names provided through --multisig must already exist in the local database.

Unless the --nosort flag is used, the order in which the keys are entered on the command line does not affect the result, so the following commands produce two identical keys:

humansd keys add --multisig=p1,p2,p3 --multisig-threshold=2 multisig_address
humansd keys add --multisig=p2,p3,p1 --multisig-threshold=2 multisig_address

Additionally, multisig addresses can be instantly produced and printed with the which command:

humansd keys show --multisig-threshold=K name1 name2 name3 [...]

Signing a transaction

Step 1: Create the multisig key

Assume that you have test1 and test2 and that you wish to create a multisig account with test3.

Enter test3's public keys first into your keyring.

humansd keys add \
test3 \
--pubkey=humanpub1fdhfy7qtak02zu600aes5pqpasckwgld3jdmgu9m8awmsm5wrzfw4xxenp02sdfsg3z

Generate the multisig key with 2/3 threshold.

humansd keys add \
multi \
--multisig=test1,test2,test3 \
--multisig-threshold=2

You can see its address and details:

humansd keys show multi

- name: multi
type: multi
address: human1a8m90l9qaq40pm7ce8ge3mkx60r5xxf4r3kwfm
pubkey: humanpub1ryxag9dtqfh6sgzgyk3yk2d9zp5nu6y7p50n0hy69t36jsvmqgvdk7s57tqmcjpjsrau3yuz2u04axfd363smnk6m2g6930qszfhc0qczqz26d36ahmxftj9qx2kk5wgyzfadvdjz9jl76z6akqf9julyfe6qxrtq26k4j0auyx8td6dj7dlgql6vctlx66fkc9kz6uprr6a3k3n
mnemonic: ""
threshold: 0
pubkeys: []

To the multisig wallet, let's add 10 HEART:

humansd tx bank send \
test1 \
human1a8m90l9qaq40pm7ce8ge3mkx60r5xxf4r3kwfm \
10000000000000000000aheart \
--chain-id=humans_1089-1 \
--gas=auto \
--fees=1000000aheart \
--broadcast-mode=block

Step 2: Create the multisig transaction

From our multisignature account, we would like to send 5 HEART to human1xwhamqxyuvvrhcfetwlhg7q0vxajr0s0r2xsln.

humansd tx bank send \
human1xwhamqxyuvvrhcfetwlhg7q0vxajr0s0r2xsln \
human1ygl36625zvvlxx3na5qdq57hrwrtw67a7kt620 \
5000000000000000000aheart \
--gas=200000 \
--fees=1000000aheart \
--chain-id=humans_1089-1 \
--generate-only > unsignedTx.json

The unsigned transaction is stored in JSON format in the file named unsignedTx.json.

{
"body": {
"messages": [
{
"@type": "/cosmos.bank.v1beta1.MsgSend",
"from_address": "human1xwhamqxyuvvrhcfetwlhg7q0vxajr0s0r2xsln",
"to_address": "human1ygl36625zvvlxx3na5qdq57hrwrtw67a7kt620",
"amount": [
{
"denom": "aheart",
"amount": "5000000000000000000"
}
]
}
],
"memo": "",
"timeout_height": "0",
"extension_options": [],
"non_critical_extension_options": []
},
"auth_info": {
"signer_infos": [],
"fee": {
"amount": [
{
"denom": "aheart",
"amount": "1000000"
}
],
"gas_limit": "200000",
"payer": "",
"granter": ""
}
},
"signatures": []
}

Step 3: Sign individually

Test1 and Test2 should be used to sign individually.

humansd tx sign \
unsignedTx.json \
--multisig=human1a8m90l9qaq40pm7ce8ge3mkx60r5xxf4r3kwfm \
--from=test1 \
--output-document=test1sig.json \
--chain-id=humans_1089-1
humansd tx sign \
unsignedTx.json \
--multisig=human1a8m90l9qaq40pm7ce8ge3mkx60r5xxf4r3kwfm \
--from=test2 \
--output-document=test2sig.json \
--chain-id=humans_1089-1

Step 4: Create multisignature

To sign a transaction, combine signatures.

humansd tx multisign \
unsignedTx.json \
multi \
test1sig.json test2sig.json \
--output-document=signedTx.json \
--chain-id=humans_1089-1

Now that the TX is signed:

{
"body": {
"messages": [
{
"@type": "/cosmos.bank.v1beta1.MsgSend",
"from_address": "human1xwhamqxyuvvrhcfetwlhg7q0vxajr0s0r2xsln",
"to_address": "human1ygl36625zvvlxx3na5qdq57hrwrtw67a7kt620",
"amount": [
{
"denom": "aheart",
"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": "pv7S4G9bz6Mzeh1ANNaRL72RrOtk8Ht4ur+4aTxcJECv"
},
{
"@type": "/cosmos.crypto.secp256k1.PubKey",
"key": "hUlrA0qa95nKCX47rL1z8Ka9e9RNEva/c8eiMhReCEAx"
},
{
"@type": "/cosmos.crypto.secp256k1.PubKey",
"key": "LOTAJICA/9PW9UMgw2AZFbHjoRV+Vt3jdWJcPJ0ZKirs"
}
]
},
"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": "aheart",
"amount": "1000000"
}
],
"gas_limit": "200000",
"payer": "",
"granter": ""
}
},
"signatures": [
"nezt0PJUBk1rglWXp9OAcnvt7ypW/oEqhF9xC81wLsVSc0mJhGrs8Em+Tim3zkGjrB74fg8V2CvCroi6PKEzE5ImiVHG+uCvCac5gKIl5G1outnNjUrIjzH6CYQsW/zFmkbctfrFFqZ20eE5jtZwtVfs+klu8hzwuWXk3Buk11npcDYx"
]
}

Step 5: Broadcast transaction

humansd tx broadcast signedTx.json \
--chain-id=humans_1089-1 \
--broadcast-mode=block