How to create raw transactions with bgoldjs-lib
BitcoinGoldJS (bgoldjs-lib) is a fork of the famous bitcoinjs-lib. Created for NodeJS and browsers, it makes creating a Bitcoin Gold (BTG) transaction easier than ever.
Note! It’s recommended to become familiar with the functions of the library on the Bitcoin Gold testnet first; sending raw transactions to the mainnet network will lead to monetary losses if you don’t pay attention to the details. Regtest can also be used for experimentation, which is not a public network and does not require connecting to peers. Testnet is preferred: it runs the same code as mainnet but without sending and receiving real money.
Basic non-SegWit transaction with P2PKH input
Now, let’s create our first Bitcoin Gold raw transaction. For this tutorial, we are going to use the NodeJS environment and TypeScript and will create a basic (non-SegWit) transaction.
Set up a project
The first step is to set up the project. Open your terminal, navigate to the project folder, and do the following:
- Initialize the project
npm init --yes
(You can use also “yarn” for a package manager)
2. Install a TypeScript compiler globally (global installation is recommended for beginners, because local installation can be more complex)
npm i -g typescript
3. You can test your install by checking the version
tsc --version
4. Install bgoldjs-lib as a dependency
npm i bgoldjs-lib
5. Generate a tsconfig.json file
tsc --init
6. Pointed out a “rootDir” and “outDir” in the tsconfig.json file and create a “src” folder in the project folder
7. Create a start script in the package.json file. It will compile the typescript file and will run “dist/index.js
Now, we can start creating our transaction!
Create an index.ts file in the “src” folder and add a line of code to import the library.
import bgold = require('bgoldjs-lib');
Generate Key-Pair
This is the underlying basis of an address. The easiest way to generate Elliptic Curve Pair is with the bgoldjs-lib random generator.
const keyPair = bgold.ECPair.makeRandom({ network: bgold.networks.bitcoingoldtestnet });
Generate P2PKH address
Create an address with the public key from the randomly generated EC Pair and print it to the console, so we can copy it and send some testnet BTG to it through some Bitcoin Gold testnet faucet.
const { address } = bgold.payments.p2pkh({ pubkey: keyPair.publicKey, network: bgold.networks.bitcoingoldtestnet});console.log(address)
Create variable for SIGHASH ID constant
This variable is used in the SIGHASH_FORK_ID replay protection mechanism of Bitcoin Gold.
const SIGHASH = bgold.Transaction.SIGHASH_ALL | bgold.Transaction.SIGHASH_FORKID;
We are going to use the constant later in the code.
Create our transaction
Now is the moment to initialize our transaction.
let psbt = new bgold.Psbt({ network: bgold.networks.bitcoingoldtestnet });
Add inputs
The next step is to add inputs to our transaction. It accepts as the “inputData” parameter an object consisting of:
- hash, which is the id of the transaction from which we want to spend a UTXO
- index, which is the index of the UTXO we want to spend
- nonWitnessUtxo, which is a buffer from the transaction hexadecimal representation.
- sighashType — this property is needed for the SIGHASH_FORK_ID replay protection which is implemented in Bitcoin Gold.
psbt.addInput({
hash: txid,
index: n,
nonWitnessUtxo: Buffer.from(tx.hex, 'hex'),
sighashType: SIGHASH,
});
Add outputs
Next, we have to add outputs that represent where to send the BTG which we added in the inputs. The needed properties for this parameter object are:
- address — where we want to send the BTG
- value — the sum we are going to send in Satoshis
const addressToSend = "You have to paste valid address here";psbt.addOutput({ address: addressToSend, value: 100000000 - 10000 });
Note! Any Satoshi which is added from the inputs but not spent in the outputs will be considered a miner’s fee. So, be careful with the value property. In our example, the UTXO (which is the input in our new transaction) has 100000000 Satoshis and in the output of the transaction we specify (100000000–10000). This way, 1000 Satoshis will go to the miners. The minimum mining fee for a transaction is 1 Satoshi per byte, but for simplicity I am using 10000 in this example.
Sign the transaction
The next step, which is critical, is to sign the transaction. This way we prove that we are the owners of the added UTXOs (inputs), unlock them with our private key and send them to somebody else.
Here we add as parameters:
- inputIndex — the index of the input we sign (in case the transaction has many inputs)
- the keyPair we created above
- sigHashTypes — an array that contains our sigHash variable
psbt.signInput(0, masterKey, [SIGHASH]);
Extract the transaction
It remains only to finalize our inputs and output its hexadecimal representation.
psbt.finalizeInput(0);
console.log(psbt.extractTransaction().toHex());
Now we run our program and…
npm start
Congratulations, we created our raw Bitcoin Gold Transaction! (It can be broadcast to the network by copying the signed transaction to an explorer websites which supports broadcasting, or by using a wallet app that accepts raw transactions for broadcast, such as the BTG Core Wallet or ElectrumG.)
Here you can view the source code of the tutorial. Don’t forget to provide real transaction data!
Other types of a transaction
All other types of transaction which are supported by bitcoinjs-lib are also supported by bgoldjs-lib. You just have to add the SIGHASH_FORK_ID variable which we created above.
About the author
I am a Blockchain Developer in GoStartups.net and a contributor to a Bitcoin Gold project.