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