go 语言,使用Fabric的测试网络,环境搭建

459 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第31天,点击查看活动详情

安装示例、二进制和 Docker 镜像

  1. 克隆 hyperledger/fabric-samples 仓库
  2. 检出适当的版本标签
  3. 将指定版本的 Hyperledger Fabric 平台特定二进制文件和配置文件安装到 fabric-samples 下的 /bin 和 /config 目录中
  4. 下载指定版本的 Hyperledger Fabric docker 镜像
  1. 执行命令
#如果你想要最新的生产发布版本,忽略所有的版本标识符。
# curl -sSL https://bit.ly/2ysbOFE | bash -s
# curl -sSL https://bit.ly/2ysbOFE | bash -s -- <fabric_version> <fabric-ca_version> <thirdparty_version>
# 若报错详见文末附加问题2
curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.2.0 1.4.7 0.4.18
# 若不行试试下面这个
curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh | bash -s  2.2.0 1.4.7 0.4.18

由于此命令国内无法运行成功,可以去github种找到该脚本文件,链接如下:
github.com/hyperledger…

复制该脚本信息,打开终端,并且创建一个sh文件并保存

# 创建命令:
touch bootstrap.sh
# 编辑命令:
vim bootstrap.sh
# 赋予文件权限:
sudo chmod u+x bootstrap.sh
# 运行该文件:
sudo ./bootstrap.sh

脚本所做的事:

  • 克隆 fabric-samples 源码
  • 下载 hyperledger-fabric-linux-amd64-2.2.0.tar.gz 得到 bin
  • 下载 hyperledger-fabric-ca-linux-amd64-1.4.7.tar.gz 得到 config
  • 下载相关 docker 镜像

看上图,我的 fabric-samples 在脚本中没有克隆成功,下面手动克隆下:

  1. 克隆 hyperledger/fabric-samples 仓库
mkdir -p $GOPATH/src/github.com/hyperledger
cd $GOPATH/src/github.com/hyperledger
# 克隆fabric-samples源码
sudo git clone https://github.com/hyperledger/fabric-samples.git
  1. 进入目录,切换分支

此处我们使用的是 2.2 版本

cd fabric-samples
# 可自行选择版本
sudo git checkout release-2.2
#查看版本
sudo git branch
  1. 将指定版本的 Hyperledger Fabric 平台特定二进制文件和配置文件安装到 fabric-samples 下的 /bin和 /config 目录中。

把bin和config目录复制到fabric/fabric-samples/目录下

cp -r bin $GOPATH/src/github.com/hyperledger/fabric-samples/
cp -r config $GOPATH/src/github.com/hyperledger/fabric-samples/
cd ~/go/src/github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go
sudo vi go.mod
# 进入文件发现是1.14 自己把改成1.13 ,要与你下载的go版本匹配

环境变量设置,把bin和config加入到环境变量中,以便我们可以全局访问

sudo vim /etc/profile
# 添加下面的变量
export PATH=$PATH:$GOPATH/src/github.com/hyperledger/fabric-samples/bin
export PATH=$PATH:$GOPATH/src/github.com/hyperledger/fabric-samples/config
# 使之生效
source /etc/profile
# 检验成功否
fabric-ca-client version

文件解锁

sudo chmod -R 777 fabric-samples

使用Fabric测试网络

开启debug模式!

export FABRIC_LOGGING_SPEC=debug
  1. 启动网络

在test-network目录中,运行以下命令删除先前运行的所有容器或工程:

cd test-network
./network.sh down
cd test-network/
sudo ./network.sh up 

network.sh 中的内容:

# 脚本有500多行,在这讲解脚本里的一些方法
function clearContainers()# 清除容器
function removeUnwantedImages() # 清除不想要的镜像
# 大家仔细看看都能读懂,下面挑几个关键且常用的讲
#创建组织
function createOrgs() {
# 这里包含一些业务逻辑比如
# Create crypto material using cryptogen or Fabric CA
if [ "$CRYPTO" == "cryptogen" ];then...
if [ "$CRYPTO" == "Certificate Authorities" ]; then..
}
# 创建联盟
function createConsortium()
# 开启网络
function networkUp()
# 创建channel
function createChannel()
# 开启链码
function deployCC()
# 最后给出了一些确定操作模式并打印出我们所要求的内容
if [ "$MODE" == "up" ]; then
  infoln "Starting nodes with CLI timeout of '${MAX_RETRY}' tries and CLI delay of '${CLI_DELAY}' seconds and using database '${DATABASE}' ${CRYPTO_MODE}"
elif [ "$MODE" == "createChannel" ]; then
  infoln "Creating channel '${CHANNEL_NAME}'."
  infoln "If network is not up, starting nodes with CLI timeout of '${MAX_RETRY}' tries and CLI delay of '${CLI_DELAY}' seconds and using database '${DATABASE} ${CRYPTO_MODE}"
elif [ "$MODE" == "down" ]; then
  infoln "Stopping network"
elif [ "$MODE" == "restart" ]; then
  infoln "Restarting network"
elif [ "$MODE" == "deployCC" ]; then
  infoln "deploying chaincode on channel '${CHANNEL_NAME}'"
else
  printHelp
  exit 1
fi

if [ "${MODE}" == "up" ]; then
  networkUp
elif [ "${MODE}" == "createChannel" ]; then
  createChannel
elif [ "${MODE}" == "deployCC" ]; then
  deployCC
elif [ "${MODE}" == "down" ]; then
  networkDown
else
  printHelp
  exit 1
fi 

创建了排序组织orderer、联盟成员org1的peer0节点和联盟成员org2的peer0节点以及相应的镜像image:

  1. 测试网络有两个组织成员,Org1和Org2, 还包括一个维护网络排序服务的排序组织。
  2. 每个组织各自运营一个对等节点, peer0.org1.example.com和peer0.org2.example.com.
  3. 每个Fabric网络还包括一个排序服务,该示例网络使用一个单节点Raft排序服务,该服务由排序组织运行。 可以看到在机器上正在运行的排序节点orderer.example.com。
  4. 虽然测试网络仅使用单节点排序服务,一个真实的网络将有多个排序节点,由一个或多个多个排序者组织操作。 不同的排序节点将使用Raft共识算法达成跨交易顺序的共识网络。

创建一个通道

现在机器上正在运行对等节点和排序节点, 我们可以使用脚本创建用于在Org1和Org2之间进行交易的Fabric通道。

使用network.sh脚本在Org1和Org2之间创建通道并加入他们的对等节点。 运行以下命令以创建一个默认名称为“ mychannel”的通道:

./network.sh createChannel

也可以自定义名称的通道:

# 1.不输入自定义名称通道,默认为mychannel
./network.sh createChannel
# 2.输入自定义名称,可以创建多个不同名称通道
./network.sh createChannel -c channel1
./network.sh createChannel -c channel2
# 3.也可以一步建立网络并创建频道
./network.sh up createChannel

在通道启动一个链码

我们需要为go语言安装依赖包,否则调用链码出错,切换到/fabric-samles/asset-transfer-basic/chaincode-go目录下,执行命令:

# 国内下载速度较慢,容易出错,换代理源
go env -w GOPROXY=https://goproxy.cn,direct
# 安装依赖包
go mod vendor

test-network 目录下启动链码:

sudo ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go

报错:

权限不够问题,不要加sudo解决,sudo会导致path环境找不到 将文件全部解锁:

sudo chmod -R 777 ~/go

如果有 'go list’failed with:go:github.com/golang/protobuf@… 解决方法:更换代理,输入命令

go env -w GOPROXY=https://goproxy.io.direct
go env -w GO111MODULE=on

解决上述问题后,执行启动安装链码结果:

与网络交互

在启用测试网络后,可以使用 peer CLI 与网络进行交互。 peer CLI 允许调用已部署的智能合约,更新通道,或安装和部署新的智能合约。

确保在 test-network 目录进行操作。可以在fabric-samples代码库的bin文件夹中找到peer二进制文件。 使用以下命令将这些二进制文件添加到您的 CLI路径:

export PATH=${PWD}/../bin:$PATH

还需要将fabric-samples代码库中的FABRIC_CFG_PATH设置为指向其中的core.yaml文件:

export FABRIC_CFG_PATH=$PWD/../config/

设置环境变量,以允许用户作为Org1操作peer CLI:

# Environment variables for Org1

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

CORE_PEER_TLS_ROOTCERT_FILECORE_PEER_MSPCONFIGPATH环境变量指向Org1的organizations文件夹中的加密材料。 如果您使用 ./network.sh deployCC -ccl go 安装和启动 asset-transfer (basic) 链码,您可以调用链码(Go)的 InitLedger 方法来赋予一些账本上的初始资产。 运行以下命令用一些资产来初始化账本:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"InitLedger","Args":[]}'

如果命令成功,您将观察到类似以下的输出:

-> INFO 001 Chaincode invoke successful. result: status:200

现在可以用 CLI 工具来查询账本。运行以下指令来获取添加到通道账本的资产列表:

peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'

调用链码改变账本上的资产所有者:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"TransferAsset","Args":["asset6","Christopher"]}'

因为 asset-transfer (basic) 链码的背书策略需要交易同时被 Org1 和 Org2 签名,链码调用指令需要使用 --peerAddresses 标签来指向 peer0.org1.example.com 和 peer0.org2.example.com。因为网络的 TLS 被开启,指令也需要用 --tlsRootCertFiles 标签指向每个 peer 节点的 TLS 证书。

调用链码之后,我们可以使用另一个查询来查看调用如何改变了区块链账本的资产。因为我们已经查询了 Org1 的 peer,我们可以把这个查询链码的机会通过 Org2 的 peer 来运行。

设置以下的环境变量来操作 Org2:

# Environment variables for Org2

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

查询运行在 peer0.org2.example.com asset-transfer (basic) 链码:

peer chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset6"]}'

结果显示 "asset6" 转给了 Christopher:

关停网络

使用完测试网络后,可以使用以下命令关闭网络:

./network.sh down

该命令将停止并删除节点和链码容器,删除组织加密材料,并从Docker Registry移除链码镜像。该命令还删除之前运行的通道项目和docker卷。

关闭后查看容器:

sudo docker ps -a