golang企业级区块链开发框架插件Hyperledger的使用
Golang企业级区块链开发框架插件Hyperledger的使用
编码规范
我们使用Go语言开发,并遵循《Effective Go》和《Go Code Review Comments》中概述的最佳实践和编码风格。
建议新贡献者在提交pull request前阅读以下内容:
- Practical Go
- Go Proverbs
所有pull request都会执行以下工具检查,必须解决这些工具报告的错误才能合并代码:
- gofmt -s
- goimports
- go vet
测试
所有生产代码变更都需附带单元测试。这些测试应该:
- 执行速度快
- 对新修改代码有很好的覆盖率
- 支持并行执行
我们常用的测试匹配库:
- gomega
- testify/assert
测试所需的fixture或数据应生成或置于版本控制下:
- 生成的fixture应放在
ioutil.TempDir
创建的临时目录中,测试结束后清理 - 版本控制的fixture应放在
testdata
文件夹中,并附带生成说明 - 不鼓励跨包共享fixture
当需要fake或mock时,必须使用生成工具:
- counterfeiter
- mockery
API文档
Hyperledger Fabric的Golang API文档可在GoDoc中查看。
生成gRPC代码
如果修改了任何.proto
文件,运行以下命令生成/更新对应的.pb.go
文件:
cd $GOPATH/src/github.com/hyperledger/fabric
make protos
添加或更新Go包
Hyperledger Fabric使用vendor机制管理依赖。所有依赖包都放在$GOPATH/src/github.com/hyperledger/fabric/vendor
文件夹中。我们使用dep工具管理vendor文件夹中的包。
示例代码
以下是一个简单的Hyperledger Fabric链码示例:
package main
import (
"fmt"
"github.com/hyperledger/fabric-contract-api-go/contractapi"
)
// SimpleChaincode 示例链码结构
type SimpleChaincode struct {
contractapi.Contract
}
// Init 链码初始化方法
func (s *SimpleChaincode) Init(ctx contractapi.TransactionContextInterface) error {
fmt.Println("Chaincode initialized")
return nil
}
// Invoke 链码调用方法
func (s *SimpleChaincode) Invoke(ctx contractapi.TransactionContextInterface) (string, error) {
fmt.Println("Chaincode invoked")
return "Hello from chaincode", nil
}
func main() {
chaincode, err := contractapi.NewChaincode(&SimpleChaincode{})
if err != nil {
fmt.Printf("Error creating chaincode: %s", err.Error())
return
}
if err := chaincode.Start(); err != nil {
fmt.Printf("Error starting chaincode: %s", err.Error())
}
}
更多关于golang企业级区块链开发框架插件Hyperledger的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang企业级区块链开发框架插件Hyperledger的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Hyperledger Fabric Golang 开发指南
Hyperledger Fabric 是企业级区块链开发的首选框架之一,下面我将介绍如何使用 Golang 进行 Hyperledger Fabric 开发。
1. 环境准备
首先需要安装必要的工具和依赖:
// 安装 Hyperledger Fabric 相关工具
// 1. 安装 Docker 和 Docker Compose
// 2. 安装 Go (推荐 1.14+)
// 3. 安装 Hyperledger Fabric 二进制文件和示例
curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.2.3 1.4.9
2. 链码(智能合约)开发
链码是 Hyperledger Fabric 的核心业务逻辑,使用 Go 开发链码的基本结构:
package main
import (
"fmt"
"github.com/hyperledger/fabric-contract-api-go/contractapi"
)
// SmartContract 提供合约函数定义
type SmartContract struct {
contractapi.Contract
}
// InitLedger 初始化账本
func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error {
assets := []Asset{
{ID: "asset1", Color: "blue", Size: 5, Owner: "Tomoko", AppraisedValue: 300},
{ID: "asset2", Color: "red", Size: 5, Owner: "Brad", AppraisedValue: 400},
}
for _, asset := range assets {
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}
err = ctx.GetStub().PutState(asset.ID, assetJSON)
if err != nil {
return fmt.Errorf("failed to put to world state. %v", err)
}
}
return nil
}
// CreateAsset 创建新资产
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
}
if exists {
return fmt.Errorf("the asset %s already exists", id)
}
asset := Asset{
ID: id,
Color: color,
Size: size,
Owner: owner,
AppraisedValue: appraisedValue,
}
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}
return ctx.GetStub().PutState(id, assetJSON)
}
// 主函数
func main() {
chaincode, err := contractapi.NewChaincode(&SmartContract{})
if err != nil {
fmt.Printf("Error creating asset-transfer-basic chaincode: %v", err)
return
}
if err := chaincode.Start(); err != nil {
fmt.Printf("Error starting asset-transfer-basic chaincode: %v", err)
}
}
3. 链码测试
可以使用 Fabric 提供的模拟框架进行测试:
package main
import (
"testing"
"github.com/hyperledger/fabric-chaincode-go/shimtest"
"github.com/stretchr/testify/assert"
)
func TestInitLedger(t *testing.T) {
chaincodeStub := shimtest.NewMockStub("chaincode", new(SmartContract))
response := chaincodeStub.MockInit("1", [][]byte{})
assert.Equal(t, int32(shim.OK), response.Status)
}
func TestCreateAsset(t *testing.T) {
chaincodeStub := shimtest.NewMockStub("chaincode", new(SmartContract))
// 先初始化
chaincodeStub.MockInit("1", [][]byte{})
// 测试创建资产
response := chaincodeStub.MockInvoke("1", [][]byte{
[]byte("CreateAsset"),
[]byte("asset3"),
[]byte("yellow"),
[]byte("5"),
[]byte("Tom"),
[]byte("600"),
})
assert.Equal(t, int32(shim.OK), response.Status)
// 验证资产已创建
assetBytes := chaincodeStub.State["asset3"]
assert.NotNil(t, assetBytes)
}
4. 客户端应用开发
使用 Fabric Go SDK 与区块链网络交互:
package main
import (
"fmt"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config"
"github.com/hyperledger/fabric-sdk-go/pkg/gateway"
"log"
)
func main() {
// 1. 加载连接配置文件
ccpPath := "./connection-org1.yaml"
gw, err := gateway.Connect(
gateway.WithConfig(config.FromFile(filepath.Clean(ccpPath))),
gateway.WithIdentity(gateway.NewX509Identity("Org1MSP", "cert.pem", "key.pem")),
)
if err != nil {
log.Fatalf("Failed to connect to gateway: %v", err)
}
defer gw.Close()
// 2. 获取网络通道
network, err := gw.GetNetwork("mychannel")
if err != nil {
log.Fatalf("Failed to get network: %v", err)
}
// 3. 获取合约实例
contract := network.GetContract("basic")
// 4. 调用链码函数
result, err := contract.SubmitTransaction("CreateAsset", "asset6", "blue", "35", "Tom", "1300")
if err != nil {
log.Fatalf("Failed to submit transaction: %v", err)
}
fmt.Println(string(result))
// 5. 查询资产
result, err = contract.EvaluateTransaction("ReadAsset", "asset6")
if err != nil {
log.Fatalf("Failed to evaluate transaction: %v", err)
}
fmt.Println(string(result))
}
5. 部署链码
部署链码到 Fabric 网络的基本步骤:
- 打包链码
peer lifecycle chaincode package basic.tar.gz --path ./chaincode --lang golang --label basic_1.0
- 安装链码
peer lifecycle chaincode install basic.tar.gz
- 批准链码定义
peer lifecycle chaincode approveformyorg -o orderer.example.com:7050 --channelID mychannel --name basic --version 1.0 --sequence 1 --package-id $PACKAGE_ID
- 提交链码定义
peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID mychannel --name basic --version 1.0 --sequence 1
最佳实践
- 错误处理:链码中必须正确处理错误,避免panic
- 状态验证:在修改状态前验证数据是否存在
- 日志记录:使用shim提供的日志功能
- 测试覆盖:编写全面的单元测试
- 性能优化:避免链码中的复杂计算
Hyperledger Fabric 提供了强大的企业级区块链功能,结合 Golang 的高效开发能力,可以构建出高性能、安全的区块链应用。