上一节环境部署ok了,就不自觉的手痒想要自己跑一个小demo看看,据我了解,fabric的开发分为两个,一个是chaincode,一个是applicaiton开发(这需要调用sdk,这是后话了)。
开发环境准备:
atom(百度看说用这个顺手,就下了一个,本人是Java出身,IDEA玩的比较熟)。
chaincode代码实例:
chaincode001.go(做一个简单的set和get操作)
package main
import(
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
)
type Helloworld struct{
}
func (t *Helloworld) Init(stub shim.ChaincodeStubInterface) peer.Response {
args:=stub.GetStringArgs()
err := stub.PutState(args[0],[]byte(args[1]))
if err != nil{
shim.Error(err.Error())
}
return shim.Success(nil)
}
func (t *Helloworld) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
fn, args := stub.GetFunctionAndParameters()
if fn == "set"{
return t.set(stub,args)
}else if fn == "get"{
return t.get(stub,args)
}
return shim.Error("error solution")
}
func (t *Helloworld) set(stub shim.ChaincodeStubInterface, args []string) peer.Response{
err := stub.PutState(args[0],[]byte(args[1]))
if err != nil{
shim.Error(err.Error())
}
return shim.Success(nil)
}
func (t *Helloworld) get(stub shim.ChaincodeStubInterface, args []string) peer.Response{
value, err := stub.GetState(args[0])
if err != nil{
return shim.Error(err.Error())
}
return shim.Success(value)
}
func main() {
err := shim.Start(new(Helloworld))
if err != nil {
fmt.Printf("Error starting Simple chaincode: %s", err)
}
}
chaincode001_test.go(本地的一个小单元测试)
package main
import (
"fmt"
"testing"
"github.com/hyperledger/fabric/core/chaincode/shim"
)
func checkInit(t *testing.T, stub *shim.MockStub, args [][]byte) {
res := stub.MockInit("1", args)
if res.Status != shim.OK {
fmt.Println("Init failed", string(res.Message))
t.FailNow()
}
}
func checkQuery(t *testing.T, stub *shim.MockStub, name string) {
res := stub.MockInvoke("1", [][]byte{[]byte("get"), []byte(name)})
if res.Status != shim.OK {
fmt.Println("Query", name, "failed", string(res.Message))
t.FailNow()
}
if res.Payload == nil {
fmt.Println("Query", name, "failed to get value")
t.FailNow()
}
fmt.Println("Query value", name, "was ", string(res.Payload))
}
func checkInvoke(t *testing.T, stub *shim.MockStub, args [][]byte) {
res := stub.MockInvoke("1", args)
if res.Status != shim.OK {
fmt.Println("Invoke", args, "failed", string(res.Message))
t.FailNow()
}
}
func Test_Helloworld(t *testing.T) {
hello := new(Helloworld)
stub := shim.NewMockStub("hello", hello)
checkInit(t, stub, [][]byte{[]byte("str"), []byte("helloworld")})
checkQuery(t, stub, "str")
checkInvoke(t, stub, [][]byte{[]byte("set"), []byte("str"), []byte("helloworld-1111")})
checkQuery(t, stub, "str")
}
测试(遇到一些语法问题,毕竟第一次使用go):
dell@dell-OptiPlex-3050:~/go/goproject/chaincode001$ go test -v chaincode001_test.go chaincode001.go
=== RUN Test_Helloworld
Query value str was helloworld
Query value str was helloworld-1111
--- PASS: Test_Helloworld (0.00s)
PASS
ok command-line-arguments 0.007s
部署到fabric中:
深蓝居
参考步骤的话只要从第5步骤开始就行。
1.切换节点
CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
2. 安装代码(此处我将自己的chaincode放到啦相同的目录下,避免不必要的麻烦主要是)
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode001
3.实例化(注意不能和以前实例化的一样,本地一开始搭建环境时已经实例化一个mycc了)
peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n helw -v 1.0 -c '{"Args":["str","helloworld"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
4. get操作
peer chaincode query -C mychannel -n helw -c '{"Args":["get","str"]}'
5. set操作
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n helw -c '{"Args":["set","str","helwworld111"]}'
基本都是在尝试中成功的,不容易,后续切换节点什么的可以参考博客里的其他操作。