Stay tuned for more updates and developments for XPR Network.

Multi signatures on the XPR Network






Multi Signatures on XPR Network · XPRLabs


XPRLabs
Block producer on XPR Network · @xprlabs
Security Guide

Multi Signatures on the XPR Network

A complete step by step guide to setting up and using multi signature transactions with cleos. Securing your accounts so no single key can act alone.

01

Create and Unlock Your Wallet

Each participant runs on their own machine. Never share private keys.

# On test1's machine
$CLEOS wallet create --name test1wallet --to-console
$CLEOS wallet unlock  --name test1wallet
$CLEOS wallet import  --name test1wallet --private-key <PRIVATE_KEY_TEST1>

# On test2's machine
$CLEOS wallet create --name test2wallet --to-console
$CLEOS wallet unlock  --name test2wallet
$CLEOS wallet import  --name test2wallet --private-key <PRIVATE_KEY_TEST2>

# On test3's machine
$CLEOS wallet create --name test3wallet --to-console
$CLEOS wallet unlock  --name test3wallet
$CLEOS wallet import  --name test3wallet --private-key <PRIVATE_KEY_TEST3>

Replace <PRIVATE_KEY_*> with the actual private key for each account.

02

Configure the Multisig Permission

Change the active permission to require 2 of 3 partner approvals.

Our treasury account is test1. We want 2 out of 3 signers to approve any transaction.

⚠️ Critical before you run this
Verify your test1 active key is imported and wallet is unlocked. Run $CLEOS wallet keys and cross check against $CLEOS get account test1. Once multisig is set, no single key can authorize actions anymore.

$CLEOS set account permission test1 active '{"threshold":2,"keys":[],"accounts":[{"permission":{"actor":"test1","permission":"active"},"weight":1},{"permission":{"actor":"test2","permission":"active"},"weight":1},{"permission":{"actor":"test3","permission":"active"},"weight":1}],"waits":[]}' -p test1@active

$CLEOS get account test1

💡 Important order
Do active first, then owner last. If owner goes wrong you can still recover via active.

03

Propose a Transaction

Submit a proposal on chain that signers will review and approve.

test3 wants to send 50.0000 XPR from test1 to recipient1. At least one more approval is needed.

$CLEOS multisig propose testingprop '[{"actor":"test1","permission":"active"},{"actor":"test2","permission":"active"}]' '[{"actor":"test1","permission":"active"}]' eosio.token transfer '{"from":"test1","to":"recipient1","quantity":"50.0000 XPR","memo":"Q2 vendor payment"}' -p test3@active

ArgumentWhat it is
testingpropProposal name: max 12 chars, a-z and 1-5 only
First arrayAccounts that must approve before execution
Second arrayAuthority injected at execution time
eosio.token transferThe contract and action being proposed
Last JSONParameters: from, to, quantity, memo
-p test3@activetest3 pays CPU/NET for this proposal
💡 Arrays must match the from account
Second array must contain test1@active or exec fails with missing_auth_exception.
⏱ Proposal expiration
Default expiry is 1 hour. Use --expiration 86400 for 24 hours.

04

Review the Proposal

Verify the full transaction details on chain before approving.

$CLEOS multisig review test3 testingprop

⚠️ Argument order
First argument is always the proposer account (test3), not whoever is reviewing.

05

Collect Approvals

Each signer approves individually using the proposer name as first argument.

# test1 approves (on test1 machine)
$CLEOS multisig approve test3 testingprop '{"actor": "test1", "permission": "active"}' -p test1@active

# test2 approves (on test2 machine)
$CLEOS multisig approve test3 testingprop '{"actor": "test2", "permission": "active"}' -p test2@active

With 2 of 3 approvals the threshold is met. test3 does not need to approve.

$CLEOS get table eosio.msig test3 approvals2

06

Execute the Transaction

Once the threshold is met, any account can trigger execution.

$CLEOS multisig exec test3 testingprop -p test3@active

$CLEOS get currency balance eosio.token test1 XPR
$CLEOS get currency balance eosio.token recipient1 XPR

07

Cancel a Proposal

Only the original proposer can cancel before execution.

$CLEOS multisig cancel test3 testingprop -p test3@active

Even expired proposals must be cancelled explicitly to free on chain RAM.


08

Common Issues

Transaction exceeded the current CPU usage limit
Your account does not have enough staked CPU. Stake more XPR to CPU or use a resource provider. On testnet use the faucet.

Provided keys, permissions, and delays do not satisfy declared authorizations
The wallet does not have the right private key. Run $CLEOS wallet keys and compare against $CLEOS get account test1. Confirm key is imported and wallet is unlocked.

Proposal not found
Either the proposal name or proposer account is wrong. In cleos multisig approve test3 testingprop the first argument is always the proposer, not the approver.

missing authority of account
The second array in your proposal does not match the from account. Cancel and repropose with the correct second array.

Proposal expires before enough approvals
Default expiry is 1 hour. Cancel and repropose using --expiration in seconds. Always cancel expired proposals to reclaim RAM.

⚡ Quick Reference

# 1. Set 2 of 3 multisig on test1
$CLEOS set account permission test1 active '{"threshold":2,"keys":[],"accounts":[{"permission":{"actor":"test1","permission":"active"},"weight":1},{"permission":{"actor":"test2","permission":"active"},"weight":1},{"permission":{"actor":"test3","permission":"active"},"weight":1}],"waits":[]}' -p test1@active

# 2. Propose
$CLEOS multisig propose testingprop '[{"actor":"test1","permission":"active"},{"actor":"test2","permission":"active"}]' '[{"actor":"test1","permission":"active"}]' eosio.token transfer '{"from":"test1","to":"recipient1","quantity":"50.0000 XPR","memo":"Q2 vendor payment"}' -p test3@active

# 3. Review
$CLEOS multisig review test3 testingprop

# 4. Approve
$CLEOS multisig approve test3 testingprop '{"actor":"test1","permission":"active"}' -p test1@active
$CLEOS multisig approve test3 testingprop '{"actor":"test2","permission":"active"}' -p test2@active

# 5. Execute
$CLEOS multisig exec test3 testingprop -p test3@active

# 6. Cancel
$CLEOS multisig cancel test3 testingprop -p test3@active