fabric链码操作和编写链码约束
docker exec -it cli /bin/bash
创建通道
peer channel create -o orderer.example.com:7050 -c zlktchannel -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem
当前节点加入通道
peer channel join -b zlktchannel.block
其他节点在cli配置环境
export CORE_PEER_ID=org2peer0
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
export CORE_PEER_LOCALMSPID=Org2MSP
export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
其他节点加入通道
peer channel join -b zlktchannel.block
安装链码
peer chaincode install -n example02 -p github.com/hyperledger/fabric/examples/chaincode/go -v 1.0.0
链码实例化
peer chaincode instantiate
-o orderer.example.com:7050
-C zlktchannel
-c '{"Args":["init","a","2","b","3"]}'
-n example02
-P "AND ('OrdererOrg.member','Org1.member','Org2.member')"
-v 1.0.0
--tls true
--cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
peer chaincode instantiate -o orderer.example.com:7050 -C zlktchannel -c '{"Args":["init","a","2","b","3"]}' -n example02 -P "AND ('OrdererOrg.member','Org1.member','Org2.member')" -v 1.0.0 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
验证是否有新增容器
exit
docker ps -a
链码操作
//查询账户状态
peer chaincode query -C zlktchannel -n example02 -c '{"Args":["query","a"]}'
//账户转账
-c '{"Args":["invoke","a","b","1"]}'
//删除指定账户:
-c '{"Args":["delete","a"]}'
编写链码相关约束
-
1.package必须是main
-
2.必须要有main函数,main函数中执行了shim.Start
-
shim.Start(new(SimpleChaincode)) // SimpleChaincode是个结构体
-
3.必须要有个结构体,除了main函数,其他的函数必须都挂到这个结构体下,使用指针,包括Init函数
-
4.必须要有Init函数,不是小写的init
-
5.必须要用Invoke函数
peer包
type Response struct {
// A status code that should follow the HTTP status codes.
Status int32 `protobuf:"varint,1,opt,name=status" json:"status,omitempty"`
// A message associated with the response code.
Message string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"`
// A payload that can be used to include metadata with this response.
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"`
}
?
?
shim.Success(nil)
?
func Success(payload []byte) pb.Response {
return pb.Response{
Status: OK,
Payload: payload,
}
}
shim包
1.Chaincode interface
Init(stub ChaincodeStubInterface) pb.Response
Invoke(stub ChaincodeStubInterface) pb.Response
2.ChaincodeStubInterface interface
GetArgs() [][]byte // 获取所有的参数,包括函数和参数两个
GetStringArgs() []string // 获取所有的参数,包括函数和参数两个,转成string类型
GetFunctionAndParameters() (string, []string) // 获取所有的参数,把函数和参数分成两部分
GetArgsSlice() ([]byte, error) // 获取所有的参数,包括函数和参数两个,封装成切片类型
GetTxID() string // 获取交易的id
GetChannelID() string // 获取通道id
InvokeChaincode(chaincodeName string, args [][]byte, channel string) pb.Response // 根据链码名和channel名调用链码
GetState(key string) ([]byte, error) // 根据指定用户查看状态
PutState(key string, value []byte) error // 写入用户状态到账本
DelState(key string) error // 删除指定用户
GetStateByRange(startKey, endKey string) (StateQueryIteratorInterface, error) // 通过range方式获取多个用户状态
GetStateByPartialCompositeKey(objectType string, keys []string) (StateQueryIteratorInterface, error) // 获取组合键的集合
CreateCompositeKey(objectType string, attributes []string) (string, error) // 创建组合键
SplitCompositeKey(compositeKey string) (string, []string, error) // 切割组合键
GetQueryResult(query string) (StateQueryIteratorInterface, error) // CouchDB查询结果,couchdb 文档 https://github.com/cloudant/mango
GetHistoryForKey(key string) (HistoryQueryIteratorInterface, error) // 获取key的历史值
GetPrivateData(collection, key string) ([]byte, error) // 获取私有数据
PutPrivateData(collection string, key string, value []byte) error
DelPrivateData(collection, key string) error
GetPrivateDataByRange(collection, startKey, endKey string) (StateQueryIteratorInterface, error)
GetPrivateDataByPartialCompositeKey(collection, objectType string, keys []string) (StateQueryIteratorInterface, error) // 根据组合键获取私有数据
GetPrivateDataQueryResult(collection, query string) (StateQueryIteratorInterface, error)
GetCreator() ([]byte, error) // 获取当前用户
GetTransient() (map[string][]byte, error) // 返回可以被链码使用但没有保存在账本中的临时映射表,例如用于加密和解密的密码学信息
GetBinding() ([]byte, error) // 交易的nonce、creator和epoch拼接结果的SHA256哈希
GetDecorations() map[string][]byte // 获取map结构的附加数据
GetSignedProposal() (*pb.SignedProposal, error) // 返回完全解码的签名交易对象
GetTxTimestamp() (*timestamp.Timestamp, error) // 返回交易创建时的时间戳
SetEvent(name string, payload []byte) error // 当ChainCode提交完毕,会通过Event的方式通知Client。而通知的内
3.CommonIteratorInterface interface
HasNext() bool
Close() error
4.StateQueryIteratorInterface interface
CommonIteratorInterface
Next() (*queryresult.KV, error)
5.HistoryQueryIteratorInterface interface
CommonIteratorInterface 继承
Next() (*queryresult.KeyModification, error)
6.MockQueryIteratorInterface interface
StateQueryIteratorInterface 继承
接口文档: