Skip to content

Commit

Permalink
able to save into single key
Browse files Browse the repository at this point in the history
  • Loading branch information
chenchanglew committed Jun 11, 2024
1 parent de52035 commit dfad2c1
Show file tree
Hide file tree
Showing 4 changed files with 359 additions and 29 deletions.
110 changes: 110 additions & 0 deletions ecc_go/chaincode/enclave_go/skvs_stub.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package enclave_go

import (
"crypto/sha256"

"github.com/hyperledger/fabric-chaincode-go/shim"
"github.com/hyperledger/fabric-private-chaincode/internal/protos"
"github.com/hyperledger/fabric/protoutil"
"github.com/pkg/errors"
"google.golang.org/protobuf/proto"
)

type skvsStub struct {
*EnclaveStub
}

func NewSkvsStub(cc shim.Chaincode) *skvsStub {
enclaveStub := NewEnclaveStub(cc)
return &skvsStub{enclaveStub}
}

func (e *skvsStub) ChaincodeInvoke(stub shim.ChaincodeStubInterface, chaincodeRequestMessageBytes []byte) ([]byte, error) {
logger.Error("==== SKVS ChaincodeInvoke ====")

signedProposal, err := stub.GetSignedProposal()
if err != nil {
shim.Error(err.Error())
}

if err := e.verifySignedProposal(stub, chaincodeRequestMessageBytes); err != nil {
return nil, errors.Wrap(err, "signed proposal verification failed")
}

// unmarshal chaincodeRequest
chaincodeRequestMessage := &protos.ChaincodeRequestMessage{}
err = proto.Unmarshal(chaincodeRequestMessageBytes, chaincodeRequestMessage)
if err != nil {
return nil, err
}

// get key transport message including the encryption keys for request and response
keyTransportMessage, err := e.extractKeyTransportMessage(chaincodeRequestMessage)
if err != nil {
return nil, errors.Wrap(err, "cannot extract keyTransportMessage")
}

// decrypt request
cleartextChaincodeRequest, err := e.extractCleartextChaincodeRequest(chaincodeRequestMessage, keyTransportMessage)
if err != nil {
return nil, errors.Wrap(err, "cannot decrypt chaincode request")
}

// create a new instance of a FPC RWSet that we pass to the stub and later return with the response
rwset := NewReadWriteSet()

// Invoke chaincode
// we wrap the stub with our FpcStubInterface
// ** Implement our own FpcStubInterface
skvsStub := NewSkvsStubInterface(stub, cleartextChaincodeRequest.GetInput(), rwset, e.ccKeys)
ccResponse := e.ccRef.Invoke(skvsStub)
// **
// fpcStub := NewFpcStubInterface(stub, cleartextChaincodeRequest.GetInput(), rwset, e.ccKeys)
// ccResponse := e.ccRef.Invoke(fpcStub)

// marshal chaincode response
ccResponseBytes, err := protoutil.Marshal(&ccResponse)
if err != nil {
return nil, err
}

//encrypt response
encryptedResponse, err := e.csp.EncryptMessage(keyTransportMessage.GetResponseEncryptionKey(), ccResponseBytes)
if err != nil {
return nil, err
}

chaincodeRequestMessageHash := sha256.Sum256(chaincodeRequestMessageBytes)

response := &protos.ChaincodeResponseMessage{
EncryptedResponse: encryptedResponse,
FpcRwSet: rwset.ToFPCKVSet(),
EnclaveId: e.identity.GetEnclaveId(),
Proposal: signedProposal,
ChaincodeRequestMessageHash: chaincodeRequestMessageHash[:],
}

responseBytes, err := proto.Marshal(response)
if err != nil {
return nil, err
}

// create signature
sig, err := e.identity.Sign(responseBytes)
if err != nil {
return nil, err
}

signedResponse := &protos.SignedChaincodeResponseMessage{
ChaincodeResponseMessage: responseBytes,
Signature: sig,
}

return proto.Marshal(signedResponse)
}
108 changes: 108 additions & 0 deletions ecc_go/chaincode/enclave_go/skvs_stub_Interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package enclave_go

import (
"encoding/hex"
"encoding/json"

"github.com/hyperledger/fabric-chaincode-go/shim"
pb "github.com/hyperledger/fabric-protos-go/peer"
)

var SingleKey = "SingleKey"

type SkvsStubInterface struct {
*FpcStubInterface
}

func NewSkvsStubInterface(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) *SkvsStubInterface {
fpcStub := NewFpcStubInterface(stub, input, rwset, sep)
return &SkvsStubInterface{fpcStub}
}

func (s *SkvsStubInterface) GetState(key string) ([]byte, error) {
logger.Warningf("Calling Get State (Start), key = %s", key)
encValue, err := s.GetPublicState(SingleKey)
if err != nil {
return nil, err
}

// in case the key does not exist, return early
if len(encValue) == 0 {
logger.Warningf("Calling Get State (End), data empty return.")
return nil, nil
}

value, err := s.sep.DecryptState(encValue)
if err != nil {
return nil, err
}

// Create an interface{} value to hold the unmarshalled data
var allData map[string]string

// Unmarshal the JSON data into the interface{} value
err = json.Unmarshal(value, &allData)
if err != nil {
logger.Errorf("SKVS Json unmarshal error: %s", err)
return nil, err
}
logger.Warningf("Calling Get State (Mid), key = %s, decrypted done alldata = %s", key, allData)

targetHex := allData[key]
targetBytes, err := hex.DecodeString(targetHex)
logger.Warningf("Calling Get State (End), Target: %s, TargetBytes: %x, err: %s", targetHex, targetBytes, err)
return targetBytes, err
// return s.sep.DecryptState(encValue)
}

func (s *SkvsStubInterface) PutState(key string, value []byte) error {
logger.Warningf("Calling Put State (Start), key = %s, value = %x", key, value)
// grab all data from the state.
encAllValue, err := s.GetPublicState(SingleKey)
if err != nil {
return err
}
var allData map[string]string

if len(encAllValue) == 0 {
// current world state is empty
allData = map[string]string{}
} else {
allValue, err := s.sep.DecryptState(encAllValue)
if err != nil {
return err
}
// Unmarshal the JSON data into the interface{} value
err = json.Unmarshal(allValue, &allData)
if err != nil {
logger.Errorf("SKVS Json unmarshal error: %s", err)
return err
}
}
logger.Warningf("Calling Put State (Mid-1), decrypt succeed, allData = %s", allData)

valueHex := hex.EncodeToString(value)

allData[key] = valueHex
logger.Warningf("Calling Put State (Mid-2), add need data key = %s, valueHex = %s, allData = %s", key, valueHex, allData)

byteAllData, err := json.Marshal(allData)
if err != nil {
return err
}
logger.Warningf("Calling Put State (Mid-3), successfull marshal allData, byteAlldata = %x", byteAllData)

encValue, err := s.sep.EncryptState(byteAllData)
if err != nil {
return err
}
logger.Warningf("Calling Put State (End), put encValue %x", encValue)

return s.PutPublicState(SingleKey, encValue)
}
163 changes: 137 additions & 26 deletions ecc_go/chaincode/singleKVS.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,150 @@ SPDX-License-Identifier: Apache-2.0
package chaincode

import (
"fmt"

"github.com/hyperledger/fabric-chaincode-go/shim"
"github.com/hyperledger/fabric-private-chaincode/ecc/chaincode"
"github.com/hyperledger/fabric-private-chaincode/ecc/chaincode/ercc"
"github.com/hyperledger/fabric-private-chaincode/ecc_go/chaincode/enclave_go"
"github.com/hyperledger/fabric-private-chaincode/internal/endorsement"
"github.com/hyperledger/fabric/common/flogging"
)

var SingleKey = "SingleKey"
var logger = flogging.MustGetLogger("enclave_go")

type SKVSWrapper struct {
*chaincode.EnclaveChaincode
func NewSkvsChaincode(cc shim.Chaincode) *chaincode.EnclaveChaincode {
ecc := &chaincode.EnclaveChaincode{
Enclave: enclave_go.NewSkvsStub(cc),
Validator: endorsement.NewValidator(),
Extractor: &chaincode.ExtractorImpl{},
Ercc: &ercc.StubImpl{},
}
return ecc
}

type skvsStub struct {
shim.ChaincodeStubInterface
}
// type skvsStub struct {
// *enclave_go.EnclaveStub
// }

func (s *skvsStub) GetState(key string) ([]byte, error) {
fmt.Printf("Inside SKVS solution, GetState, key=%s\n", key)
return s.ChaincodeStubInterface.GetState(SingleKey)
// return s.ChaincodeStubInterface.GetState(key)
}
// func NewSkvsStub(cc shim.Chaincode) *skvsStub {
// enclaveStub := enclave_go.NewEnclaveStub(cc)
// return &skvsStub{enclaveStub}
// }

func (s *skvsStub) PutState(key string, value []byte) error {
fmt.Printf("Inside SKVS solution, PutState, key=%s, value=%x\n", key, value)
return s.ChaincodeStubInterface.PutState(SingleKey, value)
// return s.ChaincodeStubInterface.PutState(key, value)
}
// func (e *skvsStub) ChaincodeInvoke(stub shim.ChaincodeStubInterface, chaincodeRequestMessageBytes []byte) ([]byte, error) {
// logger.Error("==== SKVS ChaincodeInvoke ====")

func (s *SKVSWrapper) GetStub() shim.ChaincodeStubInterface {
// get the original stub
stub := s.GetStub()
fmt.Println("Inside SKVS solution, GetStub")
// create a new stub with the overridden GetState() function
skvsStub := &skvsStub{stub}
return skvsStub
}
// signedProposal, err := stub.GetSignedProposal()
// if err != nil {
// shim.Error(err.Error())
// }

// if err := e.verifySignedProposal(stub, chaincodeRequestMessageBytes); err != nil {
// return nil, errors.Wrap(err, "signed proposal verification failed")
// }

// // unmarshal chaincodeRequest
// chaincodeRequestMessage := &protos.ChaincodeRequestMessage{}
// err = proto.Unmarshal(chaincodeRequestMessageBytes, chaincodeRequestMessage)
// if err != nil {
// return nil, err
// }

// // get key transport message including the encryption keys for request and response
// keyTransportMessage, err := e.extractKeyTransportMessage(chaincodeRequestMessage)
// if err != nil {
// return nil, errors.Wrap(err, "cannot extract keyTransportMessage")
// }

// // decrypt request
// cleartextChaincodeRequest, err := e.extractCleartextChaincodeRequest(chaincodeRequestMessage, keyTransportMessage)
// if err != nil {
// return nil, errors.Wrap(err, "cannot decrypt chaincode request")
// }

// // create a new instance of a FPC RWSet that we pass to the stub and later return with the response
// rwset := NewReadWriteSet()

// // Invoke chaincode
// // we wrap the stub with our FpcStubInterface
// // ** Implement our own FpcStubInterface
// skvsStub := NewSkvsStubInterface(stub, cleartextChaincodeRequest.GetInput(), rwset, e.ccKeys)
// ccResponse := e.ccRef.Invoke(skvsStub)
// // **
// // fpcStub := NewFpcStubInterface(stub, cleartextChaincodeRequest.GetInput(), rwset, e.ccKeys)
// // ccResponse := e.ccRef.Invoke(fpcStub)

// // marshal chaincode response
// ccResponseBytes, err := protoutil.Marshal(&ccResponse)
// if err != nil {
// return nil, err
// }

// //encrypt response
// encryptedResponse, err := e.csp.EncryptMessage(keyTransportMessage.GetResponseEncryptionKey(), ccResponseBytes)
// if err != nil {
// return nil, err
// }

// chaincodeRequestMessageHash := sha256.Sum256(chaincodeRequestMessageBytes)

// response := &protos.ChaincodeResponseMessage{
// EncryptedResponse: encryptedResponse,
// FpcRwSet: rwset.ToFPCKVSet(),
// EnclaveId: e.identity.GetEnclaveId(),
// Proposal: signedProposal,
// ChaincodeRequestMessageHash: chaincodeRequestMessageHash[:],
// }

// responseBytes, err := proto.Marshal(response)
// if err != nil {
// return nil, err
// }

// // create signature
// sig, err := e.identity.Sign(responseBytes)
// if err != nil {
// return nil, err
// }

// signedResponse := &protos.SignedChaincodeResponseMessage{
// ChaincodeResponseMessage: responseBytes,
// Signature: sig,
// }

// return proto.Marshal(signedResponse)
// }

// func (e *skvsStub) verifySignedProposal(stub shim.ChaincodeStubInterface, chaincodeRequestMessageBytes []byte) error {
// return e.EnclaveStub.verifySignedProposal(stub, chaincodeRequestMessageBytes)
// }

// type SkvsStubInterface struct {
// *enclave_go.FpcStubInterface
// }

// func NewSkvsStubInterface(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) *SkvsStubInterface {
// fpcStub := enclave_go.NewFpcStubInterface(stub, input, rwset, sep)
// return &SkvsStubInterface{fpcStub}
// }

// func (s *SkvsStubInterface) GetState(key string) ([]byte, error) {
// encValue, err := s.GetPublicState(SingleKey)
// if err != nil {
// return nil, err
// }

// // in case the key does not exist, return early
// if len(encValue) == 0 {
// return nil, nil
// }

// return s.sep.DecryptState(encValue)
// }

// func (s *SkvsStubInterface) PutState(key string, value []byte) error {
// encValue, err := s.sep.EncryptState(SingleKey)
// if err != nil {
// return err
// }
// return s.PutPublicState(key, encValue)
// }
Loading

0 comments on commit dfad2c1

Please sign in to comment.