Commit 67e83456 authored by zhourong's avatar zhourong

feat(*): use secp256k1 for signature verification

parent a8c148a3
......@@ -8,4 +8,7 @@ bin
cover.out
cover.html
coverage.txt
example/contracts/
\ No newline at end of file
/example/contracts/src/asset_exchange/vendor/
/example/contracts/src/broker/vendor/
/example/contracts/src/data_swapper/vendor/
/example/contracts/src/transfer/vendor/
No preview for this file type
This diff is collapsed.
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
}
if value == nil || string(value) == "" {
return 0, nil
}
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"
)
func (broker *Broker) interchainAssetExchangeInit(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) != 11 {
return errorResponse("incorrect number of arguments, expecting 11")
}
sourceChainID := args[0]
sequenceNum := args[1]
targetCID := args[2]
sourceCID := args[3]
assetExchangeId := args[4]
senderOnSrcChain := args[5]
receiverOnSrcChain := args[6]
assetOnSrcChain := args[7]
senderOnDstChain := args[8]
receiverOnDstChain := args[9]
assetOnDstChain := args[10]
if err := broker.checkIndex(stub, sourceChainID, sequenceNum, innerMeta); err != nil {
return errorResponse(err.Error())
}
if err := broker.markInCounter(stub, sourceChainID); err != nil {
return errorResponse(err.Error())
}
splitedCID := strings.Split(targetCID, delimiter)
if len(splitedCID) != 2 {
return errorResponse(fmt.Sprintf("Target chaincode id %s is not valid", targetCID))
}
b := util.ToChaincodeArgs(
"interchainAssetExchangeInit",
sourceChainID,
sourceCID,
assetExchangeId,
senderOnSrcChain,
receiverOnSrcChain,
assetOnSrcChain,
senderOnDstChain,
receiverOnDstChain,
assetOnDstChain)
response := stub.InvokeChaincode(splitedCID[1], b, splitedCID[0])
if response.Status != shim.OK {
return errorResponse(fmt.Sprintf("invoke chaincode '%s' err: %s", splitedCID[1], response.Message))
}
// persist execution result
key := broker.inMsgKey(sourceChainID, sequenceNum)
if err := stub.PutState(key, response.Payload); err != nil {
return errorResponse(err.Error())
}
return successResponse(nil)
}
func (broker *Broker) interchainAssetExchangeRedeem(stub shim.ChaincodeStubInterface, args []string) pb.Response {
return broker.interchainAssetExchangeFinish(stub, args, "1")
}
func (broker *Broker) interchainAssetExchangeRefund(stub shim.ChaincodeStubInterface, args []string) pb.Response {
return broker.interchainAssetExchangeFinish(stub, args, "2")
}
func (broker *Broker) interchainAssetExchangeFinish(stub shim.ChaincodeStubInterface, args []string, status string) pb.Response {
// check args
if len(args) != 5 {
return errorResponse("incorrect number of arguments, expecting 5")
}
sourceChainID := args[0]
sequenceNum := args[1]
targetCID := args[2]
assetExchangeId := args[3]
signatures := args[4]
if err := broker.checkIndex(stub, sourceChainID, sequenceNum, innerMeta); err != nil {
return errorResponse(err.Error())
}
if err := broker.markInCounter(stub, sourceChainID); err != nil {
return errorResponse(err.Error())
}
splitedCID := strings.Split(targetCID, delimiter)
if len(splitedCID) != 2 {
return errorResponse(fmt.Sprintf("Target chaincode id %s is not valid", targetCID))
}
b := util.ToChaincodeArgs("interchainAssetExchangeFinish", assetExchangeId, status, signatures)
response := stub.InvokeChaincode(splitedCID[1], b, splitedCID[0])
if response.Status != shim.OK {
return errorResponse(fmt.Sprintf("invoke chaincode '%s' err: %s", splitedCID[1], response.Message))
}
return successResponse(nil)
}
func (broker *Broker) interchainAssetExchangeConfirm(stub shim.ChaincodeStubInterface, args []string) pb.Response {
// check args
if len(args) != 5 {
return errorResponse("incorrect number of arguments, expecting 5")
}
sourceChainID := args[0]
sequenceNum := args[1]
targetCID := args[2]
assetExchangeId := args[3]
signatures := args[4]
if err := broker.checkIndex(stub, sourceChainID, sequenceNum, callbackMeta); err != nil {
return errorResponse(err.Error())
}
idx, err := strconv.ParseUint(sequenceNum, 10, 64)
if err != nil {
return errorResponse(err.Error())
}
if err := broker.markCallbackCounter(stub, sourceChainID, idx); err != nil {
return errorResponse(err.Error())
}
splitedCID := strings.Split(targetCID, delimiter)
if len(splitedCID) != 2 {
return errorResponse(fmt.Sprintf("Target chaincode id %s is not valid", targetCID))
}
b := util.ToChaincodeArgs("interchainAssetExchangeConfirm", assetExchangeId, signatures)
response := stub.InvokeChaincode(splitedCID[1], b, splitedCID[0])
if response.Status != shim.OK {
return errorResponse(fmt.Sprintf("invoke chaincode '%s' err: %s", splitedCID[1], response.Message))
}
return successResponse(nil)
}
This diff is collapsed.
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"
)
// get interchain account for transfer contract: setData from,index,tid,name_id,amount
func (broker *Broker) interchainSet(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) < 5 {
return errorResponse("incorrect number of arguments, expecting 5")
}
sourceChainID := args[0]
sequenceNum := args[1]
targetCID := args[2]
key := args[3]
data := args[4]
if err := broker.checkIndex(stub, sourceChainID, sequenceNum, callbackMeta); err != nil {
return errorResponse(err.Error())
}
idx, err := strconv.ParseUint(sequenceNum, 10, 64)
if err != nil {
return errorResponse(err.Error())
}
if err := broker.markCallbackCounter(stub, sourceChainID, idx); err != nil {
return errorResponse(err.Error())
}
splitedCID := strings.Split(targetCID, delimiter)
if len(splitedCID) != 2 {
return errorResponse(fmt.Sprintf("Target chaincode id %s is not valid", targetCID))
}
b := util.ToChaincodeArgs("interchainSet", key, data)
response := stub.InvokeChaincode(splitedCID[1], b, splitedCID[0])
if response.Status != shim.OK {
return errorResponse(fmt.Sprintf("invoke chaincode '%s' err: %s", splitedCID[1], response.Message))
}
return successResponse(nil)
}
// example for calling get: getData from,index,tid,id
func (broker *Broker) interchainGet(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) < 4 {
return errorResponse("incorrect number of arguments, expecting 4")
}
sourceChainID := args[0]
sequenceNum := args[1]
targetCID := args[2]
key := args[3]
if err := broker.checkIndex(stub, sourceChainID, sequenceNum, innerMeta); err != nil {
return errorResponse(err.Error())
}
if err := broker.markInCounter(stub, sourceChainID); err != nil {
return errorResponse(err.Error())
}
splitedCID := strings.Split(targetCID, delimiter)
if len(splitedCID) != 2 {
return errorResponse(fmt.Sprintf("Target chaincode id %s is not valid", targetCID))
}
b := util.ToChaincodeArgs("interchainGet", key)
response := stub.InvokeChaincode(splitedCID[1], b, splitedCID[0])
if response.Status != shim.OK {
return errorResponse(fmt.Sprintf("invoke chaincode '%s' err: %s", splitedCID[1], response.Message))
}
inKey := broker.inMsgKey(sourceChainID, sequenceNum)
if err := stub.PutState(inKey, response.Payload); err != nil {
return errorResponse(err.Error())
}
return successResponse(response.Payload)
}
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.Success(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": {},
"interchainCharge": {},
"interchainConfirm": {},
"interchainGet": {},
"interchainSet": {},
"interchainAssetExchangeInit": {},
"interchainAssetExchangeRedeem": {},
"interchainAssetExchangeRefund": {},
}
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{}{
"InterchainTransferInvoke": {},
"InterchainDataSwapInvoke": {},
"InterchainInvoke": {},
"InterchainAssetExchangeInitInvoke": {},
"InterchainAssetExchangeRedeemInvoke": {},
"InterchainAssetExchangeRefundInvoke": {},
}
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")
}
destChainID := args[0]
sequenceNum := args[1]
key := broker.outMsgKey(destChainID, 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")
}
sourceChainID := args[0]
sequenceNum := args[1]
key := broker.inMsgKey(sourceChainID, 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) 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)
}
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"
)
// recharge for transfer contract: charge from,index,tid,name_id,amount
func (broker *Broker) interchainCharge(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) < 6 {
return errorResponse("incorrect number of arguments, expecting 6")
}
sourceChainID := args[0]
sequenceNum := args[1]
targetCID := args[2]
sender := args[3]
receiver := args[4]
amount := args[5]
if err := broker.checkIndex(stub, sourceChainID, sequenceNum, innerMeta); err != nil {
return errorResponse(err.Error())
}
if err := broker.markInCounter(stub, sourceChainID); err != nil {
return errorResponse(err.Error())
}
splitedCID := strings.Split(targetCID, delimiter)
if len(splitedCID) != 2 {
return errorResponse(fmt.Sprintf("Target chaincode id %s is not valid", targetCID))
}
b := util.ToChaincodeArgs("interchainCharge", sender, receiver, amount)
response := stub.InvokeChaincode(splitedCID[1], b, splitedCID[0])
if response.Status != shim.OK {
return errorResponse(fmt.Sprintf("invoke chaincode '%s' err: %s", splitedCID[1], response.Message))
}
// persist execution result
key := broker.inMsgKey(sourceChainID, sequenceNum)
if err := stub.PutState(key, response.Payload); err != nil {
return errorResponse(err.Error())
}
return successResponse(nil)
}
func (broker *Broker) interchainConfirm(stub shim.ChaincodeStubInterface, args []string) pb.Response {
// check args
if len(args) < 6 {
return errorResponse("incorrect number of arguments, expecting 6")
}
sourceChainID := args[0]
sequenceNum := args[1]
targetCID := args[2]
status := args[3]
receiver := args[4]
amount := args[5]
if err := broker.checkIndex(stub, sourceChainID, sequenceNum, callbackMeta); err != nil {
return errorResponse(err.Error())
}
idx, err := strconv.ParseUint(sequenceNum, 10, 64)
if err != nil {
return errorResponse(err.Error())
}
if err := broker.markCallbackCounter(stub, sourceChainID, idx); err != nil {
return errorResponse(err.Error())
}
// confirm interchain tx execution
if status == "true" {
return successResponse(nil)
}
splitedCID := strings.Split(targetCID, delimiter)
if len(splitedCID) != 2 {
return errorResponse(fmt.Sprintf("Target chaincode id %s is not valid", targetCID))
}
b := util.ToChaincodeArgs("interchainRollback", receiver, amount)
response := stub.InvokeChaincode(splitedCID[1], b, splitedCID[0])
if response.Status != shim.OK {
return errorResponse(fmt.Sprintf("invoke chaincode '%s' err: %s", splitedCID[1], response.Message))
}
return successResponse(nil)
}
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"
interchainInvokeFunc = "InterchainDataSwapInvoke"
)
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 3:
// args[0]: destination appchain id
// args[1]: destination contract address
// args[2]: key
b := util.ToChaincodeArgs(interchainInvokeFunc, args[0], args[1], args[2])
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)
}
}
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"
interchainInvokeFunc = "InterchainTransferInvoke"
)
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 5:
// args[0]: destination appchain id
// args[1]: destination contract address
dest := args[0]
address := args[1]
sender := args[2]
receiver := args[3]
amountArg := args[4]
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())
}
b := util.ToChaincodeArgs(interchainInvokeFunc, dest, address, sender, receiver, amountArg)
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("incorrect number of arguments")
}
}
// 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) != 3 {
return shim.Error("incorrect number of arguments, expect 3")
}
sender := args[0]
receiver := args[1]
amountArg := args[2]
// 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())
}
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)
}
}
......@@ -5,7 +5,8 @@ go 1.13
require (
github.com/Rican7/retry v0.1.0
github.com/VividCortex/gohistogram v1.0.0 // indirect
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004
github.com/cloudflare/cfssl v0.0.0-20190409034051-768cd563887f
github.com/go-logfmt/logfmt v0.4.0 // indirect
github.com/golang/protobuf v1.4.0
github.com/google/certificate-transparency-go v1.1.0 // indirect
github.com/hashicorp/go-plugin v1.3.0
......@@ -14,11 +15,16 @@ require (
github.com/hyperledger/fabric-lib-go v1.0.0 // indirect
github.com/hyperledger/fabric-protos-go v0.0.0-20200330074707-cfe579e86986
github.com/hyperledger/fabric-sdk-go v1.0.0-alpha5
github.com/meshplus/bitxhub-kit v1.0.1-0.20200525112026-df2160653e23
github.com/meshplus/bitxhub-kit v1.0.1-0.20200813124031-6f6bdc99564f
github.com/meshplus/bitxhub-model v1.0.0-rc4.0.20200731025300-2bb1717059e0
github.com/meshplus/pier v1.0.0-rc1.0.20200717044435-de24cfbef0f3
github.com/meshplus/pier v1.1.0-rc1.0.20200824115625-bb57600455be
github.com/sirupsen/logrus v1.5.0
github.com/spf13/viper v1.6.1
sigs.k8s.io/yaml v1.2.0 // indirect
)
replace github.com/golang/protobuf => github.com/golang/protobuf v1.3.2
replace (
github.com/go-kit/kit => github.com/go-kit/kit v0.8.0
github.com/golang/protobuf => github.com/golang/protobuf v1.3.2
github.com/prometheus/client_golang => github.com/prometheus/client_golang v0.9.3
)
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