cmdruid / tapscript

A humble library for working with Tapscript and Bitcoin Transactions.
https://www.npmjs.com/package/@cmdcode/tapscript
Creative Commons Zero v1.0 Universal
188 stars 49 forks source link

Public key version reserved for soft-fork upgrades #31

Closed pokrovskyy closed 8 months ago

pokrovskyy commented 8 months ago

Hi, I'm playing with taproot scripts via tapscript and bumped into this blocker when trying to send raw transaction on Bitcoin Signet via bitcoin-cli -signet sendrawtransaction:

error code: -26
error message:
non-mandatory-script-verify-flag (Public key version reserved for soft-fork upgrades)

Here is the code I'm using:

const {Address, Script, Signer, Tap, Tx} = require('@cmdcode/tapscript')
const utils = require('@cmdcode/crypto-utils')

const secret = '.....'
const seckey = utils.keys.get_seckey(secret)
const pubkey = utils.keys.get_pubkey(seckey)

const script = [....]
const tapleaf = Tap.encodeScript(script)
const [tpubkey, cblock] = Tap.getPubKey(pubkey, {target: tapleaf})
const address = Address.p2tr.fromPubKey(tpubkey, 'signet')

const txdata = Tx.create({
      vin: [{
          txid: '.....',
          vout: 1,
          prevout: {
              value: 100000,
              scriptPubKey: ['OP_1', tpubkey]
          },
      }],
      vout: [
          {
              value: 90000,
              scriptPubKey: Address.toScriptPubKey('tb1p.....')
          }
      ]
  })
const sig = Signer.taproot.sign(seckey, txdata, 0, {extension: tapleaf, throws: true})
txdata.vin[0].witness = [sig.hex, script, cblock]

await Signer.taproot.verify(txdata, 0, {pubkey, throws: true})

Is there anything wrong with how get_pubkey derives public key? Or any other reason I might be getting this strange error? Thanks!

pokrovskyy commented 8 months ago

Update - I switched to "@cmdcode/crypto-utils": "2.0.2" and now using this to generate private/public key pair:

const seckey = util.getSecretKey(secret)
const pubkey = util.getPublicKey(seckey, true)

And it now works 😄 (for anyone bumping into this) So I guess it is a matter of using the right key generation functions. However I would still appreciate the answer on how to do this properly with up-to-date library versions @cmdruid Thanks!

cmdruid commented 8 months ago

Public key version reserved for soft-fork upgrades

This error happens when you use a 33-byte pubkey in a taproot script instead of a 32-byte pubkey.

In newer versions of the crypto library, I have switched to using 32-byte pubkeys by default, since that is the direction things seem to be going.

The taproot upgrade reserves that 33rd byte as a version number for future upgrades.

I hope that helps!

pokrovskyy commented 8 months ago

oh, I see! will take that into account, makes sense 👌