0

i made a P2WSH address with bitcoinjs-lib from a script. the same script results in the same address with bitcoin core. I made an unlocking script and tested the combination with btcdeb and everything looked fine, so i sent some sats to the address and tried unlocking it. however, bitcoin core gives me this error when trying to broadcast the transaction.

non-mandatory-script-verify-flag (unknown error)

the script is made by adding t times OP_OVER OP_SUB OP_1 OP_EQUALVERIFY and OP_0 OP_EQUAL to the end

you can run the code by putting it in a file in https://github.com/antonilol/btc_stuff and running npm i. (for bitcoinjs-lib package and files btc.js and btc2.js) on a node running testnet

my code:

const { send } = require('./btc')();
const { bech32toScriptPubKey } = require('./btc2');
const bitcoin = require('bitcoinjs-lib');
const network = bitcoin.networks.testnet;

const witnessScriptPiece = bitcoin.script.compile([
    bitcoin.opcodes.OP_OVER,
    bitcoin.opcodes.OP_SUB,
    bitcoin.opcodes.OP_1,
    bitcoin.opcodes.OP_EQUALVERIFY
]);

const l = witnessScriptPiece.length;

const witnessScriptEnd = bitcoin.script.compile([
    bitcoin.opcodes.OP_0,
    bitcoin.opcodes.OP_EQUAL
]);

const t = 3;

const witnessScript = Buffer.allocUnsafe(l * t + witnessScriptEnd.length);

for (var i = 0; i < t; i++) {
    witnessScriptPiece.copy(witnessScript, i * l);
}

witnessScriptEnd.copy(witnessScript, t * l);

console.log('Locking script: ' + witnessScript.toString('hex'));

console.log(
    'send 1000 sat to ' +
    bitcoin.payments.p2wsh({ redeem: { output: witnessScript, network }, network }).address
);

const tx = new bitcoin.Transaction(network);

// const txid = 'b37fc02fda463403a4d077863d163f6c2738659a4bba77284711ea8eeb95fc7d'; // t=17 vout=0
const txid = '407e7513afdd4baedeac62870acb7e426a6f7aa85ca45f7e54411e8b74d8876c'; // t=3 vout=1
const vout = 1;

tx.addInput(Buffer.from(txid, 'hex').reverse(), vout);
tx.setWitness(0, [
    ...Array(t + 1).fill().map((x, i) => {
        const b = Buffer.allocUnsafe(1);
        b.writeInt8(i);
        return b;
    }),
    witnessScript
]);

const fee_sat = 110;
const input_sat = 1000;

tx.addOutput(bech32toScriptPubKey('tb1q3my0fxc7n5sfx9c76p9mdyk6ly6j22wgp644q6'), input_sat-fee_sat);

send(tx.toHex()).then(console.log)

raw tx hex it produces for t=3:

010000000001016c87d8748b1e41547e5fa45ca87a6f6a427ecb0a8762acdeae4bddaf13757e400100000000ffffffff017a030000000000001600148ec8f49b1e9d2093171ed04bb692daf9352529c80501000101010201030e789451887894518878945188008700000000

t=17:

010000000001017dfc95eb8eea11472877ba4b9a6538276c3f163d8677d0a4033446da2fc07fb30000000000ffffffff017a030000000000001600148ec8f49b1e9d2093171ed04bb692daf9352529c8130100010101020103010401050106010701080109010a010b010c010d010e010f01100111467894518878945188789451887894518878945188789451887894518878945188789451887894518878945188789451887894518878945188789451887894518878945188008700000000

1 Answer 1

2

The error you are encountering is the requirement for the minimal encoding of data. Specifically, your witness stack contains 0x00 for the number 0. However this is not the minimal encoding of 0. Rather the minimal encoding for 0 is an empty vector. So your transactions should actually be

010000000001016c87d8748b1e41547e5fa45ca87a6f6a427ecb0a8762acdeae4bddaf13757e400100000000ffffffff017a030000000000001600148ec8f49b1e9d2093171ed04bb692daf9352529c805000101010201030e789451887894518878945188008700000000
010000000001017dfc95eb8eea11472877ba4b9a6538276c3f163d8677d0a4033446da2fc07fb30000000000ffffffff017a030000000000001600148ec8f49b1e9d2093171ed04bb692daf9352529c81300010101020103010401050106010701080109010a010b010c010d010e010f01100111467894518878945188789451887894518878945188789451887894518878945188789451887894518878945188789451887894518878945188789451887894518878945188008700000000
1
  • thanks, it worked. i also have it fixed in my javascript code now! (allocate 0 bytes buffer if i == 0)
    – Antoni
    Commented Jan 4, 2022 at 12:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.