天天看點

使用NodeJS開發Hyperledger Fabric筆記3——合約互動

Fabric網絡搭建好,合約部署好,接下來就是和合約互動。

我們上一章節中部署了官方給的fabcar合約項目,這裡我們還是以這套合約為例做簡單的互動介紹。

首先,fabcar的chaincode位址:https://github.com/hyperledger/fabric-samples/tree/main/chaincode/fabcar/javascript

部署的方法上一章節介紹過,使用

deployCC

即可。

這裡我們假設已經部署好了fabcar的合約。

接下來我們直接開始對合約進行操作,也就是調用合約裡面的方法。

建立項目

首先我們使用npm建立一個node項目,

npm init

,在

package.json

加入3個包:

{
  "name": "fabcar",
  "version": "1.0.0",
  "description": "FabCar application implemented in JavaScript",
  "engineStrict": true,
  "author": "Hyperledger",
  "license": "Apache-2.0",
  "dependencies": {
    "app-root-path": "^3.0.0",
    "fabric-ca-client": "^2.2.4",
    "fabric-network": "^2.2.4"
  }
}
           

說明下,

fabric-network

用于合約互動,裡面有很重要的

contract

對象可以操作合約。

fabric-ca-client

用于fabric網絡層面的一些互動,可以注冊使用者等。

注冊Admin使用者

const FabricCAServices = require('fabric-ca-client');
const { Wallets } = require('fabric-network');
const ROOT = require('app-root-path');
const ccp = require(`${ROOT}/organizations/peerOrganizations/org1.example.com/connection-org1.json`);
const walletPath = `${ROOT}/wallet`;

async function main() {
    try {
        // Create a new CA client for interacting with the CA.
        const caInfo = ccp.certificateAuthorities['ca.org1.example.com'];
        const caTLSCACerts = caInfo.tlsCACerts.pem;
        const ca = new FabricCAServices(
            caInfo.url,
            { trustedRoots: caTLSCACerts, verify: false },
            caInfo.caName
        );
        // Create a new file system based wallet for managing identities.
        const wallet = await Wallets.newFileSystemWallet(walletPath);
        // Enroll the admin user, and import the new identity into the wallet.
        const enrollment = await ca.enroll({
            enrollmentID: 'admin',
            enrollmentSecret: 'adminpw',
        });
        const x509Identity = {
            credentials: {
                certificate: enrollment.certificate,
                privateKey: enrollment.key.toBytes(),
            },
            mspId: 'Org1MSP',
            type: 'X.509',
        };
        await wallet.put('admin', x509Identity);
        console.log('Successfully enrolled admin user');
    } catch (e) {
        console.error(e);
    }
}

main();
           

這裡我們注意到,需要引用一些外部檔案,首先項目目錄下建立一個

wallet

目錄,存儲使用者錢包,也就是私鑰,用于之後互動時的簽名權。另外一個就是引入連接配接節點的配置檔案,這個檔案在organization下,我們必須要把第一章中用

cryptogen

生成的那個organization目錄全部複制過來,注意是全部,否則會報錯,可能是有什麼關聯引用吧。

注冊普通使用者

上面已經注冊了admin使用者,是以可以用admin使用者再注冊普通使用者了,如下:

const { Wallets } = require('fabric-network');
const FabricCAServices = require('fabric-ca-client');
const ROOT = require('app-root-path');
const ccp = require(`${ROOT}/organizations/peerOrganizations/org1.example.com/connection-org1.json`);
const walletPath = `${ROOT}/wallet`;

async function main() {
    try {
        // Create a new CA client for interacting with the CA.
        const caURL = ccp.certificateAuthorities['ca.org1.example.com'].url;
        const ca = new FabricCAServices(caURL);
        const wallet = await Wallets.newFileSystemWallet(walletPath);
        const adminIdentity = await wallet.get('admin');
        const provider = wallet
            .getProviderRegistry()
            .getProvider(adminIdentity.type);
        const adminUser = await provider.getUserContext(adminIdentity, 'admin');

        // Register the user, enroll the user, and import the new identity into the wallet.
        const secret = await ca.register(
            {
                affiliation: 'org1.department1',
                enrollmentID: 'appUser',
                role: 'client',
            },
            adminUser
        );
        const enrollment = await ca.enroll({
            enrollmentID: 'appUser',
            enrollmentSecret: secret,
        });
        const x509Identity = {
            credentials: {
                certificate: enrollment.certificate,
                privateKey: enrollment.key.toBytes(),
            },
            mspId: 'Org1MSP',
            type: 'X.509',
        };
        await wallet.put('appUser', x509Identity);
        console.log('Successfully registeredd');
    } catch (error) {
        console.error(error);
    }
}

main();
           

合約讀寫

const { Gateway, Wallets } = require('fabric-network');
const ROOT = require('app-root-path');
const walletPath = `${ROOT}/wallet`;
const ccp = require(`${ROOT}/organizations/peerOrganizations/org1.example.com/connection-org1.json`);
let conf = null;
let contract = null;

async function query() {
    const res = await contract.evaluateTransaction('queryCar', 'CAR1');
    console.log(JSON.parse(res.toString()));
}

async function change(name) {
    await contract.submitTransaction('changeCarOwner', 'CAR1', name);
}
async function main() {
    try {
        // load the network configuration
        const wallet = await Wallets.newFileSystemWallet(walletPath);
        conf = {
            wallet,
            identity: 'appUser',
            discovery: { enabled: true, asLocalhost: true },
        };
        const gateway = new Gateway();
        await gateway.connect(ccp, conf);
        const network = await gateway.getNetwork('mychannel');
        contract = network.getContract('fabcar');
        await query();
        await change('devil');
        await query();
        await gateway.disconnect();
    } catch (error) {
        console.error(error);
    }
}

main();
           

對應輸出結果:

使用NodeJS開發Hyperledger Fabric筆記3——合約互動

繼續閱讀