From 5653efad3cc717188595ba63e783da2bb7972a7f Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Tue, 25 Feb 2020 17:15:12 -0800 Subject: [PATCH 01/28] CouchDB Integrated --- .gitignore | 2 + Gopkg.toml | 5 + blockreader.go | 149 ++++++++++++++++++++++++ config.json | 12 ++ couchdb.go | 43 +++++++ download.sh | 16 +++ eventlistener.go | 297 +++++++++++++++++++++++++++++++++++++++++++++++ model.go | 9 ++ offchaindata.go | 36 ++++++ 9 files changed, 569 insertions(+) create mode 100644 .gitignore create mode 100755 Gopkg.toml create mode 100644 blockreader.go create mode 100644 config.json create mode 100644 couchdb.go create mode 100755 download.sh create mode 100644 eventlistener.go create mode 100644 model.go create mode 100644 offchaindata.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..987014e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +vendor +offchaindata diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100755 index 0000000..d4822f9 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,5 @@ +[[constraint]] + # Release v1.0.0-alpha4 + name = "github.com/hyperledger/fabric-sdk-go" + #revision = "a906355f73d060d7bf95874a9e90dc17589edbb3" + revision = "e00befbefdb6deb06b59a697c42e0f3147c91b7e" diff --git a/blockreader.go b/blockreader.go new file mode 100644 index 0000000..3df2bea --- /dev/null +++ b/blockreader.go @@ -0,0 +1,149 @@ +package main + +import ( + "fmt" + "encoding/json" + //"github.com/hyperledger/fabric-protos-go/peer" + "github.com/hyperledger/fabric/protos/common" + "github.com/hyperledger/fabric/protos/peer" + "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/ledger/rwset/kvrwset" + "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/ledger/rwset" + "github.com/golang/protobuf/proto" + "github.com/pkg/errors" +) + +func ReadBlock(block *common.Block) error{ + + blockData := block.Data.Data + + //First Get the Envelope from the BlockData + envelope, err := GetEnvelopeFromBlock(blockData[0]) + if err != nil { + return errors.WithMessage(err,"unmarshaling Envelope error: ") + } + + //Retrieve the Payload from the Envelope + payload := &common.Payload{} + err = proto.Unmarshal(envelope.Payload, payload) + if err != nil { + return errors.WithMessage(err,"unmarshaling Payload error: ") + } + + transaction := &peer.Transaction{} + err = proto.Unmarshal(payload.Data, transaction) + if err != nil { + return errors.WithMessage(err,"unmarshaling Payload Transaction error: ") + } + + chaincodeActionPayload := &peer.ChaincodeActionPayload{} + err = proto.Unmarshal(transaction.Actions[0].Payload, chaincodeActionPayload) + if err != nil { + return errors.WithMessage(err,"unmarshaling Chaincode Action Payload error: ") + } + + chaincodeProposalPayload := &peer.ChaincodeProposalPayload{} + err = proto.Unmarshal(chaincodeActionPayload.ChaincodeProposalPayload, chaincodeProposalPayload) + if err != nil { + return errors.WithMessage(err,"unmarshaling Chaincode Proposal Payload error: ") + } + + // The Input field is marshalled object of ChaincodeInvocationSpec + input := &peer.ChaincodeInvocationSpec{} + err = proto.Unmarshal(chaincodeProposalPayload.Input, input) + if err != nil { + return errors.WithMessage(err,"unmarshaling Chaincode Proposal Payload Input error: ") + } + + fmt.Println("Chaincode Name === "+input.ChaincodeSpec.ChaincodeId.Name) + + chaincodeArgs := make([]string, len(input.ChaincodeSpec.Input.Args)) + + for i, c := range input.ChaincodeSpec.Input.Args { + args := CToGoString(c[:]) + chaincodeArgs[i] = args + } + + fmt.Println("Chaicode Args = ", chaincodeArgs) + + proposalResponsePayload := &peer.ProposalResponsePayload{} + err = proto.Unmarshal(chaincodeActionPayload.Action.ProposalResponsePayload, proposalResponsePayload) + if err != nil { + return errors.WithMessage(err,"unmarshaling Proposal Response Payload error: ") + } + + chaincodeAction := &peer.ChaincodeAction{} + err = proto.Unmarshal(proposalResponsePayload.Extension, chaincodeAction) + if err != nil { + return errors.WithMessage(err,"unmarshaling Extension error: ") + } + + txReadWriteSet := &rwset.TxReadWriteSet{} + err = proto.Unmarshal(chaincodeAction.Results, txReadWriteSet) + if err != nil { + return errors.WithMessage(err,"unmarshaling txReadWriteSet error: ") + } + + RwSet := txReadWriteSet.NsRwset[0].Rwset + + kvrwset := &kvrwset.KVRWSet{} + err = proto.Unmarshal(RwSet, kvrwset) + if err != nil { + return errors.WithMessage(err,"unmarshaling kvrwset error: ") + } + + if len(kvrwset.Reads) != 0 { + + fmt.Println("BlockNum = ",kvrwset.Reads[0].Version.BlockNum) + fmt.Println("TxNum = ",kvrwset.Reads[0].Version.TxNum) + fmt.Println("KVRead Key = ",kvrwset.Reads[0].Key) + //fmt.Println("KVRead Value = ",kvrwset.Reads[0].Value) + } + + if len(kvrwset.Writes) != 0 { + + args := CToGoString(kvrwset.Writes[0].Value[:]) + + fmt.Println("KVWrite Key = ",kvrwset.Writes[0].Key) + fmt.Println("KVWrite Value = ",args) + + User := &SampleUser{} + err = json.Unmarshal(kvrwset.Writes[0].Value, User) + if err != nil{ + return errors.WithMessage(err,"unmarshaling write set error: ") + } + + fmt.Println("Email = "+User.Email) + fmt.Println("Name = "+User.Name) + fmt.Println("Age = "+User.Age) + fmt.Println("Country = "+User.Country) + + SaveToCouchDB(kvrwset.Writes[0].Value) + } + + + + return nil + +} + +func GetEnvelopeFromBlock(data []byte) (*common.Envelope, error){ + + var err error + env := &common.Envelope{} + if err = proto.Unmarshal(data, env); err != nil { + return nil, errors.Wrap(err, "error unmarshaling Envelope") + } + + return env, nil +} + +func CToGoString(c []byte) string { + n := -1 + for i, b := range c { + if b == 0 { + break + } + n = i + } + return string(c[:n+1]) +} \ No newline at end of file diff --git a/config.json b/config.json new file mode 100644 index 0000000..7a3ed13 --- /dev/null +++ b/config.json @@ -0,0 +1,12 @@ +{ + "fabric_cfg_path": "privacytracker/fixtures/crypto-config/peerOrganizations/", + "msp_id": "Org1MSP", + "msp_type": "bccsp", + "msp_config_dir": "org1.privacy.tracker.com/users/Admin@org1.privacy.tracker.com/msp", + "client_key": "org1.privacy.tracker.com/peers/peer0.org1.privacy.tracker.com/tls/server.key", + "client_cert": "org1.privacy.tracker.com/peers/peer0.org1.privacy.tracker.com/tls/server.crt", + "root_cert": "org1.privacy.tracker.com/peers/peer0.org1.privacy.tracker.com/tls/ca.crt", + "server": "peer0.org1.privacy.tracker.com:7051", + "channel_id": "privacytracker", + "config_file": "configtx" +} diff --git a/couchdb.go b/couchdb.go new file mode 100644 index 0000000..ffdf502 --- /dev/null +++ b/couchdb.go @@ -0,0 +1,43 @@ +package main + +import ( + "fmt" + "context" + "encoding/json" + kivik "github.com/go-kivik/kivik/v4" + _ "github.com/go-kivik/couchdb/v4" + "github.com/pkg/errors" +) + +func SaveToCouchDB(kvWriteSet []byte) error{ + + fmt.Println("Saving to CouchDB") + client, err := kivik.New("couch", "http://localhost:5990/") + + if err != nil { + fmt.Println("failed to set couchdb - "+err.Error()) + return errors.WithMessage(err,"failed to set couchdb: ") + } + + db := client.DB(context.TODO(), "offchaindb") + + /*if err != nil { + return errors.WithMessage(err,"failed to create database: ") + }*/ + + User := &SampleUser{} + err = json.Unmarshal(kvWriteSet, User) + if err != nil{ + return errors.WithMessage(err,"unmarshaling write set error: ") + } + + rev, err := db.Put(context.TODO(), User.Email, User) + if err != nil { + fmt.Println("user insertion error - "+err.Error()) + return errors.WithMessage(err,"user insertion error: ") + } + + fmt.Println("User Inserted into CouchDB %s ",rev) + + return nil +} \ No newline at end of file diff --git a/download.sh b/download.sh new file mode 100755 index 0000000..f8cf9fa --- /dev/null +++ b/download.sh @@ -0,0 +1,16 @@ +go get -v github.com/Shopify/sarama +go get -v github.com/hashicorp/go-version +go get -v github.com/onsi/ginkgo +go get -v github.com/onsi/gomega +go get -v github.com/spf13/cobra +go get -v github.com/syndtr/goleveldb/leveldb +go get -v github.com/syndtr/goleveldb/leveldb/iterator +go get -v github.com/syndtr/goleveldb/leveldb/opt +go get -v github.com/syndtr/goleveldb/leveldb/util +go get -v github.com/tedsuo/ifrit +go get -v github.com/willf/bitset +go get -v golang.org/x/sync/semaphore +<<<<<<< HEAD + +======= +>>>>>>> 30861862dfb5c84d3332f1502de8aa723bc95de6 diff --git a/eventlistener.go b/eventlistener.go new file mode 100644 index 0000000..c3e6053 --- /dev/null +++ b/eventlistener.go @@ -0,0 +1,297 @@ +package main + +import ( + "fmt" + "os" + "time" + "math" + "context" + "io/ioutil" + "encoding/json" + "google.golang.org/grpc" + "github.com/pkg/errors" + "github.com/hyperledger/fabric/common/util" + "github.com/hyperledger/fabric/common/crypto" + "github.com/hyperledger/fabric/common/localmsp" + "github.com/hyperledger/fabric/protos/peer" + "github.com/hyperledger/fabric/protos/orderer" + //"github.com/hyperledger/fabric/common/tools/protolator" + common2 "github.com/hyperledger/fabric/peer/common" + "github.com/hyperledger/fabric/protos/common" + "github.com/hyperledger/fabric/protos/utils" + "github.com/hyperledger/fabric/core/comm" +) + +type DeliveryClient interface { + Send(*common.Envelope) error + Recv() (*peer.DeliverResponse, error) +} + +type GRPCClient struct { + grpcClient *comm.GRPCClient + grpcClientConn *grpc.ClientConn + deliveryClient DeliveryClient + signer crypto.LocalSigner + tlsCertHash []byte +} + +var ( + fabric_cfg_path string + msp_id string + msp_type string + msp_config_dir string + client_key string + client_cert string + root_cert string + server string + channel_id string + config_file string +) + +const ( + ROOT = "/home/harald/go/src/github.com/" +) + +func InitClientConfigs() (comm.ClientConfig,error) { + + fmt.Println("Init Client Configs ") + + err := ReadConfigs() + if err != nil { + return comm.ClientConfig{}, errors.WithMessage(err, "failed to read config json") + } + + /* Initialize Config */ + err = common2.InitConfig(config_file) + if err != nil { + return comm.ClientConfig{}, errors.WithMessage(err, "fatal error when initializing config") + } + + fmt.Println("Init Config Successfully") + + /* Initialize Crypto */ + err = common2.InitCrypto(msp_config_dir, msp_id, msp_type) + if err != nil { + return comm.ClientConfig{}, errors.WithMessage(err, "Cannot run client because") + } + + fmt.Println("Init Crypto Successfully") + + /* Init Client Configs */ + clientConfig := comm.ClientConfig{ + KaOpts: comm.DefaultKeepaliveOptions, + SecOpts: &comm.SecureOptions{}, + Timeout: 5 * time.Minute, + } + + clientConfig.SecOpts.UseTLS = true + clientConfig.SecOpts.RequireClientCert = true + + rootCert, err := ioutil.ReadFile(root_cert) + if err != nil { + return comm.ClientConfig{}, errors.WithMessage(err, "Error loading TLS root certificate") + } + clientConfig.SecOpts.ServerRootCAs = [][]byte{rootCert} + + + clientKey, err := ioutil.ReadFile(client_key) + if err != nil { + return comm.ClientConfig{}, errors.WithMessage(err, "Error loading client TLS key") + } + clientConfig.SecOpts.Key = clientKey + + clientCert, err := ioutil.ReadFile(client_cert) + if err != nil { + return comm.ClientConfig{}, errors.WithMessage(err, "Error loading client TLS cert") + } + clientConfig.SecOpts.Certificate = clientCert + + return clientConfig, nil + +} + + +func InitGRPCClient(clientConfig comm.ClientConfig) (*GRPCClient, error){ + + grpcClient, err := comm.NewGRPCClient(clientConfig) + if err != nil { + fmt.Println("Error creating grpc client: "+ err.Error()) + return nil, errors.WithMessage(err, "Error creating grpc client") + } + + grpcClientConn, err := grpcClient.NewConnection(server, "") + if err != nil { + fmt.Println("Error connecting: "+ err.Error()) + return nil, errors.WithMessage(err, "Error connecting") + } + + signer := localmsp.NewSigner() + tlsCertHash := util.ComputeSHA256(grpcClient.Certificate().Certificate[0]) + + return &GRPCClient { + grpcClient: grpcClient, + grpcClientConn: grpcClientConn, + signer: signer, + tlsCertHash: tlsCertHash, + }, nil +} + + +func(grpc *GRPCClient) InitDeliveryClient(filtered bool) (error){ + + + deliverClient := peer.NewDeliverClient(grpc.grpcClientConn) + + if deliverClient == nil { + return errors.New("No Host Available") + } + + var err error + var deliveryClient DeliveryClient + if filtered { + deliveryClient, err = deliverClient.DeliverFiltered(context.Background()) + } else { + deliveryClient, err = deliverClient.Deliver(context.Background()) + } + + if err != nil { + return errors.WithMessage(err, "failed to connect") + } + + grpc.deliveryClient = deliveryClient + return nil +} + +func(grpc *GRPCClient) CreateEventStream() error{ + + envelope, err := grpc.CreateSignedEnvelope() + if err != nil { + return errors.WithMessage(err, "Error creating signed envelope") + } + + err = grpc.deliveryClient.Send(envelope) + + if err != nil { + return errors.WithMessage(err, "Error in delivering the signed envelope") + } + + return nil +} + +func(grpc *GRPCClient) CreateSignedEnvelope() (*common.Envelope,error) { + + start := &orderer.SeekPosition{ + Type: &orderer.SeekPosition_Newest{ + Newest: &orderer.SeekNewest{}, + }, + } + + stop := &orderer.SeekPosition{ + Type: &orderer.SeekPosition_Specified{ + Specified: &orderer.SeekSpecified{ + Number: math.MaxUint64, + }, + }, + } + + env, err := utils.CreateSignedEnvelopeWithTLSBinding(common.HeaderType_DELIVER_SEEK_INFO, + channel_id, grpc.signer, + &orderer.SeekInfo{ + Start: start, + Stop: stop, + Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY, + }, 0, 0, grpc.tlsCertHash) + if err != nil { + return nil, errors.WithMessage(err, "Error creating signed envelope") + } + return env, nil +} + + +func(grpc *GRPCClient) ReadEventStream() error{ + + for { + + receivedMsg, err := grpc.deliveryClient.Recv() + if err != nil { + return errors.WithMessage(err, "Error in Receiving Message") + } + + switch t := receivedMsg.Type.(type) { + + case *peer.DeliverResponse_Status: + fmt.Println("Block Status ",t) + //return nil + case *peer.DeliverResponse_Block: + + fmt.Println(" Read Block --") + ReadBlock(t.Block) + + /*err = protolator.DeepMarshalJSON(os.Stdout, t.Block) + if err != nil { + return errors.WithMessage(err, " Error pretty printing block") + }*/ + + //return nil + case *peer.DeliverResponse_FilteredBlock: + + fmt.Println(" Read Filter Block --") + //ReadBlock(t.FilteredBlock) + + /*err = protolator.DeepMarshalJSON(os.Stdout, t.FilteredBlock) + if err != nil { + return errors.WithMessage(err, " Error pretty printing filtered block") + }*/ + //return nil + } + } + + return nil +} + + + +func ReadConfigs() error { + + fmt.Println("Read Configs ") + + configFile, err := os.Open("config.json") + + if err != nil { + return errors.WithMessage(err, "failed to read config json") + } + + fmt.Println("Successfully Opened Config File") + + defer configFile.Close() + + byteValue, _ := ioutil.ReadAll(configFile) + + var configs map[string]interface{} + json.Unmarshal([]byte(byteValue), &configs) + + fabric_cfg_path = ROOT + fmt.Sprint(configs["fabric_cfg_path"]) + msp_id = fmt.Sprint(configs["msp_id"]) + msp_type = fmt.Sprint(configs["msp_type"]) + msp_config_dir = fabric_cfg_path + fmt.Sprint(configs["msp_config_dir"]) + client_key = fabric_cfg_path + fmt.Sprint(configs["client_key"]) + client_cert = fabric_cfg_path + fmt.Sprint(configs["client_cert"]) + root_cert = fabric_cfg_path + fmt.Sprint(configs["root_cert"]) + server = fmt.Sprint(configs["server"]) + channel_id = fmt.Sprint(configs["channel_id"]) + config_file = fmt.Sprint(configs["config_file"]) + + fmt.Println("**** Configs **** ") + fmt.Println(configs["fabric_cfg_path"]) + fmt.Println(configs["msp_id"]) + fmt.Println(configs["msp_type"]) + fmt.Println(msp_config_dir) + fmt.Println(client_key) + fmt.Println(client_cert) + fmt.Println(root_cert) + fmt.Println(configs["server"]) + fmt.Println(configs["channel_id"]) + fmt.Println(configs["config_file"]) + + return nil +} diff --git a/model.go b/model.go new file mode 100644 index 0000000..9fa6289 --- /dev/null +++ b/model.go @@ -0,0 +1,9 @@ +package main + +type SampleUser struct { + + Email string `json:"email"` + Name string `json:"name"` + Age string `json:"age"` + Country string `json:"country"` +} \ No newline at end of file diff --git a/offchaindata.go b/offchaindata.go new file mode 100644 index 0000000..18e48b7 --- /dev/null +++ b/offchaindata.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" +) + +func main(){ + + clientConfig, err := InitClientConfigs() + if err != nil { + fmt.Println("Error when initializing Client Config "+ err.Error()) + } + + fmt.Println("Client Configs initialized successfully") + + grpcClient, err := InitGRPCClient(clientConfig) + if err != nil { + fmt.Println(" Error when initializing GRPC Client Connection "+err.Error()) + } + + err = grpcClient.InitDeliveryClient(false) + if err != nil { + fmt.Println(" Error when intializing Delivery Client "+err.Error()) + } + + err = grpcClient.CreateEventStream() + if err != nil { + fmt.Println(" Error when Creating Event Stream - "+err.Error()) + } + + err = grpcClient.ReadEventStream() + if err != nil { + fmt.Println(" Error reading event stream - "+err.Error()) + } + +} \ No newline at end of file From 6f431698e3d272b14a5b0c5840b563e142fce05b Mon Sep 17 00:00:00 2001 From: Harald Gjermundrod Date: Tue, 25 Feb 2020 17:36:12 -0800 Subject: [PATCH 02/28] Mapreduce Integrated --- Mapreduce.sh | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Mapreduce.sh diff --git a/Mapreduce.sh b/Mapreduce.sh new file mode 100644 index 0000000..a1ef84b --- /dev/null +++ b/Mapreduce.sh @@ -0,0 +1,9 @@ +## Create MapReduce for Email +curl -X PUT http://127.0.0.1:5990/offchaindb/_design/emailviewdesign/ -d '{"views":{"emailview":{"map":"function(doc) { emit(doc.email,1);}", "reduce":"function (keys, values, combine) {return sum(values)}"}}}' -H 'Content-Type:application/json' + +## Query Reduce +curl -X GET http://127.0.0.1:5990/offchaindb/_design/emailviewdesign/_view/emailview?reduce=true + +## Query Group +curl -X GET http://127.0.0.1:5990/offchaindb/_design/emailviewdesign/_view/emailview?group=true + From 599832ede79a5ce983e48c9abf8ef7ad1a752b8c Mon Sep 17 00:00:00 2001 From: Harald Gjermundrod Date: Tue, 25 Feb 2020 18:52:07 -0800 Subject: [PATCH 03/28] Added Event Listener --- blockreader.go | 49 ++++++++--------- couchdb.go | 26 +++++---- eventlistener.go | 135 ++++++++++++++++++++--------------------------- offchaindata.go | 14 +++-- 4 files changed, 105 insertions(+), 119 deletions(-) diff --git a/blockreader.go b/blockreader.go index 3df2bea..a360992 100644 --- a/blockreader.go +++ b/blockreader.go @@ -2,8 +2,6 @@ package main import ( "fmt" - "encoding/json" - //"github.com/hyperledger/fabric-protos-go/peer" "github.com/hyperledger/fabric/protos/common" "github.com/hyperledger/fabric/protos/peer" "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/ledger/rwset/kvrwset" @@ -14,8 +12,13 @@ import ( func ReadBlock(block *common.Block) error{ + fmt.Println("\n ######################################################################## ") + + blockHeader := block.Header blockData := block.Data.Data + fmt.Println(" Received Block Number = ", blockHeader.Number) + //First Get the Envelope from the BlockData envelope, err := GetEnvelopeFromBlock(blockData[0]) if err != nil { @@ -54,16 +57,17 @@ func ReadBlock(block *common.Block) error{ return errors.WithMessage(err,"unmarshaling Chaincode Proposal Payload Input error: ") } - fmt.Println("Chaincode Name === "+input.ChaincodeSpec.ChaincodeId.Name) - chaincodeArgs := make([]string, len(input.ChaincodeSpec.Input.Args)) - for i, c := range input.ChaincodeSpec.Input.Args { args := CToGoString(c[:]) chaincodeArgs[i] = args } - fmt.Println("Chaicode Args = ", chaincodeArgs) + fmt.Println("\n ## Chaincode ") + fmt.Println(" Name : ", input.ChaincodeSpec.ChaincodeId.Name) + fmt.Println(" Version : ", input.ChaincodeSpec.ChaincodeId.Version) + fmt.Println(" Args : ", chaincodeArgs) + proposalResponsePayload := &peer.ProposalResponsePayload{} err = proto.Unmarshal(chaincodeActionPayload.Action.ProposalResponsePayload, proposalResponsePayload) @@ -91,33 +95,26 @@ func ReadBlock(block *common.Block) error{ return errors.WithMessage(err,"unmarshaling kvrwset error: ") } - if len(kvrwset.Reads) != 0 { - - fmt.Println("BlockNum = ",kvrwset.Reads[0].Version.BlockNum) - fmt.Println("TxNum = ",kvrwset.Reads[0].Version.TxNum) - fmt.Println("KVRead Key = ",kvrwset.Reads[0].Key) - //fmt.Println("KVRead Value = ",kvrwset.Reads[0].Value) + fmt.Println("\n Block Read Write Set ") + if len(kvrwset.Reads) != 0 { + fmt.Println("\n ## KVRead Set ") + fmt.Println(" BlockNum = ",kvrwset.Reads[0].Version.BlockNum) + fmt.Println(" TxNum = ",kvrwset.Reads[0].Version.TxNum) + fmt.Println(" Key = ",kvrwset.Reads[0].Key) } if len(kvrwset.Writes) != 0 { - args := CToGoString(kvrwset.Writes[0].Value[:]) + values := CToGoString(kvrwset.Writes[0].Value[:]) - fmt.Println("KVWrite Key = ",kvrwset.Writes[0].Key) - fmt.Println("KVWrite Value = ",args) + fmt.Println("\n ## KVWrite Set") + fmt.Println(" Key = ",kvrwset.Writes[0].Key) + fmt.Println(" Value = ",values) - User := &SampleUser{} - err = json.Unmarshal(kvrwset.Writes[0].Value, User) - if err != nil{ - return errors.WithMessage(err,"unmarshaling write set error: ") + err = SaveToCouchDB(kvrwset.Writes[0].Value) + if err != nil { + return errors.WithMessage(err,"error while saving to CouchDB") } - - fmt.Println("Email = "+User.Email) - fmt.Println("Name = "+User.Name) - fmt.Println("Age = "+User.Age) - fmt.Println("Country = "+User.Country) - - SaveToCouchDB(kvrwset.Writes[0].Value) } diff --git a/couchdb.go b/couchdb.go index ffdf502..56a5f6c 100644 --- a/couchdb.go +++ b/couchdb.go @@ -11,19 +11,20 @@ import ( func SaveToCouchDB(kvWriteSet []byte) error{ - fmt.Println("Saving to CouchDB") - client, err := kivik.New("couch", "http://localhost:5990/") + dbName := "offchaindb" + couchdbUrl := "http://localhost:5990/" + fmt.Println("\n Saving the Block details to CouchDB") + fmt.Println(" CouchDB URL = ", couchdbUrl) + fmt.Println(" DB Name = ", dbName) + + client, err := kivik.New("couch", couchdbUrl) if err != nil { fmt.Println("failed to set couchdb - "+err.Error()) return errors.WithMessage(err,"failed to set couchdb: ") } - db := client.DB(context.TODO(), "offchaindb") - - /*if err != nil { - return errors.WithMessage(err,"failed to create database: ") - }*/ + db := client.DB(context.TODO(), dbName) User := &SampleUser{} err = json.Unmarshal(kvWriteSet, User) @@ -31,13 +32,16 @@ func SaveToCouchDB(kvWriteSet []byte) error{ return errors.WithMessage(err,"unmarshaling write set error: ") } + fmt.Println("\n Collection Key ", User.Email) + rev, err := db.Put(context.TODO(), User.Email, User) if err != nil { - fmt.Println("user insertion error - "+err.Error()) - return errors.WithMessage(err,"user insertion error: ") + fmt.Println(" Error during insertion - "+err.Error()) + } else { + fmt.Println(" User Inserted into CouchDB - Revision = "+rev+" \n") } - - fmt.Println("User Inserted into CouchDB %s ",rev) + + fmt.Println(" ######################################################################## \n") return nil } \ No newline at end of file diff --git a/eventlistener.go b/eventlistener.go index c3e6053..6f312da 100644 --- a/eventlistener.go +++ b/eventlistener.go @@ -15,7 +15,6 @@ import ( "github.com/hyperledger/fabric/common/localmsp" "github.com/hyperledger/fabric/protos/peer" "github.com/hyperledger/fabric/protos/orderer" - //"github.com/hyperledger/fabric/common/tools/protolator" common2 "github.com/hyperledger/fabric/peer/common" "github.com/hyperledger/fabric/protos/common" "github.com/hyperledger/fabric/protos/utils" @@ -48,14 +47,8 @@ var ( config_file string ) -const ( - ROOT = "/home/harald/go/src/github.com/" -) - func InitClientConfigs() (comm.ClientConfig,error) { - fmt.Println("Init Client Configs ") - err := ReadConfigs() if err != nil { return comm.ClientConfig{}, errors.WithMessage(err, "failed to read config json") @@ -67,16 +60,12 @@ func InitClientConfigs() (comm.ClientConfig,error) { return comm.ClientConfig{}, errors.WithMessage(err, "fatal error when initializing config") } - fmt.Println("Init Config Successfully") - /* Initialize Crypto */ err = common2.InitCrypto(msp_config_dir, msp_id, msp_type) if err != nil { return comm.ClientConfig{}, errors.WithMessage(err, "Cannot run client because") } - fmt.Println("Init Crypto Successfully") - /* Init Client Configs */ clientConfig := comm.ClientConfig{ KaOpts: comm.DefaultKeepaliveOptions, @@ -84,30 +73,32 @@ func InitClientConfigs() (comm.ClientConfig,error) { Timeout: 5 * time.Minute, } - clientConfig.SecOpts.UseTLS = true - clientConfig.SecOpts.RequireClientCert = true + clientConfig.SecOpts.UseTLS = true + clientConfig.SecOpts.RequireClientCert = true - rootCert, err := ioutil.ReadFile(root_cert) - if err != nil { - return comm.ClientConfig{}, errors.WithMessage(err, "Error loading TLS root certificate") - } - clientConfig.SecOpts.ServerRootCAs = [][]byte{rootCert} + rootCert, err := ioutil.ReadFile(root_cert) + if err != nil { + return comm.ClientConfig{}, errors.WithMessage(err, "Error loading TLS root certificate") + } + clientConfig.SecOpts.ServerRootCAs = [][]byte{rootCert} - clientKey, err := ioutil.ReadFile(client_key) - if err != nil { - return comm.ClientConfig{}, errors.WithMessage(err, "Error loading client TLS key") - } - clientConfig.SecOpts.Key = clientKey + clientKey, err := ioutil.ReadFile(client_key) + if err != nil { + return comm.ClientConfig{}, errors.WithMessage(err, "Error loading client TLS key") + } + clientConfig.SecOpts.Key = clientKey - clientCert, err := ioutil.ReadFile(client_cert) - if err != nil { - return comm.ClientConfig{}, errors.WithMessage(err, "Error loading client TLS cert") - } - clientConfig.SecOpts.Certificate = clientCert + clientCert, err := ioutil.ReadFile(client_cert) + if err != nil { + return comm.ClientConfig{}, errors.WithMessage(err, "Error loading client TLS cert") + } + clientConfig.SecOpts.Certificate = clientCert - return clientConfig, nil + fmt.Println(" Crypto & Client Configs initialized Successfully!") + + return clientConfig, nil } @@ -128,6 +119,8 @@ func InitGRPCClient(clientConfig comm.ClientConfig) (*GRPCClient, error){ signer := localmsp.NewSigner() tlsCertHash := util.ComputeSHA256(grpcClient.Certificate().Certificate[0]) + fmt.Println(" GRPC Client initialized Successfully!") + return &GRPCClient { grpcClient: grpcClient, grpcClientConn: grpcClientConn, @@ -137,28 +130,25 @@ func InitGRPCClient(clientConfig comm.ClientConfig) (*GRPCClient, error){ } -func(grpc *GRPCClient) InitDeliveryClient(filtered bool) (error){ - +func(grpc *GRPCClient) InitDeliveryClient() (error){ deliverClient := peer.NewDeliverClient(grpc.grpcClientConn) - if deliverClient == nil { return errors.New("No Host Available") } var err error var deliveryClient DeliveryClient - if filtered { - deliveryClient, err = deliverClient.DeliverFiltered(context.Background()) - } else { - deliveryClient, err = deliverClient.Deliver(context.Background()) - } - + + deliveryClient, err = deliverClient.Deliver(context.Background()) if err != nil { return errors.WithMessage(err, "failed to connect") } grpc.deliveryClient = deliveryClient + + fmt.Println(" GRPC Delivery Client initialized Successfully!") + return nil } @@ -170,11 +160,10 @@ func(grpc *GRPCClient) CreateEventStream() error{ } err = grpc.deliveryClient.Send(envelope) - if err != nil { return errors.WithMessage(err, "Error in delivering the signed envelope") } - + fmt.Println(" GRPC Event Stream created Successfully!") return nil } @@ -204,12 +193,19 @@ func(grpc *GRPCClient) CreateSignedEnvelope() (*common.Envelope,error) { if err != nil { return nil, errors.WithMessage(err, "Error creating signed envelope") } + + fmt.Println(" Signed Envelope Created ") + fmt.Println(" Seek Info Start = ", start) + fmt.Println(" Seek Info Stop = ", stop) + return env, nil } func(grpc *GRPCClient) ReadEventStream() error{ + fmt.Println(" \n Started listening GRPC Event Stream at ", server) + for { receivedMsg, err := grpc.deliveryClient.Recv() @@ -220,29 +216,11 @@ func(grpc *GRPCClient) ReadEventStream() error{ switch t := receivedMsg.Type.(type) { case *peer.DeliverResponse_Status: - fmt.Println("Block Status ",t) - //return nil - case *peer.DeliverResponse_Block: + fmt.Println(" Received DeliverResponse Status = ", t) + case *peer.DeliverResponse_Block: + fmt.Println(" Received a new Block from = ",channel_id) + ReadBlock(t.Block) - fmt.Println(" Read Block --") - ReadBlock(t.Block) - - /*err = protolator.DeepMarshalJSON(os.Stdout, t.Block) - if err != nil { - return errors.WithMessage(err, " Error pretty printing block") - }*/ - - //return nil - case *peer.DeliverResponse_FilteredBlock: - - fmt.Println(" Read Filter Block --") - //ReadBlock(t.FilteredBlock) - - /*err = protolator.DeepMarshalJSON(os.Stdout, t.FilteredBlock) - if err != nil { - return errors.WithMessage(err, " Error pretty printing filtered block") - }*/ - //return nil } } @@ -253,20 +231,18 @@ func(grpc *GRPCClient) ReadEventStream() error{ func ReadConfigs() error { - fmt.Println("Read Configs ") + //ROOT := os.Getenv("GOPATH") - configFile, err := os.Open("config.json") + ROOT := "/home/harald/go/src/github.com/" + configFile, err := os.Open("config.json") if err != nil { return errors.WithMessage(err, "failed to read config json") } - - fmt.Println("Successfully Opened Config File") - defer configFile.Close() - byteValue, _ := ioutil.ReadAll(configFile) + byteValue, _ := ioutil.ReadAll(configFile) var configs map[string]interface{} json.Unmarshal([]byte(byteValue), &configs) @@ -281,17 +257,18 @@ func ReadConfigs() error { channel_id = fmt.Sprint(configs["channel_id"]) config_file = fmt.Sprint(configs["config_file"]) - fmt.Println("**** Configs **** ") - fmt.Println(configs["fabric_cfg_path"]) - fmt.Println(configs["msp_id"]) - fmt.Println(configs["msp_type"]) - fmt.Println(msp_config_dir) - fmt.Println(client_key) - fmt.Println(client_cert) - fmt.Println(root_cert) - fmt.Println(configs["server"]) - fmt.Println(configs["channel_id"]) - fmt.Println(configs["config_file"]) + fmt.Println(" ### Configs ") + fmt.Println(" ROOT = ", ROOT) + fmt.Println(" FABRIC_CFG_PATH = ",configs["fabric_cfg_path"]) + fmt.Println(" MSP ID = ",configs["msp_id"]) + fmt.Println(" MSP TYPE = ",configs["msp_type"]) + fmt.Println(" MSP CONFIG DIR = ",configs["msp_config_dir"]) + fmt.Println(" CLIENT KEY = ",configs["client_key"]) + fmt.Println(" CLIENT CERT = ",configs["client_cert"]) + fmt.Println(" ROOT CERT = ",configs["root_cert"]) + fmt.Println(" GRPC LISTENING SERVER = ",configs["server"]) + fmt.Println(" CHANNEL ID = ",configs["channel_id"]) + fmt.Println(" CONFIG FILE = ",configs["config_file"]) return nil } diff --git a/offchaindata.go b/offchaindata.go index 18e48b7..02dd955 100644 --- a/offchaindata.go +++ b/offchaindata.go @@ -6,31 +6,39 @@ import ( func main(){ + fmt.Println("************************************************") + fmt.Println(" Hyperledger Fabric OffChain Storage Demo ") + fmt.Println("************************************************") + + clientConfig, err := InitClientConfigs() if err != nil { fmt.Println("Error when initializing Client Config "+ err.Error()) + return } - fmt.Println("Client Configs initialized successfully") grpcClient, err := InitGRPCClient(clientConfig) if err != nil { fmt.Println(" Error when initializing GRPC Client Connection "+err.Error()) + return } - err = grpcClient.InitDeliveryClient(false) + err = grpcClient.InitDeliveryClient() if err != nil { fmt.Println(" Error when intializing Delivery Client "+err.Error()) + return } err = grpcClient.CreateEventStream() if err != nil { fmt.Println(" Error when Creating Event Stream - "+err.Error()) + return } err = grpcClient.ReadEventStream() if err != nil { - fmt.Println(" Error reading event stream - "+err.Error()) + fmt.Println(" Error reading event stream - "+err.Error()) } } \ No newline at end of file From 1ed029301e0d3b0337955b41eaebb21c82dae1e0 Mon Sep 17 00:00:00 2001 From: Harald Gjermundrod Date: Tue, 25 Feb 2020 18:53:18 -0800 Subject: [PATCH 04/28] Added Event Listener --- config.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/config.json b/config.json index 7a3ed13..4bb970a 100644 --- a/config.json +++ b/config.json @@ -1,12 +1,12 @@ { - "fabric_cfg_path": "privacytracker/fixtures/crypto-config/peerOrganizations/", + "fabric_cfg_path": "exampleledger/fixtures/crypto-config/peerOrganizations/", "msp_id": "Org1MSP", "msp_type": "bccsp", - "msp_config_dir": "org1.privacy.tracker.com/users/Admin@org1.privacy.tracker.com/msp", - "client_key": "org1.privacy.tracker.com/peers/peer0.org1.privacy.tracker.com/tls/server.key", - "client_cert": "org1.privacy.tracker.com/peers/peer0.org1.privacy.tracker.com/tls/server.crt", - "root_cert": "org1.privacy.tracker.com/peers/peer0.org1.privacy.tracker.com/tls/ca.crt", - "server": "peer0.org1.privacy.tracker.com:7051", - "channel_id": "privacytracker", + "msp_config_dir": "org1.example.ledger.com/users/Admin@org1.example.ledger.com/msp", + "client_key": "org1.example.ledger.com/peers/peer0.org1.example.ledger.com/tls/server.key", + "client_cert": "org1.example.ledger.com/peers/peer0.org1.example.ledger.com/tls/server.crt", + "root_cert": "org1.example.ledger.com/peers/peer0.org1.example.ledger.com/tls/ca.crt", + "server": "peer0.org1.example.ledger.com:7051", + "channel_id": "exampleledger", "config_file": "configtx" } From 344489ff9252b702730c9aadf4571fe0b975029c Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 05:11:03 +0200 Subject: [PATCH 05/28] Update eventlistener.go --- eventlistener.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/eventlistener.go b/eventlistener.go index 6f312da..c8ab18f 100644 --- a/eventlistener.go +++ b/eventlistener.go @@ -231,10 +231,8 @@ func(grpc *GRPCClient) ReadEventStream() error{ func ReadConfigs() error { - //ROOT := os.Getenv("GOPATH") - - ROOT := "/home/harald/go/src/github.com/" - + ROOT := os.Getenv("GOPATH") + configFile, err := os.Open("config.json") if err != nil { return errors.WithMessage(err, "failed to read config json") From 2f7b48876498b2ef1530cbf70a12f498eae85628 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 05:41:43 +0200 Subject: [PATCH 06/28] Create README.md --- README.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..9404c9e --- /dev/null +++ b/README.md @@ -0,0 +1,81 @@ +

offchaindata

+

N|Solid

+

offchaindata is a sample demonstration to understand the concept of implmenting offchain storage and it's capability in Hyperledger fabric Blockchain network. + So, this project will work as a peer block event listener and will store the block details in the couchdb. The couchdb collections can be query through Mapreduce.

+ +

Configuration requirements

+

You need to add the certain project details in `config.json`, so that it will be used to create an event listener and the Blocks will be received through GRPC delivery +client.

+ +```````````````````````````````````````````````````````````````````````````````````````````````````````````` + { + "fabric_cfg_path": "exampleledger/fixtures/crypto-config/peerOrganizations/", + "msp_id": "Org1MSP", + "msp_type": "bccsp", + "msp_config_dir": "org1.example.ledger.com/users/Admin@org1.example.ledger.com/msp", + "client_key": "org1.example.ledger.com/peers/peer0.org1.example.ledger.com/tls/server.key", + "client_cert": "org1.example.ledger.com/peers/peer0.org1.example.ledger.com/tls/server.crt", + "root_cert": "org1.example.ledger.com/peers/peer0.org1.example.ledger.com/tls/ca.crt", + "server": "peer0.org1.example.ledger.com:7051", + "channel_id": "exampleledger", + "config_file": "configtx" + } +````````````````````````````````````````````````````````````````````````````````````````````````````````````````` + +

Create CouchDB local instance

+ +The CouchDB local instance can be created using Docker. +``````````````````````````````````````````````````````````````````````````````````````````````````````````````` +docker run --publish 5990:5984 --detach --name offchaindb hyperledger/fabric-couchdb +docker start offchaindb +````````````````````````````````````````````````````````````````````````````````````````````````````````````````` + +

Mock Chaincode Model

+I have followed a sample user model to create the offchaindb. You can also create your own chaincode model and the offchaindata +will listen the `KVWriteSet` to store in the couchdb. + +Sample Model +`````````````````````````````````````````````````````````````````````````````````````````````````````````````````` +type SampleUser struct { + Email string `json:"email"` + Name string `json:"name"` + Age string `json:"age"` + Country string `json:"country"` + } +`````````````````````````````````````````````````````````````````````````````````````````````````````````````````` + +

Configure MapReduce

+ +

MapReduce will query the offchain data from `CouchDB`. So, you need to configure MapReduce for certain design element from CouchDB collection.

+ +Configure MapReduce for Email +```````````````````````````````````````````````````````````````````````````````````````````````````````````````` +curl -X PUT http://127.0.0.1:5990/offchaindb/_design/emailviewdesign/ -d '{"views":{"emailview":{"map":"function(doc) { emit(doc.email,1);}", "reduce":"function (keys, values, combine) {return sum(values)}"}}}' -H 'Content-Type:application/json' +```````````````````````````````````````````````````````````````````````````````````````````````````````````````` + +Query `Reduce` function to count total email +``````````````````````````````````````````````````````````````````````````````````````````````````````````````` +curl -X GET http://127.0.0.1:5990/offchaindb/_design/emailviewdesign/_view/emailview?reduce=true +``````````````````````````````````````````````````````````````````````````````````````````````````````````````` +Output +``````````````````````````````````````````````````````````````````````````````````````````````````````````````` +{"rows":[ + {"key":null,"value":7} + ]} +``````````````````````````````````````````````````````````````````````````````````````````````````````````````` + +Query `Map` function to list all emails +``````````````````````````````````````````````````````````````````````````````````````````````````````````````` +{"rows":[ + {"key":"alice@gmail.com","value":1}, + {"key":"john@gmail.com","value":1}, + {"key":"michale@gmail.com","value":1}, + {"key":"mark@mail.com","value":1}, + {"key":"bob@gmail.com","value":1}, + {"key":"oscar@gmail.com","value":1}, + {"key":"william@example.com","value":1} + ]} +``````````````````````````````````````````````````````````````````````````````````````````````````````````````` + +So, all the query peformed in offchain without querying from blockchain ledger. + From 02636f52ad4c1c789dce0f18cdc4bfb2dc542ba9 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 05:43:23 +0200 Subject: [PATCH 07/28] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9404c9e..d955c3d 100644 --- a/README.md +++ b/README.md @@ -38,15 +38,15 @@ will listen the `KVWriteSet` to store in the couchdb. `````````````````````````````````````````````````````````````````````````````````````````````````````````````````` type SampleUser struct { Email string `json:"email"` - Name string `json:"name"` - Age string `json:"age"` + Name string `json:"name"` + Age string `json:"age"` Country string `json:"country"` } ``````````````````````````````````````````````````````````````````````````````````````````````````````````````````

Configure MapReduce

-

MapReduce will query the offchain data from `CouchDB`. So, you need to configure MapReduce for certain design element from CouchDB collection.

+

MapReduce will query the offchain data from CouchDB. So, you need to configure MapReduce for certain design element from CouchDB collection.

Configure MapReduce for Email ```````````````````````````````````````````````````````````````````````````````````````````````````````````````` From 4765f2cc432b8e1bcf9f535a39ab355bf10d6e75 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 05:49:44 +0200 Subject: [PATCH 08/28] Update README.md --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d955c3d..4fbf66c 100644 --- a/README.md +++ b/README.md @@ -52,12 +52,16 @@ type SampleUser struct { ```````````````````````````````````````````````````````````````````````````````````````````````````````````````` curl -X PUT http://127.0.0.1:5990/offchaindb/_design/emailviewdesign/ -d '{"views":{"emailview":{"map":"function(doc) { emit(doc.email,1);}", "reduce":"function (keys, values, combine) {return sum(values)}"}}}' -H 'Content-Type:application/json' ```````````````````````````````````````````````````````````````````````````````````````````````````````````````` +Output +```````````````````````````````````````````````````````````````````````````````````````````````````````````````` +{"ok": true, "id":"_design/emailviewdesign", "rev": "1-f34147f686003ff5c7da5a5e7e2759b8"} +```````````````````````````````````````````````````````````````````````````````````````````````````````````````` Query `Reduce` function to count total email ``````````````````````````````````````````````````````````````````````````````````````````````````````````````` curl -X GET http://127.0.0.1:5990/offchaindb/_design/emailviewdesign/_view/emailview?reduce=true ``````````````````````````````````````````````````````````````````````````````````````````````````````````````` -Output +Output ``````````````````````````````````````````````````````````````````````````````````````````````````````````````` {"rows":[ {"key":null,"value":7} @@ -66,6 +70,10 @@ Output Query `Map` function to list all emails ``````````````````````````````````````````````````````````````````````````````````````````````````````````````` +curl -X GET http://127.0.0.1:5990/offchaindb/_design/emailviewdesign/_view/emailview?group=true +``````````````````````````````````````````````````````````````````````````````````````````````````````````````` +Output +``````````````````````````````````````````````````````````````````````````````````````````````````````````````` {"rows":[ {"key":"alice@gmail.com","value":1}, {"key":"john@gmail.com","value":1}, From aff112e57ffdaf8f8c8fe74509a52231655e84f0 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 05:52:57 +0200 Subject: [PATCH 09/28] Update download.sh --- download.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/download.sh b/download.sh index f8cf9fa..d789ebf 100755 --- a/download.sh +++ b/download.sh @@ -10,7 +10,3 @@ go get -v github.com/syndtr/goleveldb/leveldb/util go get -v github.com/tedsuo/ifrit go get -v github.com/willf/bitset go get -v golang.org/x/sync/semaphore -<<<<<<< HEAD - -======= ->>>>>>> 30861862dfb5c84d3332f1502de8aa723bc95de6 From ff5f3729c7fd73557304de8de5c2323dac333e8d Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 05:54:43 +0200 Subject: [PATCH 10/28] Update eventlistener.go --- eventlistener.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/eventlistener.go b/eventlistener.go index c8ab18f..47dca0e 100644 --- a/eventlistener.go +++ b/eventlistener.go @@ -27,7 +27,7 @@ type DeliveryClient interface { } type GRPCClient struct { - grpcClient *comm.GRPCClient + grpcClient *comm.GRPCClient grpcClientConn *grpc.ClientConn deliveryClient DeliveryClient signer crypto.LocalSigner @@ -36,15 +36,15 @@ type GRPCClient struct { var ( fabric_cfg_path string - msp_id string - msp_type string + msp_id string + msp_type string msp_config_dir string - client_key string + client_key string client_cert string - root_cert string - server string - channel_id string - config_file string + root_cert string + server string + channel_id string + config_file string ) func InitClientConfigs() (comm.ClientConfig,error) { From e5e8d28a4137a06887df749559e7fccfe5172833 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 05:55:39 +0200 Subject: [PATCH 11/28] Update model.go --- model.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/model.go b/model.go index 9fa6289..0750e17 100644 --- a/model.go +++ b/model.go @@ -4,6 +4,6 @@ type SampleUser struct { Email string `json:"email"` Name string `json:"name"` - Age string `json:"age"` + Age string `json:"age"` Country string `json:"country"` -} \ No newline at end of file +} From 4907d78f026264ea18afa0175514850c7f02f72f Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 05:58:21 +0200 Subject: [PATCH 12/28] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4fbf66c..38fe993 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -

offchaindata

+

OffChainData

N|Solid

-

offchaindata is a sample demonstration to understand the concept of implmenting offchain storage and it's capability in Hyperledger fabric Blockchain network. - So, this project will work as a peer block event listener and will store the block details in the couchdb. The couchdb collections can be query through Mapreduce.

+

OffChainData is a sample demonstration to understand the concept of implmenting offchain storage and it's capability in Hyperledger fabric Blockchain network. + So, this project will work as a peer block event listener and will store the block details in the CouchDB that be query through MapReduce.

Configuration requirements

You need to add the certain project details in `config.json`, so that it will be used to create an event listener and the Blocks will be received through GRPC delivery From e25da3dce6f1da6ff8fc34d9dc5dcb46368dae51 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 06:01:19 +0200 Subject: [PATCH 13/28] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 38fe993..68628be 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -

OffChainData

+

OffChain Data

N|Solid

-

OffChainData is a sample demonstration to understand the concept of implmenting offchain storage and it's capability in Hyperledger fabric Blockchain network. +

OffChain Data is a sample demonstration to understand the concept of implmenting offchain storage and it's capability in Hyperledger fabric Blockchain network. So, this project will work as a peer block event listener and will store the block details in the CouchDB that be query through MapReduce.

Configuration requirements

From 5ec51b689fa74cbcc70f52d3004aced206554fae Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 18:41:57 +0200 Subject: [PATCH 14/28] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 68628be..e670b83 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,13 @@

You need to add the certain project details in `config.json`, so that it will be used to create an event listener and the Blocks will be received through GRPC delivery client.

+```````````````````````````````````````````````````````````````````````````````````````````````````````````` +export FABRIC_CFG_PATH= /home/user/go/src/github.com/exampleledger/fixtures +```````````````````````````````````````````````````````````````````````````````````````````````````````````` + ```````````````````````````````````````````````````````````````````````````````````````````````````````````` { - "fabric_cfg_path": "exampleledger/fixtures/crypto-config/peerOrganizations/", + "peer_config_path": "exampleledger/fixtures/crypto-config/peerOrganizations/", "msp_id": "Org1MSP", "msp_type": "bccsp", "msp_config_dir": "org1.example.ledger.com/users/Admin@org1.example.ledger.com/msp", From b68e12abd26a7cffdd5a6b790a9284eb378a367a Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 18:42:16 +0200 Subject: [PATCH 15/28] Update config.json --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 4bb970a..f62823c 100644 --- a/config.json +++ b/config.json @@ -1,5 +1,5 @@ { - "fabric_cfg_path": "exampleledger/fixtures/crypto-config/peerOrganizations/", + "peer_config_path": "exampleledger/fixtures/crypto-config/peerOrganizations/", "msp_id": "Org1MSP", "msp_type": "bccsp", "msp_config_dir": "org1.example.ledger.com/users/Admin@org1.example.ledger.com/msp", From 0150979bb413c0558b5439aad44ce6473eca9ef6 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 18:43:08 +0200 Subject: [PATCH 16/28] Update eventlistener.go --- eventlistener.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eventlistener.go b/eventlistener.go index 47dca0e..9b3cc39 100644 --- a/eventlistener.go +++ b/eventlistener.go @@ -244,7 +244,7 @@ func ReadConfigs() error { var configs map[string]interface{} json.Unmarshal([]byte(byteValue), &configs) - fabric_cfg_path = ROOT + fmt.Sprint(configs["fabric_cfg_path"]) + peer_config_path = ROOT + fmt.Sprint(configs["peer_config_path"]) msp_id = fmt.Sprint(configs["msp_id"]) msp_type = fmt.Sprint(configs["msp_type"]) msp_config_dir = fabric_cfg_path + fmt.Sprint(configs["msp_config_dir"]) @@ -257,7 +257,7 @@ func ReadConfigs() error { fmt.Println(" ### Configs ") fmt.Println(" ROOT = ", ROOT) - fmt.Println(" FABRIC_CFG_PATH = ",configs["fabric_cfg_path"]) + fmt.Println(" PEER_CONFIG_PATH = ",configs["peer_config_path"]) fmt.Println(" MSP ID = ",configs["msp_id"]) fmt.Println(" MSP TYPE = ",configs["msp_type"]) fmt.Println(" MSP CONFIG DIR = ",configs["msp_config_dir"]) From cf6f625dbe5e7bdf2f864a4b1d486d2614ac7f61 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Wed, 26 Feb 2020 19:37:56 +0200 Subject: [PATCH 17/28] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e670b83..f90a2a0 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@

N|Solid

OffChain Data is a sample demonstration to understand the concept of implmenting offchain storage and it's capability in Hyperledger fabric Blockchain network. So, this project will work as a peer block event listener and will store the block details in the CouchDB that be query through MapReduce.

+

Medium writeup : https://medium.com/@deeptiman/offchain-storage-in-hyperledger-fabric-77e28bd99e0c +

Configuration requirements

You need to add the certain project details in `config.json`, so that it will be used to create an event listener and the Blocks will be received through GRPC delivery From 1150306e3ee56054b6754646589642548dfbf1f9 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Sat, 29 Feb 2020 03:28:53 +0200 Subject: [PATCH 18/28] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f90a2a0..2c9f280 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

OffChain Data

N|Solid

-

OffChain Data is a sample demonstration to understand the concept of implmenting offchain storage and it's capability in Hyperledger fabric Blockchain network. +

OffChain Data is a sample demonstration to understand the concept of implementing offchain storage and it's capability in Hyperledger fabric Blockchain network. So, this project will work as a peer block event listener and will store the block details in the CouchDB that be query through MapReduce.

Medium writeup : https://medium.com/@deeptiman/offchain-storage-in-hyperledger-fabric-77e28bd99e0c From 6d7af6651e86bc284e9b30382110868ca70d012b Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Sun, 31 May 2020 19:04:00 +0300 Subject: [PATCH 19/28] Add files via upload --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f83dbc6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Deeptiman Pattnaik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file From 31101024d7bb931c0bd58b312b8689bf1336cc79 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Sun, 31 May 2020 19:04:40 +0300 Subject: [PATCH 20/28] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2c9f280..c378381 100644 --- a/README.md +++ b/README.md @@ -93,3 +93,5 @@ curl -X GET http://127.0.0.1:5990/offchaindb/_design/emailviewdesign/_view/email So, all the query peformed in offchain without querying from blockchain ledger. +

License

+

This project is licensed under the MIT License

From 8cbe5857bd1173fa5db0d9f55381e1175b27add6 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Fri, 19 Jun 2020 16:50:32 +0300 Subject: [PATCH 21/28] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c378381..75c63f6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@

OffChain Data

+

GitHub last commit GitHub language count GitHub top language

N|Solid

OffChain Data is a sample demonstration to understand the concept of implementing offchain storage and it's capability in Hyperledger fabric Blockchain network. So, this project will work as a peer block event listener and will store the block details in the CouchDB that be query through MapReduce.

From fe841433641059cdeab59a5b34751b5f454ec634 Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Sun, 2 Aug 2020 23:35:02 +0530 Subject: [PATCH 22/28] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 75c63f6..6ce32b0 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

GitHub last commit GitHub language count GitHub top language

N|Solid

OffChain Data is a sample demonstration to understand the concept of implementing offchain storage and it's capability in Hyperledger fabric Blockchain network. - So, this project will work as a peer block event listener and will store the block details in the CouchDB that be query through MapReduce.

+ So, this project will work as a peer block event listener and will store the block details in the CouchDB that can be query through MapReduce.

Medium writeup : https://medium.com/@deeptiman/offchain-storage-in-hyperledger-fabric-77e28bd99e0c From b42587feadbc442b091abbe22255735d853ba84e Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Mon, 3 Aug 2020 02:22:47 +0530 Subject: [PATCH 23/28] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ce32b0..743d364 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

OffChain Data

-

GitHub last commit GitHub language count GitHub top language

+

GitHub last commit GitHub language count GitHub top languageGitHub forks

N|Solid

OffChain Data is a sample demonstration to understand the concept of implementing offchain storage and it's capability in Hyperledger fabric Blockchain network. So, this project will work as a peer block event listener and will store the block details in the CouchDB that can be query through MapReduce.

From 46fc74ac5d7771b5c479c1d676abeea28bc6ce9b Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Mon, 3 Aug 2020 02:23:27 +0530 Subject: [PATCH 24/28] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 743d364..6ce32b0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

OffChain Data

-

GitHub last commit GitHub language count GitHub top languageGitHub forks

+

GitHub last commit GitHub language count GitHub top language

N|Solid

OffChain Data is a sample demonstration to understand the concept of implementing offchain storage and it's capability in Hyperledger fabric Blockchain network. So, this project will work as a peer block event listener and will store the block details in the CouchDB that can be query through MapReduce.

From c556b30ff22c25274c58472908ae48e11be6f48c Mon Sep 17 00:00:00 2001 From: Deeptiman Pattnaik Date: Sat, 3 Apr 2021 00:05:41 +0530 Subject: [PATCH 25/28] Add files via upload --- go.mod | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 go.mod diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..86faba6 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module offchaindata + +go 1.13 From 282adc93e4efd1527c3eb21472b1c47b33e2afab Mon Sep 17 00:00:00 2001 From: Deeptiman Date: Sat, 8 May 2021 14:54:11 +0530 Subject: [PATCH 26/28] Dependency issues fix! --- .gitignore | 2 ++ Gopkg.toml | 5 ----- LICENSE | 21 --------------------- couchdb.go | 2 +- dependency.sh | 4 ++++ eventlistener.go | 2 +- go.mod | 3 --- 7 files changed, 8 insertions(+), 31 deletions(-) delete mode 100755 Gopkg.toml delete mode 100644 LICENSE create mode 100755 dependency.sh delete mode 100644 go.mod diff --git a/.gitignore b/.gitignore index 987014e..eadb521 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ vendor offchaindata +go.mod +go.sum diff --git a/Gopkg.toml b/Gopkg.toml deleted file mode 100755 index d4822f9..0000000 --- a/Gopkg.toml +++ /dev/null @@ -1,5 +0,0 @@ -[[constraint]] - # Release v1.0.0-alpha4 - name = "github.com/hyperledger/fabric-sdk-go" - #revision = "a906355f73d060d7bf95874a9e90dc17589edbb3" - revision = "e00befbefdb6deb06b59a697c42e0f3147c91b7e" diff --git a/LICENSE b/LICENSE deleted file mode 100644 index f83dbc6..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Deeptiman Pattnaik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/couchdb.go b/couchdb.go index 56a5f6c..90d231e 100644 --- a/couchdb.go +++ b/couchdb.go @@ -24,7 +24,7 @@ func SaveToCouchDB(kvWriteSet []byte) error{ return errors.WithMessage(err,"failed to set couchdb: ") } - db := client.DB(context.TODO(), dbName) + db := client.DB(dbName) User := &SampleUser{} err = json.Unmarshal(kvWriteSet, User) diff --git a/dependency.sh b/dependency.sh new file mode 100755 index 0000000..bc69145 --- /dev/null +++ b/dependency.sh @@ -0,0 +1,4 @@ +go mod init +go get github.com/hyperledger/fabric@v1.3.0 +go get github.com/hyperledger/fabric-sdk-go@v1.0.0-beta1 +go mod vendor \ No newline at end of file diff --git a/eventlistener.go b/eventlistener.go index 9b3cc39..17af152 100644 --- a/eventlistener.go +++ b/eventlistener.go @@ -244,7 +244,7 @@ func ReadConfigs() error { var configs map[string]interface{} json.Unmarshal([]byte(byteValue), &configs) - peer_config_path = ROOT + fmt.Sprint(configs["peer_config_path"]) + //peer_config_path := ROOT + fmt.Sprint(configs["peer_config_path"]) msp_id = fmt.Sprint(configs["msp_id"]) msp_type = fmt.Sprint(configs["msp_type"]) msp_config_dir = fabric_cfg_path + fmt.Sprint(configs["msp_config_dir"]) diff --git a/go.mod b/go.mod deleted file mode 100644 index 86faba6..0000000 --- a/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module offchaindata - -go 1.13 From e6929af5d8fd84c4d23c9f3a0e0d4f616a4313db Mon Sep 17 00:00:00 2001 From: Deeptiman Date: Sat, 8 May 2021 15:02:14 +0530 Subject: [PATCH 27/28] Dependency issues fix! --- download.sh | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100755 download.sh diff --git a/download.sh b/download.sh deleted file mode 100755 index d789ebf..0000000 --- a/download.sh +++ /dev/null @@ -1,12 +0,0 @@ -go get -v github.com/Shopify/sarama -go get -v github.com/hashicorp/go-version -go get -v github.com/onsi/ginkgo -go get -v github.com/onsi/gomega -go get -v github.com/spf13/cobra -go get -v github.com/syndtr/goleveldb/leveldb -go get -v github.com/syndtr/goleveldb/leveldb/iterator -go get -v github.com/syndtr/goleveldb/leveldb/opt -go get -v github.com/syndtr/goleveldb/leveldb/util -go get -v github.com/tedsuo/ifrit -go get -v github.com/willf/bitset -go get -v golang.org/x/sync/semaphore From a592377a510f1046ba637fd9c49ce7e22cf885df Mon Sep 17 00:00:00 2001 From: Deeptiman Date: Tue, 15 Jun 2021 02:26:47 +0530 Subject: [PATCH 28/28] Dependency fix --- dependency.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dependency.sh b/dependency.sh index bc69145..c34f933 100755 --- a/dependency.sh +++ b/dependency.sh @@ -1,4 +1,5 @@ go mod init go get github.com/hyperledger/fabric@v1.3.0 go get github.com/hyperledger/fabric-sdk-go@v1.0.0-beta1 +go get github.com/willf/bitset@v1.1.11 go mod vendor \ No newline at end of file