Multi-signature accounts can be used to require that transactions require multiple public keys to sign before they are considered valid. This is done by first configuring your account’s threshold levels. Each operation has a threshold level of either low, medium, or high. You give each threshold level a number between 1-255 in your account. Then, for each key in your account, you assign it a weight (1-255, setting a 0 weight deletes the key). Any transaction must be signed with enough keys to meet the threshold.
For example, let’s say you set your threshold levels; low = 1, medium = 2, high = 3. You want to send a payment operation, which is a medium threshold operation. Your master key has weight 1. Additionally, you have a secondary key associated with your account which has a weight of 1. Now, the transaction you submit for this payment must include both signatures of your master key and secondary key since their combined weight is 2 which is enough to authorize the payment operation.
In this example, we will:
Add a second signer to the account
Set our account’s masterkey weight and threshold levels
Create a multi signature transaction that sends a payment
1""" 2Stellar uses signatures as authorization. Transactions always need authorization 3from at least one public key in order to be considered valid. Generally, 4transactions only need authorization from the public key of the source account. 5 6Transaction signatures are created by cryptographically signing the 7transaction object contents with a secret key. Stellar currently uses the ed25519 signature 8scheme, but there’s also a mechanism for adding additional types of public/private key schemes. 9A transaction with an attached signature is considered to have authorization from that public key. 10 11In two cases, a transaction may need more than one signature. If the transaction has 12operations that affect more than one account, it will need authorization from every account 13in question. A transaction will also need additional signatures if the account associated 14with the transaction has multiple public keys. 15 16See: https://developers.stellar.org/docs/glossary/multisig/ 17""" 18from stellar_sdk import Asset, Keypair, Network, Server, Signer, TransactionBuilder 19 20server = Server(horizon_url="https://horizon-testnet.stellar.org") 21root_keypair = Keypair.from_secret( 22 "SA6XHAH4GNLRWWWF6TEVEWNS44CBNFAJWHWOPZCVZOUXSQA7BOYN7XHC" 23) 24root_account = server.load_account(account_id=root_keypair.public_key) 25secondary_keypair = Keypair.from_secret( 26 "SAMZUAAPLRUH62HH3XE7NVD6ZSMTWPWGM6DS4X47HLVRHEBKP4U2H5E7" 27) 28 29secondary_signer = Signer.ed25519_public_key( 30 account_id=secondary_keypair.public_key, weight=1 31) 32transaction = ( 33 TransactionBuilder( 34 source_account=root_account, 35 network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE, 36 base_fee=100, 37 ) 38 .append_set_options_op( 39 master_weight=1, # set master key weight 40 low_threshold=1, 41 med_threshold=2, # a payment is medium threshold 42 high_threshold=2, # make sure to have enough weight to add up to the high threshold! 43 signer=secondary_signer, 44 ) 45 .set_timeout(30) 46 .build() 47) 48 49# only need to sign with the root signer as the 2nd signer won't 50# be added to the account till after this transaction completes 51transaction.sign(root_keypair) 52response = server.submit_transaction(transaction) 53print(response) 54 55# now create a payment with the account that has two signers 56destination = "GBA5SMM5OYAOOPL6R773MV7O3CCLUDVLCWHIVVL3W4XTD3DA5FJ4JSEZ" 57transaction = ( 58 TransactionBuilder( 59 source_account=root_account, 60 network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE, 61 base_fee=100, 62 ) 63 .append_payment_op(destination=destination, amount="2000", asset=Asset.native()) 64 .set_timeout(30) 65 .build() 66) 67 68# now we need to sign the transaction with both the root and the secondary_keypair 69transaction.sign(root_keypair) 70transaction.sign(secondary_keypair) 71response = server.submit_transaction(transaction) 72print(response)