2

I know how to create a basic TX:

var bitcoin = require('bitcoinjs-lib')

var tx = new bitcoin.Transaction()

// Add the input (who is paying) of the form [previous transaction hash, index of the output to use]
tx.addInput("aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31", 0)

// Add the output (who to pay to) of the form [payee's address, amount in satoshis]
tx.addOutput("THEADDRESS", 15000)

// Initialize a private key using WIF
key = bitcoin.ECKey.fromWIF("L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy")

// Sign the first input with the new key
tx.sign(0, key)

// Print transaction serialized as hex
console.log(tx.toHex())
// => 0100000001313eb630b128102b60241ca895f1d0ffca2170d5a0990e094f2182c102ab94aa000000008a47304402200169f1f844936dc60df54e812345f5dd3e6681fea52e33c25154ad9cc23a330402204381ed8e73d74a95b15f312f33d5a0072c7a12dd6c3294df6e8efbe4aff27426014104e75628573696aed32d7656fb35e9c71ea08eb6492837e13d2662b9a36821d0fff992692fd14d74fdec20fae29128ba12653249cbeef521fc5eba84dde0689f27ffffffff01983a0000000000001976a914ad618cf4333b3b248f9744e8e81db2964d0ae39788ac00000000

// You could now push the transaction onto the Bitcoin network manually (see https://blockchain.info/pushtx)

But I didn't find out how I could create a OP_RETURN transaction with bitcoinjs-lib in Node.js. Does anyone know?

1

3 Answers 3

10

Here:

var bitcoin = require('bitcoinjs-lib')

data = new Buffer("Melons.")

var tx = new bitcoin.TransactionBuilder()
tx.addInput("aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31", 0)
tx.addOutput("some address", 15000)
ret = bitcoin.script.compile(
  [
    bitcoin.opcodes.OP_RETURN,
    data
  ])
tx.addOutput(ret, 0)
key = bitcoin.ECPair.fromWIF("L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy")
tx.sign(0, key)
console.log(tx.build().toHex())

That should do it.

Also, if you have more than 40 bytes of data, your transaction will be non-standard.

2
  • 2
    Seems things have changed. Now, instead of manually using a buffer and calling the compile function, I had to use bitcoin.script.nullDataOutput("Mellons."). I hope that helps someone. Commented Dec 9, 2016 at 6:01
  • 1
    nullDataoutput is deprecated Commented Aug 11, 2017 at 15:32
2

Here's how I was able to accomplish this with the latest bitcoinjs-lib version (5.2.0) using psbt.

const alice = bitcoin.ECPair.fromWIF(wif, bitcoin.networks.regtest);
const inputData1 = {
    hash: randomutxo.txid,
    index: randomutxo.vout,
    witnessUtxo: {script: Buffer.from(randomutxo.scriptPubKey, 'hex'), value: parseInt(randomutxo.amount*100000000)}
    };
const data = Buffer.from('YOUR OP_RETURN DATA HERE', 'utf8');
const embed = bitcoin.payments.embed({ data: [data] });
const psbt = new bitcoin.Psbt({ network: bitcoin.networks.regtest })
    .addInput(inputData1)
    .addOutput({
    script: embed.output,
    value: 0,
    })
    .addOutput({
    address: 'bcrt1q7xp6jcgmnuvvaqzr9sdg7yjdqfftswjdqz9897',
    value: 50000,
    })
    .addOutput({
    address: 'bcrt1q7xp6jcgmnuvvaqzr9sdg7yjdqfftswjdqz9897',
    value: parseInt(randomutxo.amount*100000000)-100000,
    })
    .signInput(0, alice);

psbt.finalizeAllInputs();
const txHex = psbt.extractTransaction().toHex();
1

For bitcoinjs-lib 3.2.0 (not latest):

bitcoinjs = require('bitcoinjs-lib');

const wif = 'private-key-of-sender-in-WIF';
const sender = 'miq6AWvTYZJ63hJfh1W7zozHAf1URDv5pS';
const unspent_txid = '8e320e71d43b130c0786cc9d50fae9ed79b953fba9bcf45070625e37120544c3';
const unspent_vout = 1;
const network = bitcoinjs.networks.testnet;
const keyPair = bitcoinjs.ECPair.fromWIF(wif,network);
const recipient = 'mwLfrTGnLNtyLWFzLfPVcmxEMcW4yaRUZA';

const txb = new bitcoinjs.TransactionBuilder(network);
const data = Buffer.from('YOUR OP_RETURN DATA HERE', 'utf8');
const dataScript = bitcoinjs.script.nullData.output.encode(data);
txb.addInput(unspent_txid, unspent_vout); // payer
txb.addOutput(recipient, Math.floor(1.88*1e8)); // payee
txb.addOutput(dataScript, 0); // OP_RETURN always with 0 value unless you want to burn coins

txb.sign(0, keyPair);

const txRaw = txb.build();
const txHex = txRaw.toHex();

// To broadcast, use local bitcoin core's `sendrawtransaction` or 3rd party service

UPDATE: with bitcoinjs-lib 5.0.2 (latest), same as above, only update the dataScript evaluation and the adding of the OP_RETURN output:

const dataScript = bitcoinjs.payments.embed({ data: [data] });
txb.addOutput(dataScript.output, 0); // OP_RETURN always with 0 value unless you want to burn coins

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.