寻求Hyperledger Fabric 2.2与React.js前端通过Node.js API连接的示例
Hey there! I totally get the frustration—most examples out there are stuck on 1.4, but Fabric 2.2 introduced some key changes (like the new Gateway API) that make this workflow cleaner. Let me walk you through a tailored setup that works for your stack:
1. Core Adaptations for Fabric 2.2 Node.js SDK v2.x
First, forget the old fabric-client package used in 1.4—Fabric 2.2 relies on the fabric-network package, which centers on the Gateway API. This simplifies connection management by replacing the clunky Client/Channel object chain with a single gateway instance.
2. Node.js Backend (API Layer) Example
This uses Express to expose Fabric network interactions as REST endpoints, which your React frontend can call.
Step 1: Install Dependencies
npm install fabric-network express cors
Step 2: Sample Backend Code
const express = require('express'); const cors = require('cors'); const { Gateway, Wallets } = require('fabric-network'); const path = require('path'); const app = express(); app.use(cors()); app.use(express.json()); // Helper function to connect to the Fabric network async function getFabricContract() { // Load file system wallet (adjust path to your wallet location) const walletPath = path.join(__dirname, './wallet'); const wallet = await Wallets.newFileSystemWallet(walletPath); // Initialize gateway with connection profile & identity const gateway = new Gateway(); const connectionProfile = path.join(__dirname, './connection-org1.json'); // Your org's connection config const connectionOpts = { wallet, identity: 'org1-user', // Identity stored in your wallet discovery: { enabled: true, asLocalhost: true } // Service discovery is default in 2.2 }; await gateway.connect(connectionProfile, connectionOpts); const network = await gateway.getNetwork('my-channel'); // Your channel name const contract = network.getContract('my-chaincode'); // Your chaincode name return { contract, gateway }; } // Endpoint to query chaincode (read-only) app.get('/api/assets', async (req, res) => { try { const { contract, gateway } = await getFabricContract(); const queryResult = await contract.evaluateTransaction('getAllAssets'); // Your chaincode query method res.json(JSON.parse(queryResult.toString())); gateway.disconnect(); } catch (err) { res.status(500).json({ error: err.message }); } }); // Endpoint to submit chaincode transaction (write operation) app.post('/api/assets', async (req, res) => { try { const { contract, gateway } = await getFabricContract(); const { assetId, owner, value } = req.body; await contract.submitTransaction('createAsset', assetId, owner, value); // Your chaincode write method res.json({ status: 'success', message: 'Asset created' }); gateway.disconnect(); } catch (err) { res.status(500).json({ error: err.message }); } }); const PORT = process.env.PORT || 5000; app.listen(PORT, () => console.log(`Backend running on port ${PORT}`));
3. React.js Frontend Integration Example
Use Axios to call the backend endpoints and interact with the Fabric network.
Step 1: Install Axios
npm install axios
Step 2: Sample React Component
import React, { useState, useEffect } from 'react'; import axios from 'axios'; function FabricAssetManager() { const [assets, setAssets] = useState([]); const [assetId, setAssetId] = useState(''); const [owner, setOwner] = useState(''); const [value, setValue] = useState(''); // Fetch assets on component mount useEffect(() => { fetchAssets(); }, []); const fetchAssets = async () => { try { const response = await axios.get('http://localhost:5000/api/assets'); setAssets(response.data); } catch (err) { alert(`Failed to load assets: ${err.message}`); } }; const handleCreateAsset = async (e) => { e.preventDefault(); try { await axios.post('http://localhost:5000/api/assets', { assetId, owner, value }); alert('Asset created successfully!'); fetchAssets(); // Refresh asset list // Reset form fields setAssetId(''); setOwner(''); setValue(''); } catch (err) { alert(`Failed to create asset: ${err.message}`); } }; return ( <div className="asset-manager"> <h2>Fabric 2.2 Asset Manager</h2> <form onSubmit={handleCreateAsset} className="asset-form"> <input type="text" placeholder="Asset ID" value={assetId} onChange={(e) => setAssetId(e.target.value)} required /> <input type="text" placeholder="Owner Name" value={owner} onChange={(e) => setOwner(e.target.value)} required /> <input type="text" placeholder="Asset Value" value={value} onChange={(e) => setValue(e.target.value)} required /> <button type="submit">Create Asset</button> </form> <h3>Existing Assets</h3> <ul className="asset-list"> {assets.map(asset => ( <li key={asset.ID}> <strong>{asset.ID}</strong> | Owner: {asset.Owner} | Value: {asset.Value} </li> ))} </ul> </div> ); } export default FabricAssetManager;
4. Critical Notes for Fabric 2.2
- Connection Profile: Ensure your
connection-org1.jsonuses Fabric 2.2 format, including service discovery endpoints for peers and orderers. - Wallet Setup: Use
Wallets.newFileSystemWallet(not the deprecated 1.4FileSystemWallet) and make sure your user identity is enrolled and stored in the wallet (usefabric-ca-clientfor enrollment). - CORS Configuration: Enable CORS in your backend for development; restrict to specific domains in production.
- Chaincode Compatibility: While 1.4 chaincodes can run on 2.2, it’s better to use Fabric 2.x chaincode SDKs for full feature support.
内容的提问来源于stack exchange,提问作者Shahzaib Ayyub

