Skip to main content

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 as http://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.

Warning: Security Risk

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:

  1. 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.

  2. 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.