vbuterin / pybitcointools

SImple, common-sense Bitcoin-themed Python ECC library
1.28k stars 856 forks source link

Add basic segwit support #184

Open bjarnemagnussen opened 6 years ago

bjarnemagnussen commented 6 years ago

Adds support for the segwit transaction structure and signing of P2WPKH segwit inputs.

New functions:

Also adds the following new internal functions used by sign_segwit_struct(): mk_p2wpkh_scriptcode(pubkey); mk_p2wpkh_redeemscript(pubkey); pubkey_to_hash(pubkey); signature_form_segwit(tx, i, scriptCode, amount, hashcode=SIGHASH_ALL); mk_hashOutputs(out, hashcode=SIGHASH_ALL); mk_hashInputs(inp, hashcode=SIGHASH_ALL); serialize_signature_form_segwit(txobj).

Example usage:

from bitcoin import *

Making the deposit P2WPKH address:

priv = sha256("binfiUlnidyapyenPecNijOd5") priv '944a059c201d4fa4a8362fdc16695cce4aa14b26275834c6239b5048b756a6a2' pub = compress(privtopub(priv)) pub '0208166a7cc4ec694b9874acaa1f837128cabb17b785d457d3d39b2369da346aa8' address = script_to_address(mk_p2wpkh_script(pub)) address '36BoUfjer5Y8Ezncsy6ZgYRmYEJk3HP8V4'

Making the tx:

inputs = unspent('36BoUfjer5Y8Ezncsy6ZgYRmYEJk3HP8V4')

inputs = [{'output': '5f9738939f6da66974e88967cfb858a8f427a82d46ee05a5f97c8bb14ef0bc83:1', 'value': 28851}] outputs = [{'value': 25000, 'address': '39uWVDaxPKNBxttUKc7FdXNPGwmMwqtaPC'}] tx = mktx(inputs, outputs, True) tx_signed = sign_segwit_struct(tx, 0, priv, 1, True) deserialize(tx_signed,True) {'outs': [{'value': 25000, 'script': 'a9145a1dd75ee9121ccea2acc822e335a3e15b7ddf5e87'}], 'ins': [{'script': '160014364ccd6a55f64ebda93e80706dc3fda32a16ff6e', 'outpoint': {'index': 1, 'hash': '5f9738939f6da66974e88967cfb858a8f427a82d46ee05a5f97c8bb14ef0bc83'}, 'sequence': 4294967295}], 'flag': 1, 'version': 1, 'marker': 0, 'locktime': 0, 'witness': [{'scriptCode': '4830450221008fb1f09f88a95f21f0b76a36782f861fe274d1e6e45dbbe44315212da228b7d702206b850d52a9bf5e9175179161d0e4c52f5caecaea378c43425396a59d8fe9ab3801210208166a7cc4ec694b9874acaa1f837128cabb17b785d457d3d39b2369da346aa8', 'number': 2}]} tx_signed 0100000000010183bcf04eb18b7cf9a505ee462da827f4a858b8cf6789e87469a66d9f9338975f0100000017160014364ccd6a55f64ebda93e80706dc3fda32a16ff6effffffff01a86100000000000017a9145a1dd75ee9121ccea2acc822e335a3e15b7ddf5e87024830450221008fb1f09f88a95f21f0b76a36782f861fe274d1e6e45dbbe44315212da228b7d702206b850d52a9bf5e9175179161d0e4c52f5caecaea378c43425396a59d8fe9ab3801210208166a7cc4ec694b9874acaa1f837128cabb17b785d457d3d39b2369da346aa800000000 pushtx(tx_signed) 'Transaction Submitted'

The example from the README using legacy transactio structure still works as expected.

This is only thought of as a first start to implement segwit and so many bugs are expected and more rigorous testing is necessary and implementation of other segwit types.

reiven commented 6 years ago

hey @wizardofozzie it will be possible to add this PR to your fork? let me know if i can help somehow