Commit ba75570b authored by harrylee's avatar harrylee

update sidecar-client-chain33

parent 2b71365a
...@@ -23,7 +23,7 @@ import ( ...@@ -23,7 +23,7 @@ import (
) )
var logger = hclog.New(&hclog.LoggerOptions{ var logger = hclog.New(&hclog.LoggerOptions{
Name: "client", Name: "chain33-client",
Output: os.Stderr, Output: os.Stderr,
Level: hclog.Trace, Level: hclog.Trace,
}) })
...@@ -92,7 +92,7 @@ func (c *Client) Initialize(configPath, appchainID string, extra []byte) error { ...@@ -92,7 +92,7 @@ func (c *Client) Initialize(configPath, appchainID string, extra []byte) error {
EventFilter: chain33Config.EventFilter, EventFilter: chain33Config.EventFilter,
PrivateKey: chain33Config.PrivateKey, PrivateKey: chain33Config.PrivateKey,
} }
logger.Info("=========privateKey======",chain33Config.PrivateKey)
m := make(map[string]*pb.Interchain) m := make(map[string]*pb.Interchain)
//if err := json.Unmarshal(extra, &m); err != nil { //if err := json.Unmarshal(extra, &m); err != nil {
// return fmt.Errorf("unmarshal extra for plugin :%w", err) // return fmt.Errorf("unmarshal extra for plugin :%w", err)
...@@ -167,6 +167,13 @@ func (c *Client) polling() { ...@@ -167,6 +167,13 @@ func (c *Client) polling() {
// SourceInterchainCounter: make(map[string]uint64), // SourceInterchainCounter: make(map[string]uint64),
SourceReceiptCounter: make(map[string]uint64), SourceReceiptCounter: make(map[string]uint64),
} }
//FIXME 临时修复无法从本地DB加载处理日志的bug
callBackMeta,err:=c.GetCallbackMeta()
if err !=nil {
logger.Error("get callback meta",
"error", err.Error())
}
meta.InterchainCounter[dstChainServiceID]=callBackMeta[servicePair]
c.serviceMeta[srcChainServiceID] = meta c.serviceMeta[srcChainServiceID] = meta
} }
...@@ -254,7 +261,14 @@ func (c *Client) SubmitIBTP(ibtp *pb.IBTP) (*pb.SubmitIBTPResponse, error) { ...@@ -254,7 +261,14 @@ func (c *Client) SubmitIBTP(ibtp *pb.IBTP) (*pb.SubmitIBTPResponse, error) {
if err := content.Unmarshal(pd.Content); err != nil { if err := content.Unmarshal(pd.Content); err != nil {
return ret, fmt.Errorf("ibtp content unmarshal: %w", err) return ret, fmt.Errorf("ibtp content unmarshal: %w", err)
} }
var args string
var argscb string
for _,by :=range content.Args{
args=fmt.Sprintf("%s,%s",args,string(by))
}
for _,by :=range content.ArgsCb{
argscb=fmt.Sprintf("%s,%s",argscb,string(by))
}
if ibtp.Category() == pb.IBTP_UNKNOWN { if ibtp.Category() == pb.IBTP_UNKNOWN {
return nil, fmt.Errorf("invalid ibtp category") return nil, fmt.Errorf("invalid ibtp category")
} }
...@@ -264,14 +278,8 @@ func (c *Client) SubmitIBTP(ibtp *pb.IBTP) (*pb.SubmitIBTPResponse, error) { ...@@ -264,14 +278,8 @@ func (c *Client) SubmitIBTP(ibtp *pb.IBTP) (*pb.SubmitIBTPResponse, error) {
serviceID string serviceID string
srcChainServiceID string srcChainServiceID string
) )
srcChainServiceID = ibtp.From
if ibtp.Category() == pb.IBTP_REQUEST { _, _, serviceID, err = parseChainServiceID(ibtp.To)
srcChainServiceID = ibtp.From
_, _, serviceID, err = parseChainServiceID(ibtp.To)
} else {
srcChainServiceID = ibtp.To
_, _, serviceID, err = parseChainServiceID(ibtp.From)
}
if ibtp.Category() == pb.IBTP_RESPONSE && content.Func == "" { if ibtp.Category() == pb.IBTP_RESPONSE && content.Func == "" {
// 响应类型处理 // 响应类型处理
...@@ -327,18 +335,19 @@ func (c *Client) SubmitIBTP(ibtp *pb.IBTP) (*pb.SubmitIBTPResponse, error) { ...@@ -327,18 +335,19 @@ func (c *Client) SubmitIBTP(ibtp *pb.IBTP) (*pb.SubmitIBTPResponse, error) {
if ibtp.Category() == pb.IBTP_RESPONSE { if ibtp.Category() == pb.IBTP_RESPONSE {
return ret, nil return ret, nil
} }
logger.Info("SubmitIBTP", "ibtp", ibtp.ID(),"resp",chResp)
proof, err := c.getProof(chResp) //FIXME 暂时去掉获取证明
if err != nil { //proof, err := c.getProof(chResp)
return ret, err //if err != nil {
} // return ret, err
//}
ret.Result, err = c.generateCallback(ibtp, result, ret.Status) ret.Result, err = c.generateCallback(ibtp, result, ret.Status)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ret.Result.Proof = proof ret.Result.Proof = nil
return ret, nil return ret, nil
} }
...@@ -544,18 +553,7 @@ func (c *Client) GetSrcRollbackMeta() (map[string]uint64, error) { ...@@ -544,18 +553,7 @@ func (c *Client) GetSrcRollbackMeta() (map[string]uint64, error) {
// TODO 未实现 // TODO 未实现
func (c *Client) GetDstRollbackMeta() (map[string]uint64, error) { func (c *Client) GetDstRollbackMeta() (map[string]uint64, error) {
//request := channel.Request{
// ChaincodeID: c.meta.CCID,
// Fcn: GetDstRollbackMeta,
//}
//
//var response channel.Response
//response, err := c.consumer.ChannelClient.Execute(request)
//if err != nil {
// return nil, err
//}
// return c.unpackMap(response)
return nil, nil return nil, nil
} }
......
...@@ -20,7 +20,7 @@ type Chain33 struct { ...@@ -20,7 +20,7 @@ type Chain33 struct {
Addr string `toml:"addr" json:"addr"` Addr string `toml:"addr" json:"addr"`
Name string `toml:"name" json:"name"` Name string `toml:"name" json:"name"`
EventFilter string `mapstructure:"event_filter" toml:"event_filter" json:"event_filter"` EventFilter string `mapstructure:"event_filter" toml:"event_filter" json:"event_filter"`
PrivateKey string `toml:"private_key" json:"private_key"` PrivateKey string `mapstructure:"private_key" toml:"private_key" json:"private_key"`
TimeoutHeight int64 `mapstructure:"timeout_height" json:"timeout_height"` TimeoutHeight int64 `mapstructure:"timeout_height" json:"timeout_height"`
ChainID string `mapstructure:"chain_id" json:"chain_id"` ChainID string `mapstructure:"chain_id" json:"chain_id"`
} }
......
[chain33] [chain33]
addr = "host.docker.internal:8801" #chain33的json rpc 服务地址
addr = "http://localhost:8901"
#可有可无,暂时没用到
event_filter = "interchain-event-name" event_filter = "interchain-event-name"
#username = "Admin" #跨链合约即chain33中执行器名称
ccid = "broker" ccid = "broker"
#channel_id = "mychannel" #用于跨链交易签名的私钥
#org = "org2" private_key= "cc38546e9e659d15e6b4893f0ab32a06d103931a8230b0bde71459d2b27d6944"
private_key= "xxxxxxxxxxxxxxxxx" #超时时间
timeout_height = 10 timeout_height = 10
#没用到
chain_id = "3" chain_id = "3"
#后续迭代版本中需要,现在暂时用不到
[[services]] [[services]]
id = "chain33&storage" id = "chain33&storage"
name = "storage" name = "storage"
#[[services]]
#id = "data_swapper"
#name = "data_swapper"
\ No newline at end of file
-----BEGIN CERTIFICATE-----
MIICKTCCAc+gAwIBAgIRAIBO31aZaSZoEYSy2AJuhJcwCgYIKoZIzj0EAwIwczEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh
Lm9yZzIuZXhhbXBsZS5jb20wHhcNMjAwMjA1MDgyMjAwWhcNMzAwMjAyMDgyMjAw
WjBqMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN
U2FuIEZyYW5jaXNjbzENMAsGA1UECxMEcGVlcjEfMB0GA1UEAxMWcGVlcjEub3Jn
Mi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABG3jszFPTbGm
dAYg2BxmHMTDKfQReNw3p9ttMK130qF5lQo5zLBG8Sa3viOCLnvjjg6A/P+yKnwv
isI/jEVE8T2jTTBLMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMCsGA1Ud
IwQkMCKAIMVL+daK7nMGr2/AQIXTSPFkdd3UiPVDkWtkh5ujnalEMAoGCCqGSM49
BAMCA0gAMEUCIQDMYOQiYeMiQZTxlRkj/3/jjYvwwdCcX5AWuFmraiHkugIgFkX/
6uiTSD0lz8P+wwlLf24cIABq2aZyi8q4gj0YfwA=
-----END CERTIFICATE-----
title = "Pier"
[port]
http = 44544
pprof = 44555
[log]
level = "debug"
dir = "logs"
filename = "pier.log"
report_caller = false
[mode]
type = "relay" # relay or direct
[mode.relay]
addr = "host.docker.internal:60011"
quorum = 2
validators = [
"0x000f1a7a08ccc48e5d30f80850cf1cf283aa3abd",
"0xe93b92f1da08f925bdee44e91e7768380ae83307",
"0xb18c8575e3284e79b92100025a31378feb8100d6",
"0x856E2B9A5FA82FD1B031D1FF6863864DBAC7995D",
]
[mode.direct]
peers = [
#"/ip4/host.docker.internal/tcp/4002/p2p/Qmf4fn6sT3yLh3uqJnJ453yAhzpccbCQ75XfnBURTD3NoR",
"/ip4/host.docker.internal/tcp/4003/p2p/QmS78YUNXbxjaKivSygyDkxjZXedYy4TF6vfAJRPMRYdZ8",
"/ip4/host.docker.internal/tcp/4004/p2p/QmZpeCcBQBaurf8SUEvxjRY1nLYAHHUzqWLEXd4uoiuE9K"
]
[appchain]
plugin = "fabric-client-1.4"
config = "fabric"
This diff is collapsed.
module github.com/meshplus/broker
go 1.13
require (
github.com/Knetic/govaluate v3.0.0+incompatible // indirect
github.com/Shopify/sarama v1.29.1 // indirect
github.com/fsouza/go-dockerclient v1.7.3 // indirect
github.com/golang/protobuf v1.5.2
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/hashicorp/go-version v1.3.0 // indirect
github.com/hyperledger/fabric v1.4.3
github.com/hyperledger/fabric-amcl v0.0.0-20210603140002-2670f91851c8 // indirect
github.com/miekg/pkcs11 v1.0.3 // indirect
github.com/onsi/gomega v1.14.0 // indirect
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect
github.com/spf13/viper v1.8.1 // indirect
github.com/sykesm/zap-logfmt v0.0.4 // indirect
go.uber.org/zap v1.18.1 // indirect
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
google.golang.org/grpc v1.39.0 // indirect
)
replace github.com/golang/protobuf => github.com/golang/protobuf v1.3.2
This diff is collapsed.
package main
import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
type response struct {
OK bool `json:"ok"`
Message string `json:"message"`
Data []byte `json:"data"`
}
func successResponse(data []byte) pb.Response {
res := &response{
OK: true,
Data: data,
}
data, err := json.Marshal(res)
if err != nil {
panic(err)
}
return shim.Success(data)
}
func errorResponse(msg string) pb.Response {
res := &response{
OK: false,
Message: msg,
}
data, err := json.Marshal(res)
if err != nil {
panic(err)
}
return shim.Error(string(data))
}
// putMap for persisting meta state into ledger
func (broker *Broker) putMap(stub shim.ChaincodeStubInterface, metaName string, meta map[string]uint64) error {
if meta == nil {
return nil
}
metaBytes, err := json.Marshal(meta)
if err != nil {
return err
}
return stub.PutState(metaName, metaBytes)
}
func (broker *Broker) getMap(stub shim.ChaincodeStubInterface, metaName string) (map[string]uint64, error) {
metaBytes, err := stub.GetState(metaName)
if err != nil {
return nil, err
}
meta := make(map[string]uint64)
if metaBytes == nil {
return meta, nil
}
if err := json.Unmarshal(metaBytes, &meta); err != nil {
return nil, err
}
return meta, nil
}
func getChaincodeID(stub shim.ChaincodeStubInterface) (string, error) {
sp, err := stub.GetSignedProposal()
if err != nil {
return "", err
}
proposal := &pb.Proposal{}
if err := proto.Unmarshal(sp.ProposalBytes, proposal); err != nil {
return "", err
}
payload := &pb.ChaincodeProposalPayload{}
if err := proto.Unmarshal(proposal.Payload, payload); err != nil {
return "", err
}
spec := &pb.ChaincodeInvocationSpec{}
if err := proto.Unmarshal(payload.Input, spec); err != nil {
return "", err
}
return getKey(stub.GetChannelID(), spec.ChaincodeSpec.ChaincodeId.Name), nil
}
func getKey(channel, chaincodeName string) string {
return channel + delimiter + chaincodeName
}
func (broker *Broker) checkIndex(stub shim.ChaincodeStubInterface, addr string, index string, metaName string) error {
idx, err := strconv.ParseUint(index, 10, 64)
if err != nil {
return err
}
meta, err := broker.getMap(stub, metaName)
if err != nil {
return err
}
if idx != meta[addr]+1 {
return fmt.Errorf("incorrect index, expect %d", meta[addr]+1)
}
return nil
}
func (broker *Broker) outMsgKey(to string, idx string) string {
return fmt.Sprintf("out-msg-%s-%s", to, idx)
}
func (broker *Broker) inMsgKey(from string, idx string) string {
return fmt.Sprintf("in-msg-%s-%s", from, idx)
}
func (broker *Broker) onlyAdmin(stub shim.ChaincodeStubInterface) bool {
key, err := getChaincodeID(stub)
if err != nil {
fmt.Printf("Get cert public key %s\n", err.Error())
return false
}
adminList, err := broker.getMap(stub, adminList)
if err != nil {
fmt.Println("Get admin list info failed")
return false
}
if adminList[key] == 1 {
return false
}
return true
}
func (broker *Broker) onlyWhitelist(stub shim.ChaincodeStubInterface) bool {
key, err := getChaincodeID(stub)
if err != nil {
fmt.Printf("Get cert public key %s\n", err.Error())
return false
}
whiteList, err := broker.getMap(stub, whiteList)
if err != nil {
fmt.Println("Get white list info failed")
return false
}
if whiteList[key] != 1 {
return false
}
return true
}
func (broker *Broker) getList(stub shim.ChaincodeStubInterface) pb.Response {
whiteList, err := broker.getMap(stub, whiteList)
if err != nil {
return shim.Error(fmt.Sprintf("Get white list :%s", err.Error()))
}
var list [][]byte
for k, v := range whiteList {
if v == 0 {
list = append(list, []byte(k))
}
}
return shim.Success(bytes.Join(list, []byte(",")))
}
func (broker *Broker) checkAdmin(stub shim.ChaincodeStubInterface, function string) bool {
checks := map[string]struct{}{
"audit": {},
"invokeInterchain": {},
"invokeIndexUpdate": {},
}
if _, ok := checks[function]; !ok {
return true
}
return broker.onlyAdmin(stub)
}
func (broker *Broker) checkWhitelist(stub shim.ChaincodeStubInterface, function string) bool {
checks := map[string]struct{}{
"EmitInterchainEvent": {},
}
if _, ok := checks[function]; !ok {
return true
}
return broker.onlyWhitelist(stub)
}
package main
import (
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
// getOutMeta
func (broker *Broker) getOuterMeta(stub shim.ChaincodeStubInterface) pb.Response {
v, err := stub.GetState(outterMeta)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(v)
}
// getOutMessage to,index
func (broker *Broker) getOutMessage(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) < 2 {
return shim.Error("incorrect number of arguments, expecting 2")
}
destChainMethod := args[0]
sequenceNum := args[1]
key := broker.outMsgKey(destChainMethod, sequenceNum)
v, err := stub.GetState(key)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(v)
}
func (broker *Broker) getInnerMeta(stub shim.ChaincodeStubInterface) pb.Response {
v, err := stub.GetState(innerMeta)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(v)
}
// getInMessage from,index
func (broker *Broker) getInMessage(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) < 2 {
return shim.Error("incorrect number of arguments, expecting 2")
}
inServicePair := args[0]
sequenceNum := args[1]
key := broker.inMsgKey(inServicePair, sequenceNum)
v, err := stub.GetState(key)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(v)
}
func (broker *Broker) getCallbackMeta(stub shim.ChaincodeStubInterface) pb.Response {
v, err := stub.GetState(callbackMeta)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(v)
}
func (broker *Broker) getDstRollbackMeta(stub shim.ChaincodeStubInterface) pb.Response {
v, err := stub.GetState(dstRollbackMeta)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(v)
}
func (broker *Broker) markInCounter(stub shim.ChaincodeStubInterface, from string) error {
inMeta, err := broker.getMap(stub, innerMeta)
if err != nil {
return err
}
inMeta[from]++
return broker.putMap(stub, innerMeta, inMeta)
}
func (broker *Broker) markCallbackCounter(stub shim.ChaincodeStubInterface, from string, index uint64) error {
meta, err := broker.getMap(stub, callbackMeta)
if err != nil {
return err
}
meta[from] = index
return broker.putMap(stub, callbackMeta, meta)
}
func (broker *Broker) markDstRollbackCounter(stub shim.ChaincodeStubInterface, from string, index uint64) error {
meta, err := broker.getMap(stub, dstRollbackMeta)
if err != nil {
return err
}
meta[from] = index
return broker.putMap(stub, dstRollbackMeta, meta)
}
package main
import (
"fmt"
"strings"
"github.com/hyperledger/fabric/common/util"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
const (
channelID = "mychannel"
brokerContractName = "broker"
emitInterchainEventFunc = "EmitInterchainEvent"
)
type DataSwapper struct{}
func (s *DataSwapper) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success(nil)
}
func (s *DataSwapper) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
function, args := stub.GetFunctionAndParameters()
fmt.Printf("invoke: %s\n", function)
switch function {
case "register":
return s.register(stub)
case "interchainGet":
return s.interchainGet(stub, args)
case "interchainSet":
return s.interchainSet(stub, args)
case "get":
return s.get(stub, args)
case "set":
return s.set(stub, args)
default:
return shim.Error("invalid function: " + function + ", args: " + strings.Join(args, ","))
}
}
func (s *DataSwapper) register(stub shim.ChaincodeStubInterface) pb.Response {
args := util.ToChaincodeArgs("register")
response := stub.InvokeChaincode(brokerContractName, args, channelID)
if response.Status != shim.OK {
return shim.Error(fmt.Sprintf("invoke chaincode '%s' err: %s", brokerContractName, response.Message))
}
return response
}
// get is business function which will invoke the to,tid,id
func (s *DataSwapper) get(stub shim.ChaincodeStubInterface, args []string) pb.Response {
switch len(args) {
case 1:
// args[0]: key
value, err := stub.GetState(args[0])
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(value)
case 2:
// args[0]: destination service id
// args[1]: key
b := util.ToChaincodeArgs(emitInterchainEventFunc, args[0], "interchainGet,interchainSet,", args[1], args[1], "")
response := stub.InvokeChaincode(brokerContractName, b, channelID)
if response.Status != shim.OK {
return shim.Error(fmt.Errorf("invoke broker chaincode %s error: %s", brokerContractName, response.Message).Error())
}
return shim.Success(nil)
default:
return shim.Error("incorrect number of arguments")
}
}
// get is business function which will invoke the to,tid,id
func (s *DataSwapper) set(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) != 2 {
return shim.Error("incorrect number of arguments")
}
err := stub.PutState(args[0], []byte(args[1]))
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
// interchainSet is the callback function getting data by interchain
func (s *DataSwapper) interchainSet(stub shim.ChaincodeStubInterface, args []string) pb.Response {
return s.set(stub, args)
}
// interchainGet gets data by interchain
func (s *DataSwapper) interchainGet(stub shim.ChaincodeStubInterface, args []string) pb.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(DataSwapper))
if err != nil {
fmt.Printf("Error starting chaincode: %s", err)
}
}
module github.com/meshplus/data_swapper
go 1.13
require (
github.com/Knetic/govaluate v3.0.0+incompatible // indirect
github.com/Shopify/sarama v1.29.1 // indirect
github.com/fsouza/go-dockerclient v1.7.3 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/hashicorp/go-version v1.3.0 // indirect
github.com/hyperledger/fabric v1.4.3
github.com/hyperledger/fabric-amcl v0.0.0-20210603140002-2670f91851c8 // indirect
github.com/miekg/pkcs11 v1.0.3 // indirect
github.com/onsi/gomega v1.14.0 // indirect
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect
github.com/spf13/viper v1.8.1 // indirect
github.com/sykesm/zap-logfmt v0.0.4 // indirect
go.uber.org/zap v1.18.1 // indirect
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
google.golang.org/grpc v1.39.0 // indirect
)
replace github.com/golang/protobuf => github.com/golang/protobuf v1.3.2
This diff is collapsed.
module github.com/meshplus/transfer
go 1.13
require (
github.com/Knetic/govaluate v3.0.0+incompatible // indirect
github.com/Shopify/sarama v1.29.1 // indirect
github.com/fsouza/go-dockerclient v1.7.3 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/hashicorp/go-version v1.3.0 // indirect
github.com/hyperledger/fabric v1.4.3
github.com/hyperledger/fabric-amcl v0.0.0-20210603140002-2670f91851c8 // indirect
github.com/miekg/pkcs11 v1.0.3 // indirect
github.com/onsi/gomega v1.14.0 // indirect
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect
github.com/spf13/viper v1.8.1 // indirect
github.com/sykesm/zap-logfmt v0.0.4 // indirect
go.uber.org/zap v1.18.1 // indirect
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
google.golang.org/grpc v1.39.0 // indirect
)
replace github.com/golang/protobuf => github.com/golang/protobuf v1.3.2
This diff is collapsed.
package main
import (
"fmt"
"strconv"
"github.com/hyperledger/fabric/core/chaincode/shim"
)
func getUint64(stub shim.ChaincodeStubInterface, key string) (uint64, error) {
value, err := stub.GetState(key)
if err != nil {
return 0, err
}
ret, err := strconv.ParseUint(string(value), 10, 64)
if err != nil {
return 0, err
}
return ret, nil
}
func getAmountArg(arg string) (uint64, error) {
amount, err := strconv.ParseUint(arg, 10, 64)
if err != nil {
shim.Error(fmt.Errorf("amount must be an interger %w", err).Error())
return 0, err
}
if amount < 0 {
return 0, fmt.Errorf("amount must be a positive integer, got %s", arg)
}
return amount, nil
}
package main
import (
"fmt"
"strconv"
"strings"
"github.com/hyperledger/fabric/common/util"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
const (
channelID = "mychannel"
brokerContractName = "broker"
emitInterchainEventFunc = "EmitInterchainEvent"
)
type Transfer struct{}
func (t *Transfer) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success(nil)
}
func (t *Transfer) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
function, args := stub.GetFunctionAndParameters()
fmt.Printf("invoke: %s\n", function)
switch function {
case "register":
return t.register(stub)
case "transfer":
return t.transfer(stub, args)
case "getBalance":
return t.getBalance(stub, args)
case "setBalance":
return t.setBalance(stub, args)
case "interchainCharge":
return t.interchainCharge(stub, args)
case "interchainRollback":
return t.interchainRollback(stub, args)
default:
return shim.Error("invalid function: " + function + ", args: " + strings.Join(args, ","))
}
}
func (t *Transfer) register(stub shim.ChaincodeStubInterface) pb.Response {
args := util.ToChaincodeArgs("register")
response := stub.InvokeChaincode(brokerContractName, args, channelID)
if response.Status != shim.OK {
return shim.Error(fmt.Sprintf("invoke chaincode '%s' err: %s", brokerContractName, response.Message))
}
return response
}
func (t *Transfer) transfer(stub shim.ChaincodeStubInterface, args []string) pb.Response {
switch len(args) {
case 3:
sender := args[0]
receiver := args[1]
amountArg := args[2]
amount, err := getAmountArg(amountArg)
if err != nil {
return shim.Error(fmt.Errorf("get amount from arg: %w", err).Error())
}
balance, err := getUint64(stub, sender)
if err != nil {
return shim.Error(fmt.Errorf("got account value from %s %w", sender, err).Error())
}
if balance < amount {
return shim.Error("not sufficient funds")
}
balance -= amount
err = stub.PutState(sender, []byte(strconv.FormatUint(balance, 10)))
if err != nil {
return shim.Error(err.Error())
}
receiverBalance, err := getUint64(stub, receiver)
if err != nil {
return shim.Error(fmt.Errorf("got account value from %s %w", receiver, err).Error())
}
err = stub.PutState(receiver, []byte(strconv.FormatUint(receiverBalance+amount, 10)))
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
case 4:
dstServiceID := args[0]
sender := args[1]
receiver := args[2]
amountArg := args[3]
amount, err := getAmountArg(amountArg)
if err != nil {
return shim.Error(fmt.Errorf("get amount from arg: %w", err).Error())
}
balance, err := getUint64(stub, sender)
if err != nil {
return shim.Error(fmt.Errorf("got account value from %s %w", sender, err).Error())
}
if balance < amount {
return shim.Error("not sufficient funds")
}
balance -= amount
err = stub.PutState(sender, []byte(strconv.FormatUint(balance, 10)))
if err != nil {
return shim.Error(err.Error())
}
args := strings.Join([]string{sender, receiver, amountArg, "false"}, ",")
argsRb := strings.Join([]string{sender, amountArg}, ",")
b := util.ToChaincodeArgs(emitInterchainEventFunc, dstServiceID, "interchainCharge,,interchainRollback", args, "", argsRb)
response := stub.InvokeChaincode(brokerContractName, b, channelID)
if response.Status != shim.OK {
return shim.Error(fmt.Errorf("invoke broker chaincode %s", response.Message).Error())
}
return shim.Success(nil)
default:
return shim.Error(fmt.Sprintf("incorrect number of arguments %d", len(args)))
}
}
// getBalance gets account balance
func (t *Transfer) getBalance(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) != 1 {
return shim.Error("incorrect number of arguments")
}
name := args[0]
value, err := stub.GetState(name)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(value)
}
// setBalance sets account balance
func (t *Transfer) setBalance(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) != 2 {
return shim.Error("incorrect number of arguments")
}
name := args[0]
amount := args[1]
if err := stub.PutState(name, []byte(amount)); err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
// charge user,amount
func (t *Transfer) interchainCharge(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) != 4 {
return shim.Error("incorrect number of arguments, expect 3")
}
sender := args[0]
receiver := args[1]
amountArg := args[2]
isRollback := args[3]
// check for sender info
if sender == "" {
return shim.Error("incorrect sender info")
}
amount, err := getAmountArg(amountArg)
if err != nil {
return shim.Error(fmt.Errorf("get amount from arg: %w", err).Error())
}
balance, err := getUint64(stub, receiver)
if err != nil {
return shim.Error(fmt.Errorf("get balancee from %s %w", receiver, err).Error())
}
// TODO: deal with rollback failure (balance not enough)
if isRollback == "true" {
balance -= amount
} else {
balance += amount
}
err = stub.PutState(receiver, []byte(strconv.FormatUint(balance, 10)))
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
func (t *Transfer) interchainRollback(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) != 2 {
return shim.Error("incorrect number of arguments, expecting 2")
}
name := args[0]
amountArg := args[1]
amount, err := getAmountArg(amountArg)
if err != nil {
return shim.Error(fmt.Errorf("get amount from arg: %w", err).Error())
}
balance, err := getUint64(stub, name)
if err != nil {
return shim.Error(fmt.Errorf("get balancee from %s %w", name, err).Error())
}
balance += amount
err = stub.PutState(name, []byte(strconv.FormatUint(balance, 10)))
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
func main() {
err := shim.Start(new(Transfer))
if err != nil {
fmt.Printf("Error starting chaincode: %s", err)
}
}
...@@ -8,8 +8,8 @@ require ( ...@@ -8,8 +8,8 @@ require (
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd
github.com/hashicorp/go-plugin v1.3.0 github.com/hashicorp/go-plugin v1.3.0
github.com/spf13/viper v1.7.0 github.com/spf13/viper v1.7.0
gitlab.33.cn/link33/chain33-sdk-go v0.0.0-20211115064655-8b3cd52918d4 gitlab.33.cn/link33/chain33-sdk-go v0.0.0-20211208090718-d6e59899ef37
gitlab.33.cn/link33/sidecar v0.0.0-20211116030852-4818401c6673 gitlab.33.cn/link33/sidecar v0.0.0-20211207073608-752987b8d686
) )
replace ( replace (
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment