Fabric应用开发基础

应用程序可以通过将交易提交到帐本或查询帐本内容来与区块链网络进行交互。

需要注意的是:Fabric的应用是类似客户端的存在,而更核心的是智能合约的开发。

目录

基本流程

应用程序必须遵循六个基本步骤来提交交易:

  • 从钱包中选择一个身份
  • 连接到网关
  • 访问所需的网络
  • 构建智能合约的交易请求
  • 将交易提交到网络
  • 处理响应

例如:issue.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
'use strict';

// Bring key classes into scope, most importantly Fabric SDK network class
const fs = require('fs');
const yaml = require('js-yaml');
const { Wallets, Gateway } = require('fabric-network');
const CommercialPaper = require('../contract/lib/paper.js');

// Main program function
async function main() {

// A wallet stores a collection of identities for use
const wallet = await Wallets.newFileSystemWallet('../identity/user/isabella/wallet');

// A gateway defines the peers used to access Fabric networks
const gateway = new Gateway();

// Main try/catch block
try {

// Specify userName for network access
// const userName = 'isabella.issuer@magnetocorp.com';
const userName = 'isabella';

// Load connection profile; will be used to locate a gateway
let connectionProfile = yaml.safeLoad(fs.readFileSync('../gateway/connection-org2.yaml', 'utf8'));

// Set connection options; identity and wallet
let connectionOptions = {
identity: userName,
wallet: wallet,
discovery: { enabled:true, asLocalhost: true }
};

// Connect to gateway using application specified parameters
console.log('Connect to Fabric gateway.');

await gateway.connect(connectionProfile, connectionOptions);

// Access PaperNet network
console.log('Use network channel: mychannel.');

const network = await gateway.getNetwork('mychannel');

// Get addressability to commercial paper contract
console.log('Use org.papernet.commercialpaper smart contract.');

const contract = await network.getContract('papercontract');

// issue commercial paper
console.log('Submit commercial paper issue transaction.');

const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');

// process response
console.log('Process issue transaction response.'+issueResponse);

let paper = CommercialPaper.fromBuffer(issueResponse);

console.log(`${paper.issuer} commercial paper : ${paper.paperNumber} successfully issued for value ${paper.faceValue}`);
console.log('Transaction complete.');

} catch (error) {

console.log(`Error processing transaction. ${error}`);
console.log(error.stack);

} finally {

// Disconnect from the gateway
console.log('Disconnect from Fabric gateway.');
gateway.disconnect();

}
}
main().then(() => {

console.log('Issue program complete.');

}).catch((e) => {

console.log('Issue program exception.');
console.log(e);
console.log(e.stack);
process.exit(-1);

});

名词解释

  • 钱包Wallet

    钱包拥有一组身份——X.509 数字证书——可用于访问 PaperNet Channel或任何其他 Fabric 网络。钱包中的 X.509 数字证书将持有者与组织相关联,从而使他们有权在Channel中获得权利。另请注意,钱包不持有任何形式的现金或代币——它们持有身份。

  • 网关Gateway

    网关识别一个或多个提供网络访问的 Peer 节点——在我们的例子中是 PaperNet。

    gateway.connect() 有两个重要参数:

    • connectionProfile连接配置文件的文件系统位置,用于将一组 Peer 节点标识为 PaperNet 的网关
    • connectionOptions:一组用于控制 issue.js 与 PaperNet 交互的选项

    其中connection-org2.yaml的部分配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    channels:
    papernet:
    peers:
    peer1.magnetocorp.com:
    endorsingPeer: true
    eventSource: true

    peer2.digibank.com:
    endorsingPeer: true
    eventSource: true

    peers:
    peer1.magnetocorp.com:
    url: grpcs://localhost:7051
    grpcOptions:
    ssl-target-name-override: peer1.magnetocorp.com
    request-timeout: 120
    tlsCACerts:
    path: certificates/magnetocorp/magnetocorp.com-cert.pem

    peer2.digibank.com:
    url: grpcs://localhost:8051
    grpcOptions:
    ssl-target-name-override: peer1.digibank.com
    tlsCACerts:
    path: certificates/digibank/digibank.com-cert.pem

    MagnetoCorp 拥有 peer1.magenetocorp.com,DigiBank 拥有 peer2.digibank.com,两者都有背书节点的角色。通过 peers: 键链接到这些 Peer 节点,其中包含有关如何连接它们的详细信息,包括它们各自的网络地址。

  • Channel

    1
    const network = await gateway.getNetwork('PaperNet');

    Fabric SDK提供选择特定的Channel以保证应用程序在不同的网络中获取不同的权限。

  • 获取Channel中已经部署的智能合约链码

    1
    const contract = await network.getContract('papercontract');
  • 提交交易

    交易原型为:

    1
    2
    3
    4
    5
    6
    Txn = issue
    Issuer = MagnetoCorp
    Paper = 00001
    Issue time = 31 May 2020 09:00:00 EST
    Maturity date = 30 November 2020
    Face value = 5M USD
    1
    const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');

    submitTransaction() 参数的值将传递给智能合约中的 issue() 方法,并用于创建新的商业票据。后续在P2P网络的广播,背书,验证等流程不需要我们操作。

  • 处理响应

    获取转码,并获取响应信息。

    1
    2
    let paper = CommercialPaper.fromBuffer(issueResponse);
    console.log(`${paper.issuer} commercial paper : ${paper.paperNumber} successfully issued for value ${paper.faceValue}`);

总结:

应用程序只负责用户到区块链网络的过程(UI),其中SDK封装了对身份调用、网络连接、交易…对智能合约的调用和部分对区块链状态信息的查看。开发者可以与智能合约一起设计,共同实现一个完整的功能。

参考:

Fabric官方文档2.2.0