本篇博客基于 Fabric v2.2 部署了一个联盟链,包含一个Org和两个peer,使用了单个节点的raft作为Ordering service。部署过程主要参考了Fabric的官方文档,大部分脚本和配置文件都来自于官方提供的样例。
测试使用了 tape 这个轻量级的工具,个人觉得比 caliper 好用。
部署
curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.2.2 1.4.9
cd fabric-samples/test-network
./network.sh up
./network.sh createChannel
# 使用smallbank进行测试
mkdir -p smallbank/go
cd smallbank/go
touch go.mod smallbank.go # 这两个文件内容在下面,复制进去之后,再运行下一条命令
./network.sh deployCC -ccn smallbank -ccp ./smallbank/go -ccl go -cci InitLedger
go.mod 文件如下:
module github.com/hyperledger/fabric-samples/chaincode/smallbank/go
go 1.13
require github.com/hyperledger/fabric-contract-api-go v1.1.0
smallbank.go 文件如下:
package main
import (
"encoding/json"
"fmt"
"crypto/sha512"
"encoding/hex"
"strings"
"github.com/hyperledger/fabric-contract-api-go/contractapi"
)
var namespace = hexdigest("smallbank")[:6]
// SmartContract provides functions for managing a Account
type SmartContract struct {
contractapi.Contract
}
type Account struct {
CustomId string
CustomName string
SavingsBalance int
CheckingBalance int
}
func hexdigest(str string) string {
hash := sha512.New()
hash.Write([]byte(str))
hashBytes := hash.Sum(nil)
return strings.ToLower(hex.EncodeToString(hashBytes))
}
func accountKey(id string) string {
return namespace + hexdigest(id)[:64]
}
func saveAccount(ctx contractapi.TransactionContextInterface, account *Account) error {
accountBytes, err := json.Marshal(account)
if err != nil {
return err
}
key := accountKey(account.CustomId)
return ctx.GetStub().PutState(key, accountBytes)
}
func loadAccount(ctx contractapi.TransactionContextInterface, id string) (*Account, error) {
key := accountKey(id)
accountBytes,err := ctx.GetStub().GetState(key