P2SH address (multisig)

The example for 1-of-1 should only serve as an example. We don't recommend using it in the real world because it is not its intention. Instead of 1-of-1 use P2PKH!

Generate address (1-of-1)

 1import hashlib
 2
 3from bitcoin import SelectParams
 4from bitcoin.core import b2x, lx, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160
 5from bitcoin.core.script import CScript, OP_DUP, OP_HASH160, OP_EQUALVERIFY, OP_CHECKSIG, SignatureHash, SIGHASH_ALL
 6from bitcoin.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH
 7from bitcoin.wallet import CBitcoinAddress, CBitcoinSecret
 8
 9SelectParams('regtest')
10
11# Create the (in)famous correct brainwallet secret key.
12h = hashlib.sha256(b'correct horse battery staple').digest()
13seckey = CBitcoinSecret.from_secret_bytes(h)
14
15# Create a redeemScript. Similar to a scriptPubKey the redeemScript must be
16# satisfied for the funds to be spent.
17redeem_script = CScript([seckey.pub, OP_CHECKSIG])
18
19# Create the magic P2SH scriptPubKey format from that redeemScript. You should
20# look at the CScript.to_p2sh_scriptPubKey() function in bitcoin.core.script to
21# understand what's happening, as well as read BIP16:
22# https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
23script_pubkey = redeem_script.to_p2sh_scriptPubKey()
24
25# Convert the P2SH scriptPubKey to a base58 Bitcoin address and print it.
26# You'll need to send some funds to it to create a txout to spend.
27address = CBitcoinAddress.from_scriptPubKey(script_pubkey)
28print('Address:',str(address))
29# outputs: Address: 2Msc7itHhx2x8MEkTthvtED9pFC36J7QpQb

Spend from address (1-of-1)

Assuming the previously generated address has received funds, we can spend them. In order to spend them, we'll need information about the transaction id (txid) and a vector of an output (vout). You can get both from an explorer or by querying your running Bitcoin node by running listunspent along with some filters:

bitcoin-cli listunspent 1 9999999 "[\"address\"]"

Note that you must have an address in the watchlist in order to get any output. To add an address to a watchlist run importaddress:

bitcoin-cli importaddress <address> "<label>" false false

 1# we are continuing the code from above
 2
 3txid = lx("600bb0135fa78bbf895b5a933bbff0c304f66ba74810cb9f533e358ded2663c5")
 4vout = 1
 5
 6# Specify the amount send to your P2WSH address.
 7amount = int(1 * COIN)
 8
 9# Calculate an amount for the upcoming new UTXO. Set a high fee (5%) to bypass bitcoind minfee
10# setting on regtest.
11amount_less_fee = amount * 0.99
12
13# Create the txin structure, which includes the outpoint. The scriptSig
14# defaults to being empty.
15txin = CMutableTxIn(COutPoint(txid, vout))
16
17# Specify a destination address and create the txout.
18destination = CBitcoinAddress("bcrt1qzw44fxmxs2y39uxtl9ql0sxwpspwd0p8rum3nw").to_scriptPubKey()
19txout = CMutableTxOut(amount_less_fee, destination)
20
21# Create the unsigned transaction.
22tx = CMutableTransaction([txin], [txout])
23
24# Calculate the signature hash for that transaction. Note how the script we use
25# is the redeemScript, not the scriptPubKey. That's because when the CHECKSIG
26# operation happens EvalScript() will be evaluating the redeemScript, so the
27# corresponding SignatureHash() function will use that same script when it
28# replaces the scriptSig in the transaction being hashed with the script being
29# executed.
30sighash = SignatureHash(redeem_script, tx, 0, SIGHASH_ALL)
31
32# Now sign it. We have to append the type of signature we want to the end, in
33# this case the usual SIGHASH_ALL.
34sig = seckey.sign(sighash) + bytes([SIGHASH_ALL])
35
36# Set the scriptSig of our transaction input appropriately.
37txin.scriptSig = CScript([sig, redeem_script])
38
39# Done! Print the transaction
40print(b2x(tx.serialize()))
41# outputs: 0100000001c56326ed8d353e539fcb1048a76bf604c3f0bf3b935a5b89bf8ba75f13b00b60010000006d483045022100ec13f326674bc6accef9aa8ec7101d1301d8e33af86fc5737c04d66bf6beaa000220095d38069dc8563edfcfb52c36b7b8334d3c76d4ab07fdcd9635bfaf67b19ba60123210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71acffffffff01c09ee6050000000016001413ab549b66828912f0cbf941f7c0ce0c02e6bc2700000000

Now that we have our signed and encoded transaction, we can broadcast it using sendrawtransaction:

bitcoin-cli sendrawtransaction <transaction>

If the transaction is broadcasted successfully a transaction id will be returned. In this case it was 5cf00f81103b8b0283d98cec2f20421496eba6cc0660b263275e06f142686650.

Generate address (2-of-2)

In this example we show how to create a 2-of-2 multisig address. This means that two signatures are required in order to unlock funds.

 1import hashlib
 2
 3from bitcoin import SelectParams
 4from bitcoin.core import b2x, lx, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160
 5from bitcoin.core.script import CScript, OP_DUP, OP_0, OP_2, OP_HASH160, OP_EQUALVERIFY, OP_CHECKMULTISIG, SignatureHash, SIGHASH_ALL
 6from bitcoin.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH
 7from bitcoin.wallet import CBitcoinAddress, CBitcoinSecret
 8
 9SelectParams('regtest')
10
11# first key
12h1 = hashlib.sha256(b'correct horse battery staple first').digest()
13seckey1 = CBitcoinSecret.from_secret_bytes(h1)
14
15# second key
16h2 = hashlib.sha256(b'correct horse battery staple second').digest()
17seckey2 = CBitcoinSecret.from_secret_bytes(h2)
18
19# Create a redeemScript. Similar to a scriptPubKey the redeemScript must be
20# satisfied for the funds to be spent.
21redeem_script = CScript([OP_2, seckey1.pub, seckey2.pub, OP_2, OP_CHECKMULTISIG])
22
23# Create the magic P2SH scriptPubKey format from that redeemScript. You should
24# look at the CScript.to_p2sh_scriptPubKey() function in bitcoin.core.script to
25# understand what's happening, as well as read BIP16:
26# https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
27script_pubkey = redeem_script.to_p2sh_scriptPubKey()
28
29# Convert the P2SH scriptPubKey to a base58 Bitcoin address and print it.
30# You'll need to send some funds to it to create a txout to spend.
31address = CBitcoinAddress.from_scriptPubKey(script_pubkey)
32print('Address:',str(address))
33# outputs: Address: 2N3avDJKpr9c8pkRSYgWAsHSVCmRX3ce3w7

Spend from address (2-of-2)

Assuming the previously generated address has received funds, we can spend them. In order to spend them, we'll need information about the transaction id (txid) and a vector of an output (vout). You can get both from an explorer or by querying your running Bitcoin node by running listunspent along with some filters:

bitcoin-cli listunspent 1 9999999 "[\"address\"]"

Note that you must have an address in the watchlist in order to get any output. To add an address to a watchlist run importaddress:

bitcoin-cli importaddress <address> "<label>" false false

 1# we are continuing the code from above
 2
 3txid = lx("55a7cdebf307597fade5327daa6c95bcab6abc200a878ec191c1f3bd0b7664d0")
 4vout = 0
 5
 6# Specify the amount send to your P2WSH address.
 7amount = int(1 * COIN)
 8
 9# Calculate an amount for the upcoming new UTXO. Set a high fee (5%) to bypass bitcoind minfee
10# setting on regtest.
11amount_less_fee = amount * 0.99
12
13# Create the txin structure, which includes the outpoint. The scriptSig defaults to being empty as
14# is necessary for spending a P2WSH output.
15txin = CMutableTxIn(COutPoint(txid, vout))
16
17# Specify a destination address and create the txout.
18destination = CBitcoinAddress("bcrt1q0q579hm06qf655cr6ns274udgf6k9x7nedkeaa").to_scriptPubKey() 
19txout = CMutableTxOut(amount_less_fee, destination)
20
21# Create the unsigned transaction.
22tx = CMutableTransaction([txin], [txout])
23
24# Calculate the signature hash for that transaction.
25sighash = SignatureHash(
26    script=redeem_script,
27    txTo=tx,
28    inIdx=0,
29    hashtype=SIGHASH_ALL,
30    amount=amount,
31)
32
33# Now sign it. We have to append the type of signature we want to the end, in this case the usual
34# SIGHASH_ALL.
35sig1 = seckey1.sign(sighash) + bytes([SIGHASH_ALL])
36sig2 = seckey2.sign(sighash) + bytes([SIGHASH_ALL])
37
38# Construct a witness for this P2WSH transaction and add to tx.
39txin.scriptSig = CScript([OP_0, sig1, sig2, redeem_script])
40
41# Done! Print the transaction
42print(b2x(tx.serialize()))
43# outputs: 0100000001d064760bbdf3c191c18e870a20bc6aabbc956caa7d32e5ad7f5907f3ebcda75500000000db00483045022100a22bf0495398d87538bb07daf62948572def31d411df6048e92a53b00d35f06c02204583f20a0fcbb6f5a978f32dde6dfadfe11581973eef946bb87e1ce5b164fb3a014830450221008611aacb5ab9efb1f64200800ac8f55bb6a1acbcdaa2d3db7741df6b99c9f6f802202be1a1c4fdcb649f622b25ad88befba4ef23689e07409bffd4a1d63237993dbd01475221038d19497c3922b807c91b829d6873ae5bfa2ae500f3237100265a302fdce87b052103d3a9dff5a0bb0267f19a9ee1c374901c39045fbe041c1c168d4da4ce0112595552aeffffffff01c09ee605000000001600147829e2df6fd013aa5303d4e0af578d4275629bd300000000

Now that we have our signed and encoded transaction, we can broadcast it using sendrawtransaction:

bitcoin-cli sendrawtransaction <transaction>

If the transaction is broadcasted successfully a transaction id will be returned. In this case it was 844dd295da6877b8e7b01fa79f46aedf1b4f21651c0210ebf5e36f2476f2116d.

Generate address (1-of-3)

In this example we show how to create a 1-of-3 multisig address. This means that one out of three signatures can unlock and spend bitcoins.

 1import hashlib
 2
 3from bitcoin import SelectParams
 4from bitcoin.core import b2x, lx, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160
 5from bitcoin.core.script import CScript, OP_DUP, OP_0, OP_1, OP_3, OP_HASH160, OP_EQUALVERIFY, OP_CHECKMULTISIG, SignatureHash, SIGHASH_ALL
 6from bitcoin.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH
 7from bitcoin.wallet import CBitcoinAddress, CBitcoinSecret
 8
 9SelectParams('regtest')
10
11# first key
12h1 = hashlib.sha256(b'correct horse battery staple first').digest()
13seckey1 = CBitcoinSecret.from_secret_bytes(h1)
14
15# second key
16h2 = hashlib.sha256(b'correct horse battery staple second').digest()
17seckey2 = CBitcoinSecret.from_secret_bytes(h2)
18
19# third key
20h3 = hashlib.sha256(b'correct horse battery staple third').digest()
21seckey3 = CBitcoinSecret.from_secret_bytes(h2)
22
23# Create a redeemScript. Similar to a scriptPubKey the redeemScript must be
24# satisfied for the funds to be spent.
25redeem_script = CScript([OP_1, seckey1.pub, seckey2.pub, seckey3.pub, OP_3, OP_CHECKMULTISIG])
26
27# Create the magic P2SH scriptPubKey format from that redeemScript. You should
28# look at the CScript.to_p2sh_scriptPubKey() function in bitcoin.core.script to
29# understand what's happening, as well as read BIP16:
30# https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
31script_pubkey = redeem_script.to_p2sh_scriptPubKey()
32
33# Convert the P2SH scriptPubKey to a base58 Bitcoin address and print it.
34# You'll need to send some funds to it to create a txout to spend.
35address = CBitcoinAddress.from_scriptPubKey(script_pubkey)
36print('Address:',str(address))
37# outputs: Address: 2MzB7ZEastmRyWMdY54fMxRXu3Wf9iu47AE

Spend from address (1-of-3)

Assuming the previously generated address has received funds, we can spend them. In order to spend them, we'll need information about the transaction id (txid) and a vector of an output (vout). You can get both from an explorer or by querying your running Bitcoin node by running listunspent along with some filters:

bitcoin-cli listunspent 1 9999999 "[\"address\"]"

Note that you must have an address in the watchlist in order to get any output. To add an address to a watchlist run importaddress:

bitcoin-cli importaddress <address> "<label>" false false

 1# we are continuing the code from above
 2
 3txid = lx("8e46a443d5877e21d83cc519cb22dde72e29884e91c4fb3410afa2cf1cb8b03c")
 4vout = 0
 5
 6# Specify the amount send to your P2WSH address.
 7amount = int(1 * COIN)
 8
 9# Calculate an amount for the upcoming new UTXO. Set a high fee (5%) to bypass bitcoind minfee
10# setting on regtest.
11amount_less_fee = amount * 0.99
12
13# Create the txin structure, which includes the outpoint. The scriptSig defaults to being empty as
14# is necessary for spending a P2WSH output.
15txin = CMutableTxIn(COutPoint(txid, vout))
16
17# Specify a destination address and create the txout.
18destination = CBitcoinAddress("bcrt1q0q579hm06qf655cr6ns274udgf6k9x7nedkeaa").to_scriptPubKey() 
19txout = CMutableTxOut(amount_less_fee, destination)
20
21# Create the unsigned transaction.
22tx = CMutableTransaction([txin], [txout])
23
24# Calculate the signature hash for that transaction.
25sighash = SignatureHash(
26    script=redeem_script,
27    txTo=tx,
28    inIdx=0,
29    hashtype=SIGHASH_ALL,
30    amount=amount,
31)
32
33# Now sign it. We have to append the type of signature we want to the end, in this case the usual
34# SIGHASH_ALL.
35sig2 = seckey2.sign(sighash) + bytes([SIGHASH_ALL])
36
37# Construct a witness for this P2WSH transaction and add to tx.
38txin.scriptSig = CScript([OP_0, sig2, redeem_script])
39
40# Done! Print the transaction
41print(b2x(tx.serialize()))
42# outputs: 01000000013cb0b81ccfa2af1034fbc4914e88292ee7dd22cb19c53cd8217e87d543a4468e00000000b4004730440220437bc4b0a8c600de2cbbd57f14a60c0737c680e7cabc25217bb9a61950b55214022027bfc9d4bf0cc2ea88d416e877a54b8841483b1c18633c8732186d4333049e64014c695121038d19497c3922b807c91b829d6873ae5bfa2ae500f3237100265a302fdce87b052103d3a9dff5a0bb0267f19a9ee1c374901c39045fbe041c1c168d4da4ce011259552103d3a9dff5a0bb0267f19a9ee1c374901c39045fbe041c1c168d4da4ce0112595553aeffffffff01c09ee605000000001600147829e2df6fd013aa5303d4e0af578d4275629bd300000000

Now that we have our signed and encoded transaction, we can broadcast it using sendrawtransaction:

bitcoin-cli sendrawtransaction <transaction>

If the transaction is broadcasted successfully a transaction id will be returned. In this case it was afb52d8ca23ef7b98444845258018905360cf635c7e8b19bb1a541f74a8f3124.

Generate address (2-of-3)

In this example we show how to create a 2-of-3 multisig address. This means that two out of three signatures can unlock and spend bitcoins.

 1import hashlib
 2
 3from bitcoin import SelectParams
 4from bitcoin.core import b2x, lx, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160
 5from bitcoin.core.script import CScript, OP_DUP, OP_0, OP_2, OP_3, OP_HASH160, OP_EQUALVERIFY, OP_CHECKMULTISIG, SignatureHash, SIGHASH_ALL
 6from bitcoin.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH
 7from bitcoin.wallet import CBitcoinAddress, CBitcoinSecret
 8
 9SelectParams('regtest')
10
11# first key
12h1 = hashlib.sha256(b'correct horse battery staple first').digest()
13seckey1 = CBitcoinSecret.from_secret_bytes(h1)
14
15# second key
16h2 = hashlib.sha256(b'correct horse battery staple second').digest()
17seckey2 = CBitcoinSecret.from_secret_bytes(h2)
18
19# third key
20h3 = hashlib.sha256(b'correct horse battery staple third').digest()
21seckey3 = CBitcoinSecret.from_secret_bytes(h2)
22
23# Create a redeemScript. Similar to a scriptPubKey the redeemScript must be
24# satisfied for the funds to be spent.
25redeem_script = CScript([OP_2, seckey1.pub, seckey2.pub, seckey3.pub, OP_3, OP_CHECKMULTISIG])
26
27# Create the magic P2SH scriptPubKey format from that redeemScript. You should
28# look at the CScript.to_p2sh_scriptPubKey() function in bitcoin.core.script to
29# understand what's happening, as well as read BIP16:
30# https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
31script_pubkey = redeem_script.to_p2sh_scriptPubKey()
32
33# Convert the P2SH scriptPubKey to a base58 Bitcoin address and print it.
34# You'll need to send some funds to it to create a txout to spend.
35address = CBitcoinAddress.from_scriptPubKey(script_pubkey)
36print('Address:',str(address))
37# outputs: Address: 2MuHBt425GsVo1wXnoN3mvCzdMRFf7HnvJV

Spend from address (2-of-3)

Assuming the previously generated address has received funds, we can spend them. In order to spend them, we'll need information about the transaction id (txid) and a vector of an output (vout). You can get both from an explorer or by querying your running Bitcoin node by running listunspent along with some filters:

bitcoin-cli listunspent 1 9999999 "[\"address\"]"

Note that you must have an address in the watchlist in order to get any output. To add an address to a watchlist run importaddress:

bitcoin-cli importaddress <address> "<label>" false false

 1# we are continuing the code from above
 2
 3txid = lx("e2d5767f90a0129292baf11ec440824860a0b065becfab433dc6c66e19b4abb6")
 4vout = 1
 5
 6# Specify the amount send to your P2WSH address.
 7amount = int(1 * COIN)
 8
 9# Calculate an amount for the upcoming new UTXO. Set a high fee (5%) to bypass bitcoind minfee
10# setting on regtest.
11amount_less_fee = amount * 0.99
12
13# Create the txin structure, which includes the outpoint. The scriptSig defaults to being empty as
14# is necessary for spending a P2WSH output.
15txin = CMutableTxIn(COutPoint(txid, vout))
16
17# Specify a destination address and create the txout.
18destination = CBitcoinAddress("bcrt1q0q579hm06qf655cr6ns274udgf6k9x7nedkeaa").to_scriptPubKey() 
19txout = CMutableTxOut(amount_less_fee, destination)
20
21# Create the unsigned transaction.
22tx = CMutableTransaction([txin], [txout])
23
24# Calculate the signature hash for that transaction.
25sighash = SignatureHash(
26    script=redeem_script,
27    txTo=tx,
28    inIdx=0,
29    hashtype=SIGHASH_ALL,
30    amount=amount,
31)
32
33# Now sign it. We have to append the type of signature we want to the end, in this case the usual
34# SIGHASH_ALL.
35sig2 = seckey2.sign(sighash) + bytes([SIGHASH_ALL])
36sig3 = seckey3.sign(sighash) + bytes([SIGHASH_ALL])
37
38# Construct a witness for this P2WSH transaction and add to tx.
39txin.scriptSig = CScript([OP_0, sig2, sig3, redeem_script])
40
41# Done! Print the transaction
42print(b2x(tx.serialize()))
43# outputs: 0100000001b6abb4196ec6c63d43abcfbe65b0a060488240c41ef1ba929212a0907f76d5e201000000fdfe0000483045022100806e36bc310c0ed942e9ec979407dc0981340d304ec058e8e2aed4c74af34af202201eafaf6392f8f58d5f80b9fe621fd6cea1bfd8db5d427080152ee9f3e2c2899701483045022100ad999b0c72368ea7e83dd25286d2289e0da38247f1a05fab90c1a48d1879934202201e3bdcdb1f2528bd4f2a8ffd6eadf1aef36e934160f709a713af54a8e376d7c1014c695221038d19497c3922b807c91b829d6873ae5bfa2ae500f3237100265a302fdce87b052103d3a9dff5a0bb0267f19a9ee1c374901c39045fbe041c1c168d4da4ce011259552103d3a9dff5a0bb0267f19a9ee1c374901c39045fbe041c1c168d4da4ce0112595553aeffffffff01c09ee605000000001600147829e2df6fd013aa5303d4e0af578d4275629bd300000000

Now that we have our signed and encoded transaction, we can broadcast it using sendrawtransaction:

bitcoin-cli sendrawtransaction <transaction>

If the transaction is broadcasted successfully a transaction id will be returned. In this case it was 11c69b64290a67e95f7148b1e399db89ab98982a18f3dc02ed408f90b66158ea.