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

How to use sequence in input? #12

Closed amber0515 closed 10 months ago

amber0515 commented 1 year ago

here is my code

    const txdata = Tx.create({
        vin: [{
            txid: '5b8ce54ca0993713552939b3d248c1f1b98c3ba18575f0d34f6b5ae13d58eac0',
            vout: 0,
            prevout: {
                value: 5000,
                scriptPubKey: ['OP_1', tpubkey]
            }
        }],
        vout: [
            {
                value: 4000,
                scriptPubKey: Address.toScriptPubKey(receiverAddress)
            }
        ]
    })
    console.log(txdata)
    const sig = Signer.taproot.sign(senderSeckey, txdata, 0, { extension: lockTapleaf })
    txdata.vin[0].witness = [sig.hex, puzzle.toString('hex'), lockScript, cblock]

then, I want to set sequence in input like this

const txdata = Tx.create({
        vin: [{
            txid: '5b8ce54ca0993713552939b3d248c1f1b98c3ba18575f0d34f6b5ae13d58eac0',
            vout: 0,
            prevout: {
                value: 5000,
                scriptPubKey: ['OP_1', tpubkey]
            },
            sequence: 6,
        }],
        vout: [
            {
                value: 4000,
                scriptPubKey: Address.toScriptPubKey(receiverAddress)
            }
        ]
    })

But I always got error "Transaction has superfluous witness data", what should I do?

amber0515 commented 1 year ago

I see, there is a bug when encode tx at squence part. I compare the raw txn between bitcoinjs-lib and tapscript.

If use tapscript,fffffffd is the default value in raw tx when I did not set a specific sequence number. If use bitcoinjs-lib, the value is fdffffff which is right.

As the same, in my case, if I want to set 6 as sequence number, the tapscript encode result is 06, but the right one is 06000000.

Here is the wrong raw transaction which cannot be broadcasted.

02000000000101c0ea583de15a6b4fd3f07585a13b8cb9f1c148d2b3392955133799a04ce58c5b0000000000
06 // here is the wrong bytecode
01a00f0000000000002251204ba4d03970647066920d20b72fc60363cda669df87d5611f2eed1392906b78560440119c9c0ea1d76ee02d5abe6900be47512d1203d1f77f14929aac20614fb6193f8d54db33d63ad5259828d3678098ac51b2419640a865ffee0bec2fb2cd2ec37d14ab183ebe43326234ecfab4fea082d34088110f9461a914ab183ebe43326234ecfab4fea082d34088110f948763200290230929463d99d776a7753fe7f4f9021449b36f6884e0471df812319caac2ac6755b27520aee9ec584ca8301362fe71b86cce1d0971f3dba31b0586f92b610d3eb812ff27ac6821c00290230929463d99d776a7753fe7f4f9021449b36f6884e0471df812319caac200000000

Here is the right one

02000000000101c0ea583de15a6b4fd3f07585a13b8cb9f1c148d2b3392955133799a04ce58c5b0000000000
06000000 // the right one
01a00f0000000000002251204ba4d03970647066920d20b72fc60363cda669df87d5611f2eed1392906b78560440bb7e797678c7e967397fb951c90a33ae5cb5927d676612fb46bd4448c2f075585bafd312f9711e182ae1f0ff641a2a5ba764b3f7156de9f3240c2a7e2b6609dd14ab183ebe43326234ecfab4fea082d34088110f9461a914ab183ebe43326234ecfab4fea082d34088110f948763200290230929463d99d776a7753fe7f4f9021449b36f6884e0471df812319caac2ac6755b27520aee9ec584ca8301362fe71b86cce1d0971f3dba31b0586f92b610d3eb812ff27ac6821c00290230929463d99d776a7753fe7f4f9021449b36f6884e0471df812319caac200000000

I dont know when author could fix this bug, but we can fix the problem by the following 2 steps:

Here is another example:

sequence number is 65536
- 65536 -> 0x00010000
- 0x00010000 -> 0x00000100

Hope it would help.

cmdruid commented 1 year ago

The default value is 0xFFFFFFFD when you start with a new transaction template, but that value should be properly reversed to 0xFDFFFFFF when you encode the transaction.

However, there was a bug where the sequence value was not being properly buffered with zeroes! Which would result in 06 instead of 06000000.

The bug should be fixed in the latest version. I will review the parse logic as well to make sure there aren't any other trouble areas where the proper zero padding may not be applied.