var bitcoin = require('bitcoinjs-lib');
var testnet = bitcoin.networks.testnet;
Example of transaction that creates and signs a HRC20 transfer transaction for Hydra using the bitcoin-js library.
The transaction format is nearly identical to that of Bitcoin, except for the OP_CALL output.
Note, since OP_CALL is a Hydra specific opcode, it needs to be hardcoded as 0xc2
The script below will assume that the input tx being spent is a P2PKH output.
// The input tx hash and vout of the utxo we are going to spend
const TXINHASH = "e06d87ecfc8563e899118de9b9fc9deafc9aba41f2c420075bbf2c610fe160fc";
// The WIF key of the input key. Hydra uses the same WIF format and prefx as Bitcoin
const TXINKEY = bitcoin.ECPair.fromWIF('cVNrcCHX5q318dDkpMFoLD1ack7TybxEjFB44xCsv5sW35kM7QuE', testnet);
// The value of the utxo, Hydra uses the same number of decimals as Bitcoin (8 decimals)
const TXINVALUE = 2000000000000;
// The contract address we wish to call
const HRC20_CONTRACT = "a20ee8612b8d338c55dcd03e65544339efd7cebc";
// The receiver address. Note that the SENDER is the address of the UTXO we are spending.
const HRC20_RECEIVER="qauZFnmbNBNuY2ujQateDwzvL6zoxBiY3H";
// The number of tokens we want to transfer
const HRC20_TOKEN_TRANSFER_VALUE=1n;
// The number of decimals defined by the HRC20 contract.
// The minimum gas price is 0.00000040 Hydra, so we set the gas price to that here
// The gas schedule of Hydra is virtually identical to that of Ethereum, so a value that works for Ethereum will typically work for Hydra
// The OP_CALL (0xc2) opcode is Hydra specific and must therefore be hardcoded.
var hrc20_receiver_hex=bitcoin.address.fromBase58Check(HRC20_RECEIVER)['hash'].toString('hex')
var hrc20_token_transfer_value_adjusted=HRC20_TOKEN_TRANSFER_VALUE * (10n**HRC20_DECIMALS);
var hrc20_token_transfer_value_adjusted_hex=("0".repeat(64) + hrc20_token_transfer_value_adjusted.toString(16)).slice(-64)
// The calldata, should be ABI encoded according the Ethereum ABI specification.
var calldata = "a9059cbb000000000000000000000000"+hrc20_receiver_hex+hrc20_token_transfer_value_adjusted_hex;
// The input value minus the gas cost/txfee
var changeValue = TXINVALUE-(GASPRICE*GASLIMIT);
// The opcall scriptPubKey on the form of "version gaslimit gasprice calldata contractaddress OP_CALL"
var contractCallScript = bitcoin.script.compile([
bitcoin.script.number.encode(4), // version
bitcoin.script.number.encode(GASLIMIT), // gas limit
bitcoin.script.number.encode(GASPRICE), // gas price
new Buffer(calldata, "hex"), // The ABI encoded calldata
new Buffer(HRC20_CONTRACT, "hex"), // the contract's address
OP_CALL // OP_CALL opcode
// A normal P2PKH change output
var changeScript = bitcoin.script.compile([
bitcoin.opcodes.OP_HASH160,
new Buffer(bitcoin.crypto.hash160(TXINKEY.publicKey)),
bitcoin.opcodes.OP_EQUALVERIFY,
bitcoin.opcodes.OP_CHECKSIG
var txb = new bitcoin.TransactionBuilder(testnet);
txb.addInput(TXINHASH, TXINVOUT);
txb.addOutput(contractCallScript, 0);
txb.addOutput(changeScript, changeValue);