bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.65k stars 2.09k forks source link

Creating a SegWit transaction #1611

Closed kss-espeo closed 4 years ago

kss-espeo commented 4 years ago

Hello!

I have a working p2pkh implementation of a wallet transaction. I am able to build transactions and successfully submit them to blockchain. I am looking to improve that implementation to include SegWit (p2wpkh). Specifically I want my code to work with bech32 addresses which requires being able to both send and receive SegWit transactions, AFAIK .

I have put together an implementation, basing on https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.spec.ts and some other code samples I found around the internet. It's not working for me - the node rejects my transaction with the following message: Message: non-mandatory-script-verify-flag (Signature must be zero for failed CHECK(MULTI)SIG operation) (code 64) .

I have also tried to compare hex that my code produced:

02000000000101472473424c76de5257aa5ec1aadb36569cf0728a448b10c3dd72344a3bdc99bb0100000000ffffffff02a0860100000000001600142e12e355523d82c266a68051fea92368d46a7a1f82af0d0000000000160014c09f9d50a3e78063b956ef6793399cafed6ab0aa02483045022100b02a3fa7bf6a070ff8d3694141119bdfbd978c07939c0d2e1cc971271ae77156022026495f120231053f89909fe4922794b169a556b9571a112f7580670c0a8601c1012102d987dc7e47283c5a8d9988d2c619db768ae6e86e35e65471d251c09b4e610e4e00000000

with a transaction structure quoted in https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki . It seems correct.

So what am I doing wrong? Please find a Gist with an excerpt from my implementation here: https://gist.github.com/kss-espeo/3accc915348ca3a2f6f246b570a8de49 and an UTXO I am trying to spend here: https://live.blockcypher.com/btc-testnet/tx/bb99dc3b4a3472ddc3108b448a72f09c5636dbaac15eaa5752de764c42732447/

junderw commented 4 years ago
  1. You should use PSBT and ECPair. It's much easier. With a hex-based private key all you need is to convert to Buffer, then use ECPair.fromPrivateKey with the network parameter as an additional data.

https://github.com/bitcoinjs/bitcoinjs-lib/blob/c0718a9f7c41f8235e46e2d015ada2c32021e0c7/test/integration/transactions.spec.ts#L315-L347

  1. See the SegWit spec: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#specification

The item 5:

  • For P2WPKH witness program, the scriptCode is 0x1976a914{20-byte-pubkey-hash}88ac.

Which is the format for P2PKH. So to put it simply: "In regards to the signatureHash, P2WPKH uses P2PKH script instead."

kss-espeo commented 4 years ago

Thanks @junderw . One additional question - in my case, I can't use a private key to directly sign a transaction . Instead, I need to use existing signature to apply it to a pre-built transaction. Therefore, I can't really use Psbt.signInput . Does Psbt support that? Should I use https://github.com/bitcoinjs/bitcoinjs-lib/blob/c0718a9f7c41f8235e46e2d015ada2c32021e0c7/src/psbt.js#L520 ?