Connect to the Chromia blockchain
In this section, we'll guide you through connecting to the blockchain using a client. We will together build an example
client and we start by adding all required imports at the top of our file book_review.ts
.
import { encryption, createClient, newSignatureProvider, IClient } from "postchain-client";
import * as readline from "readline";
Then, we create a main function and add a helper function to receive input:
async function main() {}
The createClient
method
The createClient
returns a client instance that enables us to query the blockchain and send transactions. Let's add it
and break down how it works:
let client: IClient;
const blockchainRID = "<Blockchain RID>";
async function main() {
client = await createClient({
nodeUrlPool: "http://localhost:7740",
blockchainRid: blockchainRID,
});
}
Parameters:
-
nodeUrlPool
: This is the URL of the node you want to connect to. In most development scenarios, Chromia nodes run locally, often ashttp://localhost:7740
. However, in a production or testnet scenario, you'd use the address of a remote node. -
blockchainRid
: Every Chromia blockchain has a unique Referential Identifier (RID). It's a hexadecimal string that distinguishes different blockchains.
In the code snippet above, we connect to a local Chromia node and specify the blockchain of interest using its RID.
Why is this important?
-
Specificity: A single Chromia node might be aware of multiple blockchains, the RID ensures you interact with the correct one.
-
Flexibility: By parameterizing the node URL and blockchain RID, you can easily switch between different environments (e.g., development, staging, production) or blockchains without changing your app's core logic.
How to get the Blockchain RID When you have a node running you can always query the node for the Blockchain RID using:
curl http://localhost:7740/brid/iid_0
Sign a transaction with postchain-client
The postchain-client
library simplifies transaction signing for Chromia. Let's break down this process step by step:
Generate a key pair
Before signing any transaction, you need to generate a cryptographic key pair consisting of a public and private key. We
add the following to our book_review.ts
file. Add the private key for our admin book keeper found in chromia.yaml.
const privKey = Buffer.from("<private key>", "hex");
const bookKeeperKeyPair = encryption.makeKeyPair(privKey);
The makeKeyPair
function from the encryption
module generates a key pair using the provided private key (privKey
).
The resulting bookKeeperKeyPair
contains both the private key (used for signing) and the associated public key (used
for verification).
Secure storage and retrieval of keys
When working with cryptographic keys, it's crucial to store them securely to prevent unauthorized access. To learn about best practices for securely generating, storing, and managing your keys, please refer to the Chromia documentation on key generation. This documentation provides guidance on file placement and other important security practices.
In this code example, privKey
is assigned directly for the sake of simplicity. It is critically important to manage
private keys securely in a production environment. Never store private keys in plain text or expose them in client-side
code, as it poses a significant security risk.
Set up the signature provider
Once you have your key pair, you need a mechanism to use it for signing transactions, so let's create the
SignatureProvider and add it to book_review.ts
.
const bookKeeperSignatureProvider = newSignatureProvider(bookKeeperKeyPair);
The newSignatureProvider
function creates a signature provider using the provided key pair (bookKeeperKeyPair
). This
signature provider is responsible for signing any transaction before it's sent to the blockchain.
Using the signAndSendUniqueTransaction
method
So we can now add our first transaction to the main function in book_review.ts
:
console.log("Creating a new book transactions");
await client.signAndSendUniqueTransaction(
{ name: "create_book", args: ["ISBN1", "Chromia 101", "John Doe"] },
bookKeeperSignatureProvider
);
The signAndSendUniqueTransaction
method from the postchain-client
library combines two primary tasks:
-
Signing: Before a transaction is dispatched to the blockchain, it's signed using the provided signature provider. When verified by the blockchain network, this signature proves that the transaction hasn't been tampered with after being signed and confirms the sender's identity.
-
Sending: Once the transaction is signed, it's dispatched to the Chromia blockchain for processing.
Parameters explained:
This method takes two arguments:
-
Transaction object:
-
name
: Represents the operation you intend to run on the blockchain. For example, "create_book" corresponds to a Rell function that creates a new book entity on the blockchain. -
args
: An array containing the arguments for the operation.
-
-
Signature provider: This will sign the transaction using the previously discussed key pair. In the code snippet provided, the
bookKeeperSignatureProvider
is being used.
How it fits in the overall flow:
When you invoke signAndSendUniqueTransaction
, you're essentially instructing the client to:
-
Create a transaction to call the
create_book
function on the blockchain with the provided arguments. -
Sign this transaction using the
bookKeeperSignatureProvider
. -
Send the now-signed transaction to the Chromia blockchain.
Test run our code
Lastly, at the end of our file, we add a function call to run the `main ' function like this.
main();
Now, we can test running our first example.
npx tsc book_review.ts
node book_review.js
Next, we will look at adding a query to fetch books and reviews.