DEV Community

Cover image for How I Built a Trade Finance App on Hyperledger Fabric – A Complete Blockchain Project Walkthrough
Parshuram Singh
Parshuram Singh

Posted on • Edited on

How I Built a Trade Finance App on Hyperledger Fabric – A Complete Blockchain Project Walkthrough

Hey Dev.to community! I’m Parshuram Singh, a Frontend and Blockchain Developer, and I’m excited to walk you through my journey of building a Blockchain-Powered Trade Finance App using Hyperledger Fabric, Node.js, and React. This project automates a seven-step trade finance process creation, approvals, shipping, receipt, and payment leveraging blockchain for transparency and efficiency. Whether you’re new to blockchain or a seasoned dev, this blog will guide you from setup to a working app.

The Idea: Why Blockchain for Trade Finance?

Trade finance involves a complex workflow with applicants, banks, and beneficiaries coordinating shipments and payments. Traditional systems rely on paper-based processes and intermediaries, leading to delays and errors. Blockchain’s immutability and smart contracts offer a decentralized solution, ensuring a tamper-proof ledger accessible only to trusted parties.

My goal was to create an app where:

  • An Applicant initiates a trade request.
  • Banks (Issuing and Beneficiary) approve it.
  • The Beneficiary ships goods with evidence.
  • The Applicant confirms receipt.
  • Payments are finalized all tracked on a blockchain.

I chose Hyperledger Fabric for its permissioned network, Node.js for the backend, and React for the UI. Let’s build it step-by-step!

Step 1: Network Setup

I built a full Hyperledger Fabric network from scratch using a custom script:

Docker Containers: Spun up peers, orderers, and certificate authorities (CAs) with:

./network.sh up createChannel -c mychannel -ca
Enter fullscreen mode Exit fullscreen mode
  • Crypto Material: Generated MSP and TLS certificates automatically via the script.
  • Configuration Files: Crafted a custom connection.json for the SDK to interact with the network.
  • Private Channel: Configured a private channel (mychannel) to isolate data access between trusted parties (banks, applicants, beneficiaries).

Private channels enforce secure, selective data sharing, critical for enterprise use cases.

This setup ran on my Ryzen 5 machine with 16 GB RAM and Ubuntu 22.04, providing a robust foundation.

Step 2: Writing & Deploying Chaincode

The smart contract (TradeFinance.js), written in JavaScript with the fabric-contract-api, automates the trade finance logic.

Code Highlights

const { Contract } = require('fabric-contract-api');

class TradeFinanceContract extends Contract {
    async initLedger(ctx) {
        console.info('Initializing Ledger: TradeFinanceContract');
        const participants = [
            { id: 'b1', name: 'Bank b1', type: 'Bank' },
            { id: 'b2', name: 'Bank b2', type: 'Bank' },
            { id: 'app', name: 'Applicant app', type: 'User' },
            { id: 'ben', name: 'Beneficiary ben', type: 'User' }
        ];
        for (const participant of participants) {
            await ctx.stub.putState(participant.id, Buffer.from(JSON.stringify(participant)));
        }
    }

    async createApplication(ctx, applicationID, productDetails, applicantRules) {
        const application = {
            ID: applicationID,
            applicant: 'app',
            beneficiary: 'ben',
            issuingBank: 'b1',
            exportingBank: 'b2',
            productDetails,
            rules: applicantRules,
            evidence: null,
            approvingEntities: [],
            status: 'PENDING_ISSUING_BANK',
            statusHistory: [{ status: 'PENDING_ISSUING_BANK', timestamp: ctx.stub.getTxTimestamp() }]
        };
        await ctx.stub.putState(applicationID, Buffer.from(JSON.stringify(application)));
        return JSON.stringify(application);
    }

    // Additional methods: approveByIssuingBank, approveByBeneficiaryBank, etc.
}

module.exports = TradeFinanceContract;
Enter fullscreen mode Exit fullscreen mode

Deployment

./network.sh deployCC -ccn tradeFinance -ccp ../asset-transfer-basic/my-chaincode/ -ccl javascript
Enter fullscreen mode Exit fullscreen mode

Verify Deployment

peer lifecycle chaincode querycommitted --channelID mychannel --name tradeFinance
Enter fullscreen mode Exit fullscreen mode

Test an Invocation

peer chaincode invoke -C mychannel -n tradeFinance -c '{"function":"createApplication","Args":["T001","Laptops","COD"]}'
Enter fullscreen mode Exit fullscreen mode

Step 3: App SDK + CLI Interactions

I built a Node.js SDK app (myapp.js) to enable communication with the blockchain.

Key Features

  • User Management: Registers and enrolls users via the wallet.
  • Transactions: Submits and evaluates transactions.
  • Queries: Fetches trade status by ID.
const { Gateway, Wallets } = require("fabric-network");
const express = require("express");
const cors = require("cors");
const app = express();
app.use(express.json());
app.use(cors());

const PORT = 3000;

async function connectToNetwork() {
    const wallet = await Wallets.newFileSystemWallet("wallet");
    const gateway = new Gateway();
    await gateway.connect(JSON.parse(fs.readFileSync("connection.json")), { wallet, identity: "appUser" });
    const network = await gateway.getNetwork("mychannel");
    return network.getContract("tradeFinance");
}

app.post("/create-application", async (req, res) => {
    const { id, productDetails, rules } = req.body;
    const contract = await connectToNetwork();
    const result = await contract.submitTransaction("createApplication", id, productDetails, rules);
    res.json(JSON.parse(result.toString()));
});
Enter fullscreen mode Exit fullscreen mode

CLI Tool:

node myapp.js createApplication T001 "Laptops" "COD"
Enter fullscreen mode Exit fullscreen mode

Step 4: Debugging Like a Pro

Debugging a Fabric network was a learning curve! Here’s how I tackled issues:

  • Docker Logs: docker logs <container_id> to troubleshoot peers and orderers
  • Debug Mode: Ran chaincode in debug mode inside containers
  • Common Fixes: Resolved identity mismatches, endorsement policy failures, and config issues

Debugging Fabric reveals its internals orderers sequencing transactions, peers validating them—making it a deep dive into its architecture!

Step 5: Performance Benchmarking with Caliper

I used Hyperledger Caliper to test the smart contract under load.

Setup

cd asset-transfer-basic/my-application
npx caliper launch manager --caliper-workspace . --caliper-benchconfig benchmarks/trade-finance-benchmark.yaml --caliper-networkconfig networks/trade-finance-network.yaml --caliper-fabric-gateway-enable
Enter fullscreen mode Exit fullscreen mode

Simulated 32000+ transactions

Results

  • Latency: Measured average transaction time
  • Throughput: Achieved up to 6000 TPS on my setup
  • Success Rate: Optimized logic to reduce failures

This identified bottlenecks (e.g., endorsement delays) and guided optimizations.

Key Concepts I Learned

  • Fabric Internals: Orderers sequence, peers validate, channels isolate
  • Identity Management: MSPs, TLS, and CAs secure the network
  • Chaincode Lifecycle: Install, approve, commit process
  • Business Logic: Secure state transitions and audits
  • Docker Debugging: Microservice troubleshooting
  • Benchmarking: Caliper for performance tuning

GitHub Repository

👉 View the full project on GitHub

Final Words

This project immersed me in enterprise blockchain development, from spinning up a Fabric network to benchmarking with Caliper. It’s been a wild ride debugging Docker containers, and optimizing performance all while mastering Fabric’s depths. If you’re exploring Hyperledger Fabric, fork my repo, experiment, and share your insights!

Let’s Connect!

Follow me for more real-world Blockchain + Frontend dev content!

Thanks for reading!
Parshuram Singh
Frontend + Blockchain Developer | Hyperledger | React | Smart Contracts | Java

Top comments (0)