3

I'm using the Bitcoin Functional Test framework to understand how SegWit works by analyzing and building a P2SH-P2WPKH transaction.

When I run my code the transaction gets created, but when I inspect the Tx Hex, I cannot see the SegWit marker 00 on the 5th byte nor the segWitFlag, so probably I'm doing something wrong. Can anyone point out what could be the correct way to do it? Thanks so much in advance

Here is my Python Code:

        key = ECKey()
        key.generate() # generate private key
        pubkey = key.get_pubkey().get_bytes()
        pubkey_hash = hash160(pubkey)
        witness_script = keyhash_to_p2pkh_script(pubkey_hash)
        hashed_script = hash160(witness_script)
        
        script_sig = CScript([ OP_0, pubkey_hash ])
        
        script_pubkey = scripthash_to_p2sh_script(hashed_script)
        destination_address = byte_to_base58(hashed_script, 196) # 196, Bitcoin testnet script hash
        
        self.log.info("Witness script: {}".format(repr(witness_script)))
        self.log.info("scriptSig): {}".format(repr(script_sig)))
        self.log.info("scriptPubKey: {}".format(repr(script_pubkey)))
        self.log.info("Destination Address: {}".format(repr(destination_address)))

        # Create transaction
        tx = CTransaction()
        tx.vin.append(CTxIn(COutPoint(int(utxo['txid'],16), int(utxo['vout'])), scriptSig=script_sig))
        tx.vout.append(CTxOut((int(utxo['amount']) * COIN) - 1000, script_pubkey))
        tx.rehash()
        self.log.info("Transacción: {}".format(tx))

        # Add witnessscript
        tx.wit.vtxinwit.append(CTxInWitness())
        tx.wit.vtxinwit[0].scriptWitness.stack = [witness_script]

        self.log.info("Sign transaction")
        tx_hex = self.nodes[0].signrawtransactionwithwallet(tx.serialize().hex())["hex"]
        self.log.info("Transaction HEX: {}".format(tx_hex))

        decrawtx = self.nodes[0].decoderawtransaction(tx_hex, True)
        descriptor = decrawtx['vout'][0]['scriptPubKey']['desc']
        # Get descriptor
        self.log.info("descriptor: {}".format(descriptor))
Bitcoin_1o1
  • 343
  • 1
  • 12
  • What does the transaction look like before you give it to `signrawtransactionwithwallet`? It's possible that the RPC is removing the scriptSig and scriptWitness data from the input because the wallet cannot sign for it and so it is incomplete/invalid. Since you generated the key with the test framework, you should use `signrawtransactionwithkey`. – Andrew Chow Mar 08 '22 at 21:35
  • Here is the Transaction before signing: CTransaction(nVersion=2 vin=[CTxIn(prevout=COutPoint(hash=b31ca5d5ba91df771d2e4c17dc67ed4fb9e3165acb99730df3bf44bf22403928 n=0) scriptSig=0014ddc48b68a304b5c9cbf7e52610398aa405b2aa62 nSequence=0)] vout=[CTxOut(nValue=49.99999000 scriptPubKey=a91418e6390ad3f0ae6f82a19b9bb163406a78e4356587)] wit=CTxWitness() nLockTime=0) – Bitcoin_1o1 Mar 09 '22 at 01:47
  • Based on your comment, I tried to generate the Address from the node: ```address = self.nodes[0].getnewaddress() pubkey = self.nodes[0].getaddressinfo(address)['pubkey'] pubkey_hash = hash160(pubkey.encode()) # .encode()``` – Bitcoin_1o1 Mar 09 '22 at 19:15
  • this is the Transaction HEX I get (still weird, cause the `scriptSig` is not there): `020000000128394022bf44bff30d7399cb5a16e3b94fed67dc174c2e1d77df91bad5a51cb3000000006a47304402200cf88582d5827d18b7756ca361634353adf967300030ba3090ecb749796d906b02204b7181eaf802b134a48ea4feb365333286045e1904c7c09d5f8d40c3d8ed230201210227d85ba011276cf25b51df6a188b75e604b38770a462b2d0e9fb2fc839ef5d3f000000000118ee052a0100000017a9141923ac992a31635121f6177babbdcf5ba576a4858700000000` – Bitcoin_1o1 Mar 09 '22 at 19:20
  • To use `signrawtransactionwithkey` first I would need to construct the raw transaction, `createrawtransaction` requires the inputs and the outputs, the destination address, but not the scriptPubKey or scriptSig, how should I do it? We got back to my original question. Can anyone point out what will be the correct way to do it? thx! – Bitcoin_1o1 Mar 12 '22 at 02:57

0 Answers0