如何创建 Hyperledger Fabric 通道(频道)

本教程演示如何使用node.js fabric client sdk创建Hyperledger fabric 通道,也有的人叫频道。它演示了如何使用初始化(默认)通道定义以及如何从该定义开始构建自定义的通道定义。创建网络和通道的过程还涉及创建和使用加密资料,这里不讨论这一点。

有关以下内容的详细信息:

以下假设了解了HyperledgeFabric网络(orderers and peers)、Protobuf以及节点应用程序开发,包括使用JavaScript Promise

下面显示的示例基于Balance Transfer示例应用程序。参见Hyperledger fabric 示例

通道创建步骤

  • 运行configtxgen工具生成genesis块。
  • 运行configtxgen工具初始化二进制配置定义。
  • 通过以下两种方法之一获取可签名通道定义。
    • 初始化二进制通道配置定义
      • 使用Fabric客户端SDK从二进制通道配置定义中提取可签名通道定义。
    • 生成自定义通道定义
      • 使用configtxlator将二进制通道配置定义转换为可读文本。
      • 编辑可读文本更多信息。
      • 使用configtxlator将编辑的文本转换为可签名的通道定义。
  • 使用Fabric客户端SDK对可签名的通道定义进行签名。
  • 使用Fabric客户端SDK将签名和可签名通道定义发送给orderers。
  • 使用Fabric客户端SDK让peers加入通道。
  • 然后可以使用新的通道。

使用初始定义构建可签名的通道定义

configtxgen工具生成的二进制通道配置定义是一个包含hyperledger fabric 配置protobuf common.envelope元素的二进制文件。在这个元素中是common.configupdate protobuf元素。这个配置元素是必须签名的元素。configtx.yaml中的profile元素是configtxgen工具创建的二进制通道配置定义的源。

1
../../../bin/configtxgen -channelID mychannel -outputCreateChannelTx mychannel.tx -profile TwoOrgsChannel

让fabric client sdk从mychannel.tx文件中提取config update元素:

1
2
3
4
// first read in the file, this gives us a binary config envelope
let envelope_bytes = fs.readFileSync(path.join(__dirname, 'fabric-samples/balance-transfer/artifacts/channel/mychannel.tx'));
// have the nodeSDK extract out the config update
var config_update = client.extractChannelConfig(envelope_bytes);

二进制配置更新现在可以在签名过程中使用,并发送给orderer以创建通道。

你可能会问为什么创建时使用common.configupdate。这样创建和更新的过程就是相同的。新通道的创建是系统通道中定义的增量,而更新也是通道中定义的增量。提交的common.configupdate对象将只包含创建和更新中的更改。

创建自定义可签名通道定义

开始创建自定义通道配置的最简单方法是让configtxlator将已经或可能用于创建新通道的现有可读JSON的二进制文件进行转换。配置有许多元素,从零开始太难。使用用于生成hyperledger fabric 网络的相同configtx.yaml文件,使用configtxgen工具为新通道创建初始二进制配置定义。然后,通过将该二进制文件发送给configtxlator将其转换为JSON,你将能够看到布局并有一个好的开始。该JSON还可以用作在网络上创建其他新频道的模板。对于新通道配置中未定义的设置,新通道将从系统通道继承设置。新通道上的组织必须在系统渠道上的联合体中定义。因此,在创建新通道时,对网络的系统通道进行可读定义将很有帮助。将用于启动hyperledger fabric 网络的genesis.block发送到configtxlator,以获取用作参考的JSON文件。

使用configtxgen工具生成二进制配置文件。从示例目录fabric samples/balance transfer/artifacts/channel

1
2
3
export FABRIC_CFG_PATH=$PWD
../../../bin/configtxgen -outputBlock genesis.block -profile TwoOrgsOrdererGenesis
../../../bin/configtxgen -channelID mychannel -outputCreateChannelTx mychannel.tx -profile TwoOrgsChannel

将这两个二进制文件发送到configtxlator服务。由于此步骤只完成一次,不需要node.js应用程序,因此我们将使用curl来简化并加速获得结果。注意configtxlator服务路径已经解码(从binary转换为json)。路径还必须包含二进制对象的类型,在第一种情况下,它是common.block。可以对fabric client\lib\protos目录protobuf文件中的任何protobuf message对象类型执行decodeencode。首先从fabric samples/bin目录启动configtxlator服务:

1
./configtxlator start

然后:

1
2
curl -X POST --data-binary @genesis.block http://127.0.0.1:7059/protolator/decode/common.Block > genesis.json
curl -X POST --data-binary @mychannel.tx http://127.0.0.1:7059/protolator/decode/common.Envelope > mychannel.json

解码文件mychannel.tx的结果是,该文件是configtxgen工具生成的一个common.Envelope,其中包含一个common.configupdate对象。此对象在payload.data json对象中具有名称config_update。这是创建新通道所需的模板源对象。common.configupdate将由所有组织签名提交给orderer以创建新通道的对象。下面是生成的twoorgschannel通道create binary解码中提取的json config_updatecommon.configupdate)对象。

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
{
"channel_id": "mychannel",
"read_set": {
"groups": {
"Application": {
"groups": {
"Org1MSP": {}
}
}
},
"values": {
"Consortium": {
"value": {
"name": "SampleConsortium"
}
}
}
},
"write_set": {
"groups": {
"Application": {
"groups": {
"Org1MSP": {}
},
"mod_policy": "Admins",
"policies": {
"Admins": {
"policy": {
"type": 3,
"value": {
"rule": "MAJORITY",
"sub_policy": "Admins"
}
}
},
"Readers": {
"policy": {
"type": 3,
"value": {
"sub_policy": "Readers"
}
}
},
"Writers": {
"policy": {
"type": 3,
"value": {
"sub_policy": "Writers"
}
}
}
},
"version": "1"
}
},
"values": {
"Consortium": {
"value": {
"name": "SampleConsortium"
}
}
}
}
}

请注意,所使用的Consortium名称必须存在于系统通道上。你希望添加到新通道中的所有组织必须在Consortium部分中以系统通道上的名称进行定义。使用解码后的genesis块来验证所有值,例如通过查看上面生成的genesis.json文件。要将组织添加到通道,必须将其放置在Applications部分下的groups部分下,如上图所示。请参见Org1MSPapplications.groups部分的属性。在本例中,组织org1msp的所有设置都将从系统通道继承(请注意该组织属性的空对象 {})。要查看此组织的当前设置,请查看系统通道(系统通道的Genesis块)Consortium部分下的sampleconsortium部分。

一旦你有了一个代表你的通道的JSON配置,就将它发送给configtxlator,以便将其编码为配置二进制文件。以下向configtxlator发送REST请求的示例使用node.js包superagent,因为HTTP请求易于使用。

1
2
3
4
5
6
7
8
9
10
var response = superagent.post('http://127.0.0.1:7059/protolator/encode/common.ConfigUpdate',
config_json.toString())
.buffer()
.end((err, res) => {
if(err) {
logger.error(err);
return;
}
config_proto = res.body;
});

签署并提交通道更新

二进制配置必须由所有组织签名。应用程序必须存储二进制配置,并在收集签名时将其与存储所有签名一起进行签名。然后,一旦签名完成,应用程序将使用Fabric客户端sdk api createChannel()将二进制配置和所有签名发送给orderer。

首先是签名,假设client fabric-client SDK对象在所需组织中具有有效的用户:

1
2
var signature = client.signChannelConfig(config_proto);
signatures.push(signature);

现在是创建通道的时候了,假设signatures对象是由client.signChannelConfig()方法返回的common.configSignature数组。

注意:orderer必须从与初始二进制通道配置定义相同的配置文件生成的genesis.block

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// create an orderer object to represent the orderer of the network
var orderer = client.newOrderer(url,opts);

// have the SDK generate a transaction id
let tx_id = client.newTransactionID();

request = {
config: config_proto, //the binary config
signatures : signatures, // the collected signatures
name : 'mychannel', // the channel name
orderer : orderer, //the orderer from above
txId : tx_id //the generated transaction id
};

// this call will return a Promise
client.createChannel(request)

CreateChannel API返回一个 promise,以返回提交的状态。通道创建将由orderer异步进行。

经过几秒钟的小延迟后,orderer将创建通道,现在可以由peers加入。向通道上所需的peers发出以下内容。这是一个两步的过程,首先获取通道的Genesis块,然后将其发送给peers。在下面的示例中,Genesis块是从排序器中检索到的,但也可以从文件中加载。

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
// set the channel up with network endpoints
var orderer = client.newOrderer(orderer_url,orderer_opts);
channel.addOrderer(orderer);
var peer = client.newPeer(peer_url,peer_opts);
channel.addPeer(peer);

tx_id = client.newTransactionID();
let g_request = {
txId : tx_id
};

// get the genesis block from the orderer
channel.getGenesisBlock(g_request).then((block) =>{
genesis_block = block;
tx_id = client.newTransactionID();
let j_request = {
targets : targets,
block : genesis_block,
txId : tx_id
};

// send genesis block to the peer
return channel.joinChannel(j_request);
}).then((results) =>{
if(results && results.response && results.response.status == 200) {
// join successful
} else {
// not good
}
});

======================================================================

如果你想学习区块链并在Blockchain Technologies建立职业生涯,那么请查看我们分享的一些以太坊、比特币、EOS、Fabric等区块链相关的交互式在线编程实战教程:

  • java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
  • 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • ERC721以太坊通证实战,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
  • java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
  • php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
  • c#比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在C#代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是C#工程师不可多得的比特币开发学习课程。
  • EOS入门教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
  • 深入浅出玩转EOS钱包开发,本课程以手机EOS钱包的完整开发过程为主线,深入学习EOS区块链应用开发,课程内容即涵盖账户、计算资源、智能合约、动作与交易等EOS区块链的核心概念,同时也讲解如何使用eosjs和eosjs-ecc开发包访问EOS区块链,以及如何在React前端应用中集成对EOS区块链的支持。课程内容深入浅出,非常适合前端工程师深入学习EOS区块链应用开发。
  • Hyperledger Fabric 区块链开发详解,本课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、nodejs链码与应用开发的操作实践,是Nodejs工程师学习Fabric区块链开发的最佳选择。
  • Hyperledger Fabric java 区块链开发详解,课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、java链码与应用开发的操作实践,是java工程师学习Fabric区块链开发的最佳选择。
  • tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。

汇智网原创翻译,转载请标明出处。这里是如何创建 Hyperledger Fabric 通道(频道)