预先准备

环境下载

详细可以参考官方文档-预先配置

拉取源码、下载镜像

以2.5.5版本为例子

  • 拉取Fabric源码:Fabric
  • 拉取Fabric-Sample源码:Fabric-Sample
    • 拉取后放置在\fabric\scripts
  • 下载Fabrice编译文件Realse
    • 下载名为hyperledger-fabric-linux-amd64-x.x.x.tar.gz
    • 解压后的binbuildersconfig放在\fabric\scripts\sample

拉取镜像

1
2
3
4
5
6
7
# 需要逐条执行
docker pull hyperledger/fabric-peer
docker pull hyperledger/fabric-orderer
docker pull hyperledger/fabric-ccenv
docker pull hyperledger/fabric-tools
docker pull hyperledger/fabric-baseos
docker pull hyperledger/fabric-ca

拉取镜像结果.png

启动第一个网络

切换到Fabric\fabric\scripts\fabric-samples\test-network

执行./network.sh up

常见报错: 找不到/bin/bash^M

原因:WSL下,shell脚本博主在windows写的,直接copy到了linux中
解决方案:可以使用dos2unix命令参考文章
先安装:sudo apt-get install dos2unix
输入命令dos2unix filename即可,filename为报错文件
更建议用下面的命令直接全部替换!

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
#!/usr/bin/env bash
# Author : 蛙鳜鸡鹳狸猿
# create_ts : 2019-06-06
# program : Convert DOS/Mac text file format into Unix


function dos_to_unix() {
# Convert DOS/Mac text file format into Unix under built-in `dos2unix` handler.
# $1: OS directory path
local path="$1"
local path=${path%/}
local IFS=$'\n'
# shellcheck disable=SC2045
for obj in $(ls "${path}")
do
if [[ -d "${path}/${obj}" ]]; then
dos_to_unix "${path}/${obj}"
else
dos2unix "${path}/${obj}"
fi
done
}


dos_to_unix "$1"

# 命令为:xxx.sh “根目录”,会自动遍历整个目录进行修正(包括子目录)

第一个网络运行成功.png

执行./network.sh down关闭

第一个网络关闭.png

  • 执行./network.sh查询可以执行的命令

    执行./network.sh createChannel创建链接通道

    输出Channel ‘mychannel’ joined即成果创建

Channel创建

部署链码

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

这是一个用于部署区块链智能合约的命令,它使用了Hyperledger Fabric框架,一个开源的区块链平台,用于构建可扩展、企业级的分布式账本技术解决方案。命令的各个部分含义如下:

  • ./network.sh: 这是一个脚本,可能用于设置、配置或管理一个Hyperledger Fabric网络。
  • deployCC: 这是脚本中的一个命令,用于部署一个新的智能合约。
  • -ccn basic: 这里的 basic 是智能合约的名称,它指的是 basic 智能合约。
  • -ccp ../asset-transfer-basic/chaincode-go: 这个参数指定了智能合约的代码所在的位置。../asset-transfer-basic/chaincode-go 可能是一个文件路径,指向包含 Go 语言编写的智能合约代码的目录。
  • -ccl go: 这个参数表明智能合约是用 Go 语言编写的。

    简单来说,这个命令的作用就是在一个Hyperledger Fabric网络中部署一个名为 basic 的智能合约,该合约的代码是用 Go 语言编写的,并且存放在某个指定路径中。智能合约是区块链系统中的自执行程序,它允许在满足某些条件时在区块链上自动执行预定义的业务逻辑。

部署链码

常见问题:

代理链接被拒绝Error: chaincode install failed with status: 500 - failed to invoke backing implementation of 'InstallChaincode': could not build chaincode: docker build failed: docker image build failed: docker build failed: Error returned from build: 1 "go: github.com/golang/protobuf@v1.3.2: Get "https://proxy.golang.org/github.com/golang/protobuf/@v/v1.3.2.mod": dial tcp 172.217.24.17:443: connect: connection refused使用如下方案

1
2
3
4
5
6
// 第一步:到链码所在的目录下提前下载依赖包
cd fabric-samples/asset-transfer-basic/chaincode-go
// 第一步:更改GO代理
go env -w GOPROXY=https://goproxy.io,direct
go env -w GO111MODULE=on
go mod vendor

之后重启网络部署 重新使用deployCC指令即可

初始化账本

依次执行下列内容,设置变量

1
2
3
4
5
6
7
8
9
10
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/

# 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

执行下面内容,初始化账本

1
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":[]}'

初始化账本

执行操作

  • peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'查询分类账
1
2
3
4
5
6
7
8
[
{"ID": "asset1", "color": "blue", "size": 5, "owner": "Tomoko", "appraisedValue": 300},
{"ID": "asset2", "color": "red", "size": 5, "owner": "Brad", "appraisedValue": 400},
{"ID": "asset3", "color": "green", "size": 10, "owner": "Jin Soo", "appraisedValue": 500},
{"ID": "asset4", "color": "yellow", "size": 10, "owner": "Max", "appraisedValue": 600},
{"ID": "asset5", "color": "black", "size": 15, "owner": "Adriana", "appraisedValue": 700},
{"ID": "asset6", "color": "white", "size": 15, "owner": "Michel", "appraisedValue": 800}
]
  • 转账操作
1
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"]}'

输出:

1
2024-01-13 23:01:50.539 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200 payload:"Michel"

  • 查询单个账本
    peer chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset6"]}'

输出
{"AppraisedValue":800,"Color":"white","ID":"asset6","Owner":"Christopher","Size":15}

前后端交互

基本概念

链码

链码交互

  • peer chaincode upgrade: 用于升级已经部署的智能合约。
  • peer chaincode install: 用于将智能合约的二进制文件安装到本地的 peer 节点上。
  • peer chaincode invoke: 用于执行智能合约的提交操作,即发起交易
  • peer chaincode query: 用于执行智能合约的查询操作,即执行不改变区块链状态的操作。
  • peer chaincode transaction: 这个命令是一个复合命令,包括了部署、提交和查询等多种操作。
  • peer chaincode package: 用于创建智能合约的包文件,以便于部署和安装。
  • peer chaincode lifecycle: 用于管理智能合约的生命周期,包括 instantiate、upgrade 等操作。
  • peer chaincode install: 用于将智能合约的二进制文件安装到本地的 peer 节点上。

项目文件

区块链部分

区块链项目文件长这样——

1
2
3
4
5
6
7
8
9
10
11
12
├── chaincode # 链码(智能合约)
│ ├── chaincode # 存放链码的函数与其中的结构体(数据类型)
│ ├── go.mod
│ ├── go.sum
│ ├── test.fabric # 链码开发使⽤的测试文件
│ ├── trace.go # 链码主函数
│ └── vendor # 依赖文件,⾃动⽣成
├── network
│ ├── start.sh # 启动⽹络使⽤的脚本
│ ├── stop.sh # 关闭⽹络使⽤的脚本
│ └── trace.tar.gz

启动脚本主要内容:检查镜像是否完整、启动区块链⽹络以及Mysql容器区块链浏览器的容器、复制私钥文件。启动脚本简化了本项⽬区块链⽹络的启动流程。 这⾥解释⼀下为什么需要复制私钥文件,因为每次区块链⽹络重启后都会重新⽣成私钥文件,区块链浏览器、tape在使⽤时访问Fabric⽹络需要使⽤私钥文件。

启动区块链的核心在于——

1
2
3
4
5
6
7
8
9
10
11
# 启动区块链⽹络、创建通道
./network.sh up createChannel
# 部署链码,使⽤basic链码
./network.sh deployCC -ccn trace -ccp ../chaincode -ccl go
# 复制私钥文件
cp -r organizations explorer/
# 启动mysql容器
docker run --name fabrictrace-mysql -p 3337:3306 -e
MYSQL_ROOT_PASSWORD=fabrictrace -d mysql:8
# 启动区块链浏览器
docker compose -f explorer/docker-compose.yaml up

Go是怎么调用的呢?

1
2
3
4
5
6
var args []string
args = append(args, user.UserID)
args = append(args, c.PostForm("userType"))
args = append(args, user.RealInfo)
res, err := pkg.ChaincodeInvoke("RegisterUser", args)
// "RegisterUser"是连码名,

fabric.go文件介绍

  1. 配置信息
    cryptoPath 直接使⽤相对路径获取blockchain/network的密钥证书材料。其他参考了官⽅给的⽰例代码: assetTransfer.go。使⽤了Fabric Gateway模式连接
1
2
3
4
5
6
7
8
9
10
11
const (
mspID = "Org1MSP"
cryptoPath =
"../../blockchain/network/organizations/peerOrganizations/org1.example.com"
certPath = cryptoPath +
"/users/User1@org1.example.com/msp/signcerts/User1@org1.example.com-cert.pem"
keyPath = cryptoPath + "/users/User1@org1.example.com/msp/keystore/"
tlsCertPath = cryptoPath + "/peers/peer0.org1.example.com/tls/ca.crt"
peerEndpoint = "localhost:7051"
gatewayPeer = "peer0.org1.example.com"
)