基于区块链与IPFS的数据共享系统之区块链部分设计

本节对数据共享系统的区块链部分做一个简单的介绍,包括目录结构、文件作用、设计思路。

购买专栏前请认真阅读:《基于区块链与IPFS的数据共享系统》专栏简介

一、区块链部分文件目录简介

├── bin //保存了二进制文件方便启动网络
│   ├── configtxgen //生成创世区块和通道材料
│   └── cryptogen //生成密钥
├── chaincode //链码
│   ├── datashare.go
│   ├── go.mod
│   └── go.sum
├── configtx.yaml //来自byfn
├── crypto-config.yaml //来自byfn
├── docker-compose-byfn.yaml //byfn中的节点配置与IPFS容器配置
├── explorer //区块链浏览器
│   ├── config.json
│   ├── connection-profile
│   └── docker-compose.yaml
├── start.sh //启动网络脚本
├── stop.sh //关闭网络脚本
└── tape //fabric压测工具tape
    ├── config-temp.yaml
    ├── tape
    └── test

二、启动网络脚本 start.sh

启动脚本为启动区块链网络以及IPFS容器,之后使用sed命令更换区块链浏览器、tape配置文件中的私钥。

这里解释一下为什么需要替换私钥文件,因为每次区块链网络重启后都会重新生成私钥文件,区块链浏览器、tape在使用时访问Fabric网络需要使用私钥文件。

具体步骤如下面代码所示,首先是获取私钥文件名称;然后使用模版文件 config-temp.yaml 替换当前的配置文件;使用sed命令替换priv_sk字段,此时配置文件中的私钥就替换好了。

#替换tape配置文件的私钥
priv_sk=$(ls crypto-config/peerOrganizations/org1.example.com/users/[email protected]/msp/keystore)
cp -rf ./tape/config-temp.yaml ./tape/config.yaml
sed -i "s/priv_sk/$priv_sk/" ./tape/config.yaml

三、关闭网络脚本 ./stop.sh

关闭网络脚本中依次清理区块链网络与区块链浏览器的Docker容器、网络相关材料以及链码容器。

#清理之前的网络
docker-compose -f explorer/docker-compose.yaml down -v
docker-compose -f docker-compose-byfn.yaml down -v
#清理网络相关材料
rm -rf channel-artifacts
rm -rf crypto-config
#清理链码容器
clearContainers
removeUnwantedImages

四、docker-compose-byfn.yaml 文件

这个文件是将BYFN中的first-network默认启动的网络相关的yaml文件整理了一下,整合到了一个yaml文件里,看着会比较清晰。此外,IPFS容器配置也放到了此文件,方便IPFS启动。

五、链码 datashare.go

在本链码中,使用结构体存储数据的传输记录,字段有发送者、接受者、使用发送者公钥加密的文件CID(IPFS Hash)、使用接受者公钥加密的文件CID、文件名称、区块链交易Hash、时间戳。

// 数据传输记录结构体
type Record struct {
	Sender                string `json:"sender"`
	Receiver              string `json:"receiver"`
	SenderEncrypted_cid   string `json:"secid"`
	ReceiverEncrypted_cid string `json:"recid"`
	Filename              string `json:"filename"`
	Txid                  string `json:"txid"`
	Timestamp             string `json:"timestamp"`
}

在invoke中可以看到有两个主要的函数queryRecordsendData,其中queryRecord是用来查询传输记录的,传入的参数为用户的公钥,然后是通过APIstub.GetState()获取Fabric账本中的键为args[0]对应的值。

提示:在Fabric默认使用的levelDB中,数据使用Key-Value键值对存储数据。

sendData函数为负责将传输记录上链,关键代码如下:

# 实例化Record结构体并使用传入的参数赋值
var record = Record{Sender: args[0], Receiver: args[1], SenderEncrypted_cid: args[2], ReceiverEncrypted_cid: args[3], Filename: args[4], Timestamp: time, Txid: APIstub.GetTxID()}
# 获取用户当前已存的传输记录
recordsAsBytes, err := APIstub.GetState(args[1])
#使用json反序列化,将json格式的数据转化为结构体,方便操作
json.Unmarshal(recordsAsBytes, &records)
#添加新的记录到所有的传输记录中
records = append(records, record)
#将新的传输记录存储至账本中
APIstub.PutState(args[1], recordsAsBytes)

你可能感兴趣的:(区块链)