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?

DeathAndTaxes
  • 8,797
  • 2
  • 37
  • 65
heyo
  • 81
  • 2
  • 4

3 Answers3

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.

Nick ODell
  • 29,396
  • 11
  • 72
  • 130
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();

pseudozach
  • 274
  • 1
  • 8
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
thalisk
  • 483
  • 3
  • 11