Skip to main content
edited tags
Link
Vojtěch Strnad
  • 10.4k
  • 3
  • 14
  • 43
const hexData = Buffer.from(
  `{"p":"brc-20","op":"transfer","tick":"${tick}","amt":"${amount.toString()}"}`
).toString("hex");
const publicKeyHex = toXOnly(tweakedSigner.publicKey).toString("hex");
let inscribeLockScript = bitcoin.script.fromASM(
  `${publicKeyHex} OP_CHECKSIG OP_0 OP_IF ${Buffer.from("ord").toString(
    "hex"
  )} OP_1 ${Buffer.from("text/plain;charset=utf-8").toString(
    "hex"
  )} OP_0 ${splitByNChars(hexData, 1040).join(" ")} OP_ENDIF`
);
inscribeLockScript = Buffer.from(
  inscribeLockScript.toString("hex").replace("6f726451", "6f72640101"),
  "hex"
);

const scriptTree: Taptree = {
  output: inscribeLockScript,
};

const inscribeLockRedeem = {
  output: inscribeLockScript,
  redeemVersion: 192,
};

const inscribeP2tr = bitcoin.payments.p2tr({
  internalPubkey: toXOnly(tweakedSigner.publicKey),
  scriptTree,
  network: bitcoin.networks.bitcoin,
  redeem: inscribeLockRedeem,
});

const tapLeafScript = {
  leafVersion: inscribeLockRedeem.redeemVersion!,
  script: inscribeLockRedeem.output || Buffer.from(""),
  controlBlock: inscribeP2tr.witness![inscribeP2tr.witness!.length - 1],
};

psbt.addInput({
  hash: utxo.hash,
  index: utxo.index,
  witnessUtxo: {
    script: inscribeP2tr.output!,
    value: utxo.value,
  },
  tapInternalKey: toXOnly(tweakedSigner.publicKey),
  tapLeafScript: [tapLeafScript],
});
const hexData = Buffer.from(
  `{"p":"brc-20","op":"transfer","tick":"${tick}","amt":"${amount.toString()}"}`
).toString("hex");
const publicKeyHex = toXOnly(tweakedSigner.publicKey).toString("hex");
let inscribeLockScript = bitcoin.script.fromASM(
  `${publicKeyHex} OP_CHECKSIG OP_0 OP_IF ${Buffer.from("ord").toString(
    "hex"
  )} OP_1 ${Buffer.from("text/plain;charset=utf-8").toString(
    "hex"
  )} OP_0 ${splitByNChars(hexData, 1040).join(" ")} OP_ENDIF`
);
inscribeLockScript = Buffer.from(
  inscribeLockScript.toString("hex").replace("6f726451", "6f72640101"),
  "hex"
);

const scriptTree: Taptree = {
  output: inscribeLockScript,
};

const inscribeLockRedeem = {
  output: inscribeLockScript,
  redeemVersion: 192,
};

const inscribeP2tr = bitcoin.payments.p2tr({
  internalPubkey: toXOnly(tweakedSigner.publicKey),
  scriptTree,
  network: bitcoin.networks.bitcoin,
  redeem: inscribeLockRedeem,
});

const tapLeafScript = {
  leafVersion: inscribeLockRedeem.redeemVersion!,
  script: inscribeLockRedeem.output || Buffer.from(""),
  controlBlock: inscribeP2tr.witness![inscribeP2tr.witness!.length - 1],
};

psbt.addInput({
  hash: utxo.hash,
  index: utxo.index,
  witnessUtxo: {
    script: inscribeP2tr.output!,
    value: utxo.value,
  },
  tapInternalKey: toXOnly(tweakedSigner.publicKey),
  tapLeafScript: [tapLeafScript],
});
const hexData = Buffer.from(
  `{"p":"brc-20","op":"transfer","tick":"${tick}","amt":"${amount.toString()}"}`
).toString("hex");
const publicKeyHex = toXOnly(tweakedSigner.publicKey).toString("hex");
let inscribeLockScript = bitcoin.script.fromASM(
  `${publicKeyHex} OP_CHECKSIG OP_0 OP_IF ${Buffer.from("ord").toString(
    "hex"
  )} OP_1 ${Buffer.from("text/plain;charset=utf-8").toString(
    "hex"
  )} OP_0 ${splitByNChars(hexData, 1040).join(" ")} OP_ENDIF`
);
inscribeLockScript = Buffer.from(
  inscribeLockScript.toString("hex").replace("6f726451", "6f72640101"),
  "hex"
);

const scriptTree: Taptree = {
  output: inscribeLockScript,
};

const inscribeLockRedeem = {
  output: inscribeLockScript,
  redeemVersion: 192,
};

const inscribeP2tr = bitcoin.payments.p2tr({
  internalPubkey: toXOnly(tweakedSigner.publicKey),
  scriptTree,
  network: bitcoin.networks.bitcoin,
  redeem: inscribeLockRedeem,
});

const tapLeafScript = {
  leafVersion: inscribeLockRedeem.redeemVersion!,
  script: inscribeLockRedeem.output || Buffer.from(""),
  controlBlock: inscribeP2tr.witness![inscribeP2tr.witness!.length - 1],
};

psbt.addInput({
  hash: utxo.hash,
  index: utxo.index,
  witnessUtxo: {
    script: inscribeP2tr.output!,
    value: utxo.value,
  },
  tapInternalKey: toXOnly(tweakedSigner.publicKey),
  tapLeafScript: [tapLeafScript],
});
const hexData = Buffer.from(
  `{"p":"brc-20","op":"transfer","tick":"${tick}","amt":"${amount.toString()}"}`
).toString("hex");
const publicKeyHex = toXOnly(tweakedSigner.publicKey).toString("hex");
let inscribeLockScript = bitcoin.script.fromASM(
  `${publicKeyHex} OP_CHECKSIG OP_0 OP_IF ${Buffer.from("ord").toString(
    "hex"
  )} OP_1 ${Buffer.from("text/plain;charset=utf-8").toString(
    "hex"
  )} OP_0 ${splitByNChars(hexData, 1040).join(" ")} OP_ENDIF`
);
inscribeLockScript = Buffer.from(
  inscribeLockScript.toString("hex").replace("6f726451", "6f72640101"),
  "hex"
);

const scriptTree: Taptree = {
  output: inscribeLockScript,
};

const inscribeLockRedeem = {
  output: inscribeLockScript,
  redeemVersion: 192,
};

const inscribeP2tr = bitcoin.payments.p2tr({
  internalPubkey: toXOnly(tweakedSigner.publicKey),
  scriptTree,
  network: bitcoin.networks.bitcoin,
  redeem: inscribeLockRedeem,
});

const tapLeafScript = {
  leafVersion: inscribeLockRedeem.redeemVersion!,
  script: inscribeLockRedeem.output || Buffer.from(""),
  controlBlock: inscribeP2tr.witness![inscribeP2tr.witness!.length - 1],
};

psbt.addInput({
  hash: utxo.hash,
  index: utxo.index,
  witnessUtxo: {
    script: inscribeP2tr.output!,
    value: utxo.value,
  },
  tapInternalKey: toXOnly(tweakedSigner.publicKey),
  tapLeafScript: [tapLeafScript],
});
Source Link

"Witness program hash mismatch" code -26 when broadcasting a transaction

I'm trying to broadcast a transaction to my RPC provider:

curl https://my-quicknode-rpc-provider/ \
    -X POST \
    -H "Content-Type: application/json" \
    --data '{"method": "sendrawtransaction", "params": ["02000000000101cc0fc61320a04525c8dabf30241fe9a64b3f8c28ebf61a9700b8a57a76306bac0000000000ffffffff01ea100000000000002251208dace6f04076ca1ea4eb168dcdad6ad61f695ca1c16a3df6b9586cdca1c71db8034025871482b0c7bb14b8c72d5ac44ce069991505a1aeca1c4de5b8d1857831ca87e6f43a3e784c755595574c798892ecf58c7ae525bccba441cdf46862dd405bb47e208dace6f04076ca1ea4eb168dcdad6ad61f695ca1c16a3df6b9586cdca1c71db8ac0063036f7264010118746578742f706c61696e3b636861727365743d7574662d3800387b2270223a226272632d3230222c226f70223a227472616e73666572222c227469636b223a2270657065222c22616d74223a22313030227d6821c18dace6f04076ca1ea4eb168dcdad6ad61f695ca1c16a3df6b9586cdca1c71db800000000"]}'

but I keep getting this error response from the RPC:

{"result":null,"error":{"code":-26,"message":"non-mandatory-script-verify-flag (Witness program hash mismatch)"},"id":null}

I've verified multiple times that I'm signing with the correct private key. On top of that, this occurs when broadcasting to the network, not during signing my PSBT inputs so I've been having trouble debugging.

For some context, I'm trying to attach a Taproot script to my input UTXO. Here is a code snippet of what I'm doing:

const hexData = Buffer.from(
  `{"p":"brc-20","op":"transfer","tick":"${tick}","amt":"${amount.toString()}"}`
).toString("hex");
const publicKeyHex = toXOnly(tweakedSigner.publicKey).toString("hex");
let inscribeLockScript = bitcoin.script.fromASM(
  `${publicKeyHex} OP_CHECKSIG OP_0 OP_IF ${Buffer.from("ord").toString(
    "hex"
  )} OP_1 ${Buffer.from("text/plain;charset=utf-8").toString(
    "hex"
  )} OP_0 ${splitByNChars(hexData, 1040).join(" ")} OP_ENDIF`
);
inscribeLockScript = Buffer.from(
  inscribeLockScript.toString("hex").replace("6f726451", "6f72640101"),
  "hex"
);

const scriptTree: Taptree = {
  output: inscribeLockScript,
};

const inscribeLockRedeem = {
  output: inscribeLockScript,
  redeemVersion: 192,
};

const inscribeP2tr = bitcoin.payments.p2tr({
  internalPubkey: toXOnly(tweakedSigner.publicKey),
  scriptTree,
  network: bitcoin.networks.bitcoin,
  redeem: inscribeLockRedeem,
});

const tapLeafScript = {
  leafVersion: inscribeLockRedeem.redeemVersion!,
  script: inscribeLockRedeem.output || Buffer.from(""),
  controlBlock: inscribeP2tr.witness![inscribeP2tr.witness!.length - 1],
};

psbt.addInput({
  hash: utxo.hash,
  index: utxo.index,
  witnessUtxo: {
    script: inscribeP2tr.output!,
    value: utxo.value,
  },
  tapInternalKey: toXOnly(tweakedSigner.publicKey),
  tapLeafScript: [tapLeafScript],
});

I'm fairly new to this so any help would be appreciated!