bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.71k stars 2.11k forks source link

TypeError: buf.writeBigInt64LE is not a function when using hashLockScript in input #2179

Closed bitcoinwarrior1 closed 3 weeks ago

bitcoinwarrior1 commented 3 weeks ago

Hi guys, thank you so much for creating this library!

I am trying to create a taproot script that allows a user to spend funds by providing a message and signature.

function getTaprootAddressFromMessage(message) {
    const msgBytes = Buffer.from(message);
    const hash = bitcoin.crypto.hash160(msgBytes);
    const hashHexString = Buffer.from(hash).toString("hex");
    const pubkeyHexString = Buffer.from(toXOnly(keyPair.publicKey)).toString(
      "hex",
    );
    const hashScriptAsm = `OP_HASH160 ${hashHexString} OP_EQUALVERIFY ${pubkeyHexString} OP_CHECKSIG`;
    const p2pkLockScriptAsm = `${pubkeyHexString} OP_CHECKSIG`;
    const hashLockScript = bitcoin.script.fromASM(hashScriptAsm);
    const p2pkLockScript = bitcoin.script.fromASM(p2pkLockScriptAsm);
    const scriptTree = [
      {
        output: hashLockScript,
      },
      {
        output: p2pkLockScript,
      },
    ];

    const { output, address, witness, redeem  } = bitcoin.payments.p2tr({
      internalPubkey: toXOnly(keyPair.publicKey),
      scriptTree,
      redeem: {
        output: hashLockScript,
      },
      network: bitcoin.networks.bitcoin,
    });

    return {
      output,
      address,
      hashLockScript,
      witness
    }

  }

After generating the taproot address and sending funds, I tried to spend the input by providing the tapLeafScript using the hashLockScript variable from above.

psbt.addInput({
        hash: utxos[0].tx_hash,
        index: utxos[0].tx_output_n,
        witnessUtxo: { value: BigInt(utxos[0].value), script: output },
        tapLeafScript: [
          {
            leafVersion: 192,
            script: hashLockScript, // This variable causes the error 
            controlBlock: witness[witness.length - 1],
          },
        ],
      });

The hashLockScript variable causes the error. The error does not occur if I use the output variable. Both are Uint8Arrays

Screenshot 2024-11-02 at 1 20 20 pm

Since the code runs on the client side, I imported the buffer module to resolve the issue, but it persists.

const Buffer = require('buffer/').Buffer;

Any idea what I could be doing wrong? Thank you for your time.

jasonandjay commented 3 weeks ago
function writeInt64(buffer, offset, value, littleEndian) {
    if (offset + 8 > buffer.length) {
        throw new Error("Offset is outside the bounds of Uint8Array");
    }
    if (value > 0x7fffffffffffffffn || value < -0x8000000000000000n) {
        throw new Error(`The value of "value" is out of range. It must be >= ${-0x8000000000000000n} and <= ${0x7fffffffffffffffn}. Received ${value}`);
    }
    littleEndian = littleEndian.toUpperCase();
    const buf = Buffer.alloc(8);
    if (littleEndian === "LE") {
        buf.writeBigInt64LE(value, 0);
    }
    else {
        buf.writeBigInt64BE(value, 0);
    }
    buffer.set(Uint8Array.from(buf), offset);
    return offset + 8;
}

it seems there's an error here. Can i have your detialed information about running environment?

junderw commented 3 weeks ago

Your node version or bundler is very old.

uint8array-tools has an explicitly designated browser version that your bundler is ignoring, instead it is trying to use the NodeJS version and transpile it into the browser.

if you can create a dummy repository with a minimal example using a modern bundler on its latest version we can try to fix it. (It might be a bug in the bundler)

if you are using an old version of an old bundler, try updating to the latest version

bitcoinwarrior1 commented 3 weeks ago

Thank you, @junderw & @jasonandjay, for your replies. I tried the script in node.js, and it works. It looks like the bundler was the issue.