apache服务器配置tls_Hyperledger Fabric-多通道(Multi-Channel)网络配置的教程(下)...

本教程详细介绍了如何在Hyperledger Fabric网络中配置多通道,包括启动基础设施、配置通道、安装并实例化Simple Asset Chaincode(SACC)。在三个组织的环境中,分别创建并管理了两个通道ChannelAll和Channel12,展示了每个通道独立的分类帐和状态隔离特性。
摘要由CSDN通过智能技术生成

第4步:启动基础架构(容器)

我们使用docker-compose来配置我们的超级分层结构网络,配置文件为docker-compose.yaml。

$ docker-compose -f docker-compose.yaml up -d

41bb2d489635e43ce19fe5c14c56268b.png

执行命令后,我们可以检查正在运行的容器,这些容器应该与我们的网络设置相对应。 将有五个运行容器

  1. 一个订货人
  2. 三个对等体,对应每一个组织
  3. 一个CLI

请注意,CLI将用于启动命令。

$ docker ps

58be31635d21ecd6ba039b4862622d78.png

步骤5:在基础架构上配置通道

现在我们有容器在运行。 我们开始在对等体上配置通道。

所有命令都是从带有docker exec的CLI容器发出的。 CLI容器在peer0.org1上具有默认设置。 为方便访问,我们将启动三个新终端(或将终端分成三个,如下所示),每个终端用于组织的同行。 我们的命令稍后将在终端上发布。

在步骤3.1(在crypto-config目录中)创建的那些文件被复制到相应的容器中。

在步骤3.2中创建的那些文件(在channel-artifacts目录中)被复制到容器,它们用于配置通道。

准备多个终端

我们为Org1,Org2和Org3指定了三个新终端。

对于Org1(默认)

$ docker exec -it cli bash

对于Org2(指定Org2的环境变量)

$ docker exec -e “CORE_PEER_LOCALMSPID=Org2MSP” -e “CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt” -e “CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp” -e “CORE_PEER_ADDRESS=peer0.org2.example.com:7051” -it cli bash

对于Org3(指定Org3的环境变量)

$ docker exec -e “CORE_PEER_LOCALMSPID=Org3MSP” -e “CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt” -e “CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp” -e “CORE_PEER_ADDRESS=peer0.org3.example.com:7051” -it cli bash

为便于访问,请在所有三个终端中导出此参数ORDERER_CA。

# export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

以下是Org1,Org2和Org3的三个终端,从上到下。

c470539bdcf387a12e5ec28e2235f3f3.png

配置通道的流程

29170b38d888091011256c7b2f2eabd1.png

步骤5.1 ChannelAll

创建通道块文件(任何终端)

# peer channel create -o orderer.example.com:7050 -c channelall -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/channelall.tx — tls — cafile $ORDERER_CA

现在创建了一个文件channelall.block。

将三个对等点加入此通道并更新每个对等方的锚点对等方。

Org1终端

# peer channel join -b channelall.block — tls — cafile $ORDERER_CA
# peer channel update -o orderer.example.com:7050 -c channelall -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/Org1MSPanchors_channelall.tx — tls — cafile $ORDERER_CA

Org2终端

# peer channel join -b channelall.block — tls — cafile $ORDERER_CA
# peer channel update -o orderer.example.com:7050 -c channelall -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/Org2MSPanchors_channelall.tx — tls — cafile $ORDERER_CA

Org3终端

# peer channel join -b channelall.block — tls — cafile $ORDERER_CA
# peer channel update -o orderer.example.com:7050 -c channelall -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/Org3MSPanchors_channelall.tx — tls — cafile $ORDERER_CA

步骤5.2:Channel12

创建通道块文件(任何终端)

# peer channel create -o orderer.example.com:7050 -c channel12 -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/channel12.tx — tls — cafile $ORDERER_CA

现在创建了一个文件channel12.block。

将两个对等方加入此通道并更新每个对等方的锚点对等方。

Org1终端

# peer channel join -b channel12.block — tls — cafile $ORDERER_CA
# peer channel update -o orderer.example.com:7050 -c channel12 -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/Org1MSPanchors_channel12.tx — tls — cafile $ORDERER_CA

Org2终端

# peer channel join -b channel12.block — tls — cafile $ORDERER_CA
# peer channel update -o orderer.example.com:7050 -c channel12 -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/Org2MSPanchors_channel12.tx — tls — cafile $ORDERER_CA

第6步:安装Simple Asset Chaincode(SACC)

现在我们的网络已经启动并运行,可以部署链代码。

我们正在使用fabric-samples中的SACC。 这是链码:

/*
 * Copyright IBM Corp All Rights Reserved
 *
 * SPDX-License-Identifier: Apache-2.0
 */

package main

import (
    "fmt"

    "github.com/hyperledger/fabric/core/chaincode/shim"
    "github.com/hyperledger/fabric/protos/peer"
)

// SimpleAsset implements a simple chaincode to manage an asset
type SimpleAsset struct {
}

// Init is called during chaincode instantiation to initialize any
// data. Note that chaincode upgrade also calls this function to reset
// or to migrate data.
func (t *SimpleAsset) Init(stub shim.ChaincodeStubInterface) peer.Response {
    // Get the args from the transaction proposal
    args := stub.GetStringArgs()
    if len(args) != 2 {
        return shim.Error("Incorrect arguments. Expecting a key and a value")
    }

    // Set up any variables or assets here by calling stub.PutState()

    // We store the key and the value on the ledger
    err := stub.PutState(args[0], []byte(args[1]))
    if err != nil {
        return shim.Error(fmt.Sprintf("Failed to create asset: %s", args[0]))
    }
    return shim.Success(nil)
}

// Invoke is called per transaction on the chaincode. Each transaction is
// either a 'get' or a 'set' on the asset created by Init function. The Set
// method may create a new asset by specifying a new key-value pair.
func (t *SimpleAsset) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
    // Extract the function and args from the transaction proposal
    fn, args := stub.GetFunctionAndParameters()

    var result string
    var err error
    if fn == "set" {
        result, err = set(stub, args)
    } else { // assume 'get' even if fn is nil
        result, err = get(stub, args)
    }
    if err != nil {
        return shim.Error(err.Error())
    }

    // Return the result as success payload
    return shim.Success([]byte(result))
}

// Set stores the asset (both key and value) on the ledger. If the key exists,
// it will override the value with the new one
func set(stub shim.ChaincodeStubInterface, args []string) (string, error) {
    if len(args) != 2 {
        return "", fmt.Errorf("Incorrect arguments. Expecting a key and a value")
    }

    err := stub.PutState(args[0], []byte(args[1]))
    if err != nil {
        return "", fmt.Errorf("Failed to set asset: %s", args[0])
    }
    return args[1], nil
}

// Get returns the value of the specified asset key
func get(stub shim.ChaincodeStubInterface, args []string) (string, error) {
    if len(args) != 1 {
        return "", fmt.Errorf("Incorrect arguments. Expecting a key")
    }

    value, err := stub.GetState(args[0])
    if err != nil {
        return "", fmt.Errorf("Failed to get asset: %s with error: %s", args[0], err)
    }
    if value == nil {
        return "", fmt.Errorf("Asset not found: %s", args[0])
    }
    return string(value), nil
}

// main function starts up the chaincode in the container during instantiate
func main() {
    if err := shim.Start(new(SimpleAsset)); err != nil {
        fmt.Printf("Error starting SimpleAsset chaincode: %s", err)
    }
}

这个链码的逻辑很简单。

  1. 实例化chaincode时,执行Init()。预期有两个参数,它们对应于“键”和“值”。
  2. 此键/值对存储在分类帐中(使用PutState)。
  3. 实例化后,事务由Invoke()处理。该参数由函数(或命令)和参数组成。
  4. 如果function = set,则需要两个参数。它是一个全新的键/值,或者如果键存在则覆盖该值。调用函数set(),结果存储在分类帐中(使用PutState)
  5. 如果function = anything(例如get),则预期一个参数为key。函数get()被调用。 GetState用于从分类帐中获取状态。如果key存在,则返回该值。否则显示“未找到资产”。
  6. 通过安装链代码,它将链代码加载到每个对等方。请注意,在实例化链代码之前,链代码尚不可用。

要在每个终端上安装链码。

# peer chaincode install -n sacc -p github.com/chaincode/sacc -v 1.0

我们应该看到下面一条消息:

50afb4ddf3e5fbc58e2398adceb00bcc.png

现在所有节点都安装了链代码。 我们已准备好实例化此链代码。

第7步:在ChannelAll上实例化并与Chaincode交互

我们将首先关注ChannelAll。

在Org1终端上,我们在ChannelAll上实例化代码。

# peer chaincode instantiate -o orderer.example.com:7050 — tls — cafile $ORDERER_CA -C channelall -c ‘{“Args”:[“a”, “100”]}’ -n sacc -v 1.0 -P “OR(‘Org1MSP.peer’, ‘Org2MSP.peer’, ‘Org3MSP.peer’)”

我们将初始键/值对设置为/ 100。 除此之外,我们还指定了支持政策:需要三个组织之一(使用OR)。

我们将在ChannelAll中查询键“a”的值。

在Org1终端上

# peer chaincode query -C channelall -n sacc -c ‘{“Args”:[“get”,”a”]}’

d24ee074e3c330f2b14337084f05c408.png

现在在Org2终端上

# peer chaincode query -C channelall -n sacc -c ‘{“Args”:[“get”,”a”]}’

0deeb9c7c80ce3a04001354dfdfe5551.png

在Org3终端上,

# peer chaincode query -C channelall -n sacc -c ‘{“Args”:[“get”,”a”]}’

653956845726c0b7d3435e4f129a0ba9.png

我们现在看到三个对等点获得了相同的值。 他们共享同一个分类帐。

步骤8:在Channel12上实例化并与Chaincode交互

现在我们在Channel12上实例化相同的SACC。

在Org1终端上

# peer chaincode instantiate -o orderer.example.com:7050 — tls — cafile $ORDERER_CA -C channel12 -c ‘{“Args”:[“b”, “200”]}’ -n sacc -v 1.0 -P “OR(‘Org1MSP.peer’, ‘Org2MSP.peer’)”

这次我们将初始键/值对设置为b / 200。 赞同政策需要得到任何一个组织的认可。

然后我们再次开始Org1终端。

# peer chaincode query -C channel12 -n sacc -c ‘{“Args”:[“get”,”b”]}’

2327143a8c825d617c70bef00c640aab.png

然后在Org2终端上。

# peer chaincode query -C channel12 -n sacc -c ‘{“Args”:[“get”,”b”]}’

c63fd728705e2d182901988977f7c122.png

如果我们在Org3终端上发出相同的命令,我们会看到访问被拒绝的消息。 这是因为Org3不在第12通道。

# peer chaincode query -C channel12 -n sacc -c ‘{“Args”:[“get”,”b”]}’

007f26d8af105d4d6edafe80401549a9.png

如果我们试图在Channel12上得到键“a”的值,我们发现没有定义“a”。 每个渠道都有自己的分类帐,并且不共享状态。

在Org1或Org2终端上,

# peer chaincode query -C channel12 -n sacc -c ‘{“Args”:[“get”,”a”]}’

ae2c92b6e27d16d543a29cfd04b5c427.png

第9步:清理一切

一切都完成后,最好清理所有内容,包括docker容器和为此演示生成的文件。

要关闭所有容器并将其删除,我们使用docker-compose删除通过配置文件创建的容器。

$ docker-compose -f docker-compose.yaml down

3659813b5e9c832cf69ce0093c2576ea.png

仍然有一些停止的容器(从docker ps -a看到它)。 它们是实例化后的链代码。 我们也将删除它们。

$ docker ps -a
$ docker rm $(docker ps -aq)

219cc5932c574f2df9138e6f6b7e0dda.png

在我们删除通道工件时,建议保留channel-artifacts目录,因为下一个演示需要这个目录(或者您需要再次创建它)。

$ rm channel-artifacts/*

最后我们删除了crypto-config的整个目录。 该目录将在下次由cryptogen创建。

$ rm -r crypto-config

总结

我们已经完成了针对三组织Hyperledger Fabric网络的多通道设置。 我们从配置文件开始,根据我们的设置打开我们的网络。 通过在不同的通道上部署相同的链代码,我们观察到每个通道都有自己的分类帐,并且状态不会相互共享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值