区块链优质币:在开发环境中测试Hyperledger Fabric Chaincodes
Happyledger
这是我hyperledger fabric系列文章的第四部分——happyledgerblog系列:)。在这篇文章中,我将展示如何在本地开发机器中构建、运行和测试(调试)链代码。
正常的链代码是安装和运行在对等点上的。但是使用chaincode开发模式,我们可以在本地开发机器上运行和测试它们。在真正的网络上部署链代码之前,编译、运行和测试它们是值得的。
与本文相关的所有部署文件和配置都是athlf-chaincode-dev gitlab repo。签出存储库并遵循以下步骤。
1. 设置fabric开发网络
首先,我们需要使用预先生成的orderer和channel构件部署dev mode docker容器。以下是在这个目录中找到的预生成工件。
1.myc.block – 引导块
2.myc.tx – 引导连接事物
3.orderer.block – 预定块
您可以像下面这样部署服务。它将启动并运行orderer、peer、cli和chaincode容器。Orderer以SingleSampleMSPSoloprofile开始,peer以dev-mode开始。
# deploy following containers
# 1. orderer
# 2. peer
# 3. cli
# 4. chaincode
docker-compose up -d
2. 构建和运行链代码
接下来我们需要在链代码容器中构建和运行链代码。我已经放了我的rahasak。进入chaincode/rahasak目录中的链代码。这个链代码具有用户创建、获取、搜索功能。
package main
import (
"bytes"
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
)
type RahasakContract struct {
}
type User struct {
Id string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
func (s *RahasakContract) Init(stub shim.ChaincodeStubInterface) peer.Response {
args :=stub.GetStringArgs()
fmt.Printf("INFO: init chaincode args: %s\n", args)
return shim.Success(nil)
}
func (s *RahasakContract) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
// Retrieve the requested Smart Contract function and arguments
function, args :=stub.GetFunctionAndParameters()
fmt.Printf("INFO: invoke function: %s, args: %s\n", function, args)
if function=="create" {
return s.Create(stub, args)
} else if function=="get" {
return s.Get(stub, args)
} else if function=="search" {
return s.Search(stub, args)
}
return shim.Error("Invalid smart contract function")
}
func (s *RahasakContract) Create(stub shim.ChaincodeStubInterface, args []string) peer.Response {
fmt.Printf("INFO: create with args: %s\n", args)
// user
usr :=User{
Id: args[0],
Name: args[1],
Email: args[2],
}
usrJsn, _ :=json.Marshal(usr)
err :=stub.PutState(args[0], usrJsn)
if err !=nil {
fmt.Printf("ERROR: error PutState: %s\n", err.Error())
shim.Error("error PutState: " + err.Error())
}
return shim.Success(nil)
}
func (s *RahasakContract) Get(stub shim.ChaincodeStubInterface, args []string) peer.Response {
fmt.Printf("INFO: get with args: %s\n", args)
usr, _ :=stub.GetState(args[0])
if usr==nil {
return shim.Error("Could not get user with id: " + args[0])
}
return shim.Success(usr)
}
func (s *RahasakContract) Search(stub shim.ChaincodeStubInterface, args []string) peer.Response {
fmt.Printf("INFO: search with args: %s\n", args)
// from, to range comes with args
frm :=args[0]
to :=args[1]
// search by range
iterator, err :=stub.GetStateByRange(frm, to)
if err !=nil {
return shim.Error("Error search by range: " + err.Error())
}
defer iterator.Close()
// build json respone
buffer, err :=buildResponse(iterator)
if err !=nil {
return shim.Error("Error constract response: " + err.Error())
}
fmt.Printf("INFO: search response:%s\n", buffer.String())
return shim.Success(buffer.Bytes())
}
func buildResponse(iterator shim.StateQueryIteratorInterface) (*bytes.Buffer, error) {
// buffer is a JSON array containing query results
var buffer bytes.Buffer
buffer.WriteString("[")
written :=false
for iterator.HasNext() {
resp, err :=iterator.Next()
if err !=nil {
return nil, err
}
// add a comma before array members, suppress it for the first array member
if written==true {
buffer.WriteString(",")
}
// record is a JSON object, so we write as it is
buffer.WriteString(string(resp.Value))
written=true
}
buffer.WriteString("]")
return &buffer, nil
}
func main() {
err :=shim.Start(new(RahasakContract))
if err !=nil {
fmt.Printf("ERROR: error creating rahasak contact: %s\n", err.Error())
}
}
下面是在chaincode容器中构建和运行这个链代码的命令。
# connect to chaincode container
docker exec -it chaincode bash
# build chaincode
cd rahasak
go build -o rahasak
# run chaincode
# when running we are specifying the chaincode name and version
CORE_PEER_ADDRESS=peer:7052 CORE_CHAINCODE_ID_NAME=rahasak1:0 https://www.qukuaiwang.com.cn/news/rahasak
在运行chaincode时,我们指定了chaincode的唯一名称和版本(rahasak1.0)。现在chaincode已经在链代码容器中启动了。
3.安装并实例化chaincode
下一步是在peer中安装和实例化链代码(就像我们在真实fabric集群中安装和实例化链代码一样)。下面是这样做的方法。
# install chaincode
# we are given unique name and version of the chaincode
peer chaincode install -p chaincodedev/chaincode/rahasak -n rahasak1 -v 0
# instantiate chaincode
# we are giving channel name and chaincode name
peer chaincode instantiate -n rahasak1 -v 0 -c '' -C myc
在安装和实例化时,我们需要指定chaincode的名称。在这里,我将rahasak1作为名称,0作为版本。现在,我们的chaincode设置已经准备好进行测试。
4.测试chaincode
要测试chaincode,我们可以执行调用、查询事务。下面是这样做的方法。
# invoke transactions with 'create'
peer chaincode invoke -n rahasak1 -c '{"Args":["create", "001", "lambda", ""]}' -C myc
peer chaincode invoke -n rahasak1 -c '{"Args":["create", "002", "ops", ""]}' -C myc
# query transactions with 'get'
# output - {"id":"001","name":"lambda","email":""}
peer chaincode query -n rahasak1 -c '' -C myc
# query transactions with 'search'
# output
[{"id":"001","name":"lambda","email":""},{"id":"002","name":"ops","email":""}]
peer chaincode query -n rahasak1 -c '' -C myc
更多区块链信息:www.qukuaiwang.com.cn/news