diff --git a/ecc_go/chaincode/enclave_go/enclave.go b/ecc_go/chaincode/enclave_go/enclave.go index 5d66680a8..a99663aca 100644 --- a/ecc_go/chaincode/enclave_go/enclave.go +++ b/ecc_go/chaincode/enclave_go/enclave.go @@ -18,6 +18,7 @@ import ( "github.com/hyperledger/fabric-private-chaincode/ecc_go/chaincode/enclave_go/attestation" "github.com/hyperledger/fabric-private-chaincode/internal/crypto" "github.com/hyperledger/fabric-private-chaincode/internal/protos" + pb "github.com/hyperledger/fabric-protos-go/peer" "github.com/hyperledger/fabric/bccsp" "github.com/hyperledger/fabric/bccsp/factory" "github.com/hyperledger/fabric/common/flogging" @@ -37,9 +38,10 @@ type EnclaveStub struct { hostParams *protos.HostParameters chaincodeParams *protos.CCParameters fabricCryptoProvider bccsp.BCCSP + newStubInterfaceFunc func(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) shim.ChaincodeStubInterface } -func NewEnclaveStub(cc shim.Chaincode) *EnclaveStub { +func NewEnclaveStub(cc shim.Chaincode, newStubInterfaceFunc func(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) shim.ChaincodeStubInterface) *EnclaveStub { if err := factory.InitFactories(nil); err != nil { panic(err) } @@ -49,6 +51,7 @@ func NewEnclaveStub(cc shim.Chaincode) *EnclaveStub { csp: crypto.GetDefaultCSP(), ccRef: cc, fabricCryptoProvider: cryptoProvider, + newStubInterfaceFunc: newStubInterfaceFunc, } } @@ -161,7 +164,8 @@ func (e *EnclaveStub) ChaincodeInvoke(stub shim.ChaincodeStubInterface, chaincod // Invoke chaincode // we wrap the stub with our FpcStubInterface - fpcStub := NewFpcStubInterface(stub, cleartextChaincodeRequest.GetInput(), rwset, e.ccKeys) + fpcStub := e.newStubInterfaceFunc(stub, cleartextChaincodeRequest.GetInput(), rwset, e.ccKeys) + // fpcStub := NewFpcStubInterface(stub, cleartextChaincodeRequest.GetInput(), rwset, e.ccKeys) ccResponse := e.ccRef.Invoke(fpcStub) // marshal chaincode response diff --git a/ecc_go/chaincode/enclave_go/shim.go b/ecc_go/chaincode/enclave_go/shim.go index 308965a92..f0bf979b6 100644 --- a/ecc_go/chaincode/enclave_go/shim.go +++ b/ecc_go/chaincode/enclave_go/shim.go @@ -21,7 +21,7 @@ type FpcStubInterface struct { sep StateEncryptionFunctions } -func NewFpcStubInterface(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) *FpcStubInterface { +func NewFpcStubInterface(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) shim.ChaincodeStubInterface { return &FpcStubInterface{ stub: stub, input: input, diff --git a/ecc_go/chaincode/enclave_go/skvs_stub_Interface.go b/ecc_go/chaincode/enclave_go/skvs_stub_Interface.go new file mode 100644 index 000000000..6a41acef5 --- /dev/null +++ b/ecc_go/chaincode/enclave_go/skvs_stub_Interface.go @@ -0,0 +1,102 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package enclave_go + +import ( + "encoding/json" + + "github.com/hyperledger/fabric-chaincode-go/shim" + pb "github.com/hyperledger/fabric-protos-go/peer" + "github.com/pkg/errors" +) + +type SkvsStubInterface struct { + *FpcStubInterface + allDataOld map[string][]byte + allDataNew map[string][]byte + key string +} + +func NewSkvsStubInterface(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) shim.ChaincodeStubInterface { + logger.Debugf("===== Creating New Skvs Interface =====") + fpcStub := NewFpcStubInterface(stub, input, rwset, sep) + skvsStub := SkvsStubInterface{fpcStub.(*FpcStubInterface), map[string][]byte{}, map[string][]byte{}, "SKVS"} + err := skvsStub.InitSKVS() + if err != nil { + logger.Warningf("Error!! Initializing SKVS failed") + } + return &skvsStub +} + +func (s *SkvsStubInterface) InitSKVS() error { + // get current state, this will only operate once + encValue, err := s.GetPublicState(s.key) + if err != nil { + return nil + } + + if len(encValue) == 0 { + logger.Debugf("SKVS is empty, Initiating.") + } else { + value, err := s.sep.DecryptState(encValue) + if err != nil { + return err + } + logger.Debugf("SKVS has default value, loading current value.") + + err = json.Unmarshal(value, &s.allDataOld) + err = json.Unmarshal(value, &s.allDataNew) + if err != nil { + logger.Errorf("SKVS Json unmarshal error: %s", err) + return err + } + } + return nil +} + +func (s *SkvsStubInterface) GetState(key string) ([]byte, error) { + value, found := s.allDataOld[key] + if found != true { + return nil, errors.New("skvs allDataOld key not found") + } + return value, nil +} + +func (s *SkvsStubInterface) PutState(key string, value []byte) error { + s.allDataNew[key] = value + byteAllData, err := json.Marshal(s.allDataNew) + if err != nil { + return err + } + encValue, err := s.sep.EncryptState(byteAllData) + if err != nil { + return err + } + + return s.PutPublicState(s.key, encValue) +} + +func (s *SkvsStubInterface) DelState(key string) error { + delete(s.allDataNew, key) + byteAllData, err := json.Marshal(s.allDataNew) + if err != nil { + return err + } + encValue, err := s.sep.EncryptState(byteAllData) + if err != nil { + return err + } + return s.PutPublicState(s.key, encValue) +} + +func (s *SkvsStubInterface) GetStateByRange(startKey string, endKey string) (shim.StateQueryIteratorInterface, error) { + panic("not implemented") // TODO: Implement +} + +func (s *SkvsStubInterface) GetStateByRangeWithPagination(startKey string, endKey string, pageSize int32, bookmark string) (shim.StateQueryIteratorInterface, *pb.QueryResponseMetadata, error) { + panic("not implemented") // TODO: Implement +} diff --git a/ecc_go/chaincode/private.go b/ecc_go/chaincode/private.go index d880cc474..fb3c02751 100644 --- a/ecc_go/chaincode/private.go +++ b/ecc_go/chaincode/private.go @@ -16,8 +16,9 @@ import ( // NewPrivateChaincode creates a new chaincode! This is for go support only!!! func NewPrivateChaincode(cc shim.Chaincode) *chaincode.EnclaveChaincode { + newStubInterfaceFunc := enclave_go.NewFpcStubInterface ecc := &chaincode.EnclaveChaincode{ - Enclave: enclave_go.NewEnclaveStub(cc), + Enclave: enclave_go.NewEnclaveStub(cc, newStubInterfaceFunc), Validator: endorsement.NewValidator(), Extractor: &chaincode.ExtractorImpl{}, Ercc: &ercc.StubImpl{}, diff --git a/ecc_go/chaincode/singleKVS.go b/ecc_go/chaincode/singleKVS.go new file mode 100644 index 000000000..3e6c87f32 --- /dev/null +++ b/ecc_go/chaincode/singleKVS.go @@ -0,0 +1,29 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package chaincode + +import ( + "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 logger = flogging.MustGetLogger("enclave_go") + +func NewSkvsChaincode(cc shim.Chaincode) *chaincode.EnclaveChaincode { + newStubInterfaceFunc := enclave_go.NewSkvsStubInterface + ecc := &chaincode.EnclaveChaincode{ + Enclave: enclave_go.NewEnclaveStub(cc, newStubInterfaceFunc), + Validator: endorsement.NewValidator(), + Extractor: &chaincode.ExtractorImpl{}, + Ercc: &ercc.StubImpl{}, + } + return ecc +} diff --git a/samples/chaincode/secret-keeper-go/main.go b/samples/chaincode/secret-keeper-go/main.go index a8f707f1b..ad10ae5b3 100644 --- a/samples/chaincode/secret-keeper-go/main.go +++ b/samples/chaincode/secret-keeper-go/main.go @@ -24,6 +24,7 @@ func main() { // create chaincode secretChaincode, _ := contractapi.NewChaincode(&chaincode.SecretKeeper{}) chaincode := fpc.NewPrivateChaincode(secretChaincode) + // chaincode := fpc.NewSkvsChaincode(secretChaincode) // start chaincode as a service server := &shim.ChaincodeServer{