P2WPKH address

Generate address

 1import hashlib
 2
 3from bitcoin import SelectParams
 4from bitcoin.core import b2x, lx, COIN, COutPoint, CTxOut, CTxIn, CTxInWitness, CTxWitness, CScriptWitness, CMutableTransaction, Hash160
 5from bitcoin.core.script import CScript, OP_0, SignatureHash, SIGHASH_ALL, SIGVERSION_WITNESS_V0
 6from bitcoin.wallet import CBitcoinSecret, P2WPKHBitcoinAddress, CBitcoinAddress
 7
 8SelectParams("regtest")
 9
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
15public_key = seckey.pub
16script_pubkey = CScript([OP_0, Hash160(public_key)])
17address = P2WPKHBitcoinAddress.from_scriptPubKey(script_pubkey)
18
19print('Address:', str(address))
20# outputs: Address: bcrt1q08alc0e5ua69scxhvyma568nvguqccrvah6ml0

Spend from address

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("ace85db02052679bf02216e6d3815f082ad52bf3e1e1ef1bbe3854dc45aa9b2c")
 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 = CTxIn(COutPoint(txid, vout))
16
17# Specify a destination address and create the txout.
18destination = CBitcoinAddress("bcrt1qvg69hl7uj3y4x3xpy8dq2rrfdhq4nwmzpx9s6y").to_scriptPubKey()
19
20# Create the unsigned transaction.
21txin = CTxIn(COutPoint(txid, vout))
22txout = CTxOut(amount_less_fee, destination)
23tx = CMutableTransaction([txin], [txout])
24
25# Calculate the signature hash for that transaction.
26sighash = SignatureHash(
27    script=address.to_redeemScript(),
28    txTo=tx,
29    inIdx=0,
30    hashtype=SIGHASH_ALL,
31    amount=amount,
32    sigversion=SIGVERSION_WITNESS_V0,
33)
34signature = seckey.sign(sighash) + bytes([SIGHASH_ALL])
35
36# Construct a witness for this transaction input. The public key is given in
37# the witness so that the appropriate redeemScript can be calculated by
38# anyone. The original scriptPubKey had only the Hash160 hash of the public
39# key, not the public key itself, and the redeem script can be entirely
40# re-constructed (from implicit template) if given just the public key. So the
41# public key is added to the witness. This is P2WPKH in bip141.
42witness = [signature, public_key]
43
44# Aggregate all of the witnesses together, and then assign them to the
45# transaction object.
46ctxinwitnesses = [CTxInWitness(CScriptWitness(witness))]
47tx.wit = CTxWitness(ctxinwitnesses)
48
49# Done! Print the transaction
50print(b2x(tx.serialize()))
51# outputs: 010000000001012c9baa45dc5438be1befe1e1f32bd52a085f81d3e61622f09b675220b05de8ac0100000000ffffffff01c09ee6050000000016001462345bffdc94495344c121da050c696dc159bb6202473044022010440396a713c45ef4600521f26fa5af3324ebda16fc451c56fe72366cc4817c022047bce51f6b7ac97972f2612cd3c165774cfedb71b193367afe3f7a718524bb2301210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c7100000000

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