diff --git a/.gitignore b/.gitignore index 6919373ec..674a4962e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ cscope.* common/protos internal/protos coverage.out +vendor diff --git a/.gitmodules b/.gitmodules index 7b7664e3b..7b287dcaa 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,6 +5,3 @@ [submodule "common/crypto/pdo"] path = common/crypto/pdo url = https://github.com/hyperledger-labs/private-data-objects -[submodule "samples/deployment/test-network/fabric-samples"] - path = samples/deployment/test-network/fabric-samples - url = https://github.com/hyperledger/fabric-samples.git diff --git a/build.mk b/build.mk index 98bd2b4ff..eb55efe39 100644 --- a/build.mk +++ b/build.mk @@ -9,6 +9,8 @@ include $(TOP)/config.mk # define composites only here and not in config.mk so we can override parts in config.override.mk DOCKER := $(DOCKER_CMD) $(DOCKERFLAGS) +DOCKER_COMPOSE := $(DOCKER_CMD) compose + ifeq (${SGX_MODE}, HW) GOTAGS = -tags sgx_hw_mode endif diff --git a/commands.sh b/commands.sh new file mode 100755 index 000000000..b81ce3f03 --- /dev/null +++ b/commands.sh @@ -0,0 +1,97 @@ +# ############################## Commands in order ####################################### + + +# ################################### For CC-tools inside the fpc + +# - Copy all chaincode files using the same way as simple-asset-go +# - replace the "CHAINCODE_ID" env with "CHAINCODE_PKG_ID" in main.go +# - Run `go get` inside the cc-tools-demo folder after putting it inside the fpc repo +# ------ There are huge problem with using FPC outside the FPC repository. Even go get doesn't work and you need to specify a certain version and there are conflicting packages-----------------' +# # - You have to add dummy implementation for the PurgePrivate data method in the MockStup of cc-tools but be careful you need to do it in the package installed inside the FPC dev env not your local +# # For example do: vim /project/pkg/mod/github.com/hyperledger-labs/cc-tools@v1.0.0/mock/mockstub.go and add this: +# # // PurgePrivateData ... +# # func (stub *MockStub) PurgePrivateData(collection, key string) error { +# # return errors.New("Not Implemented") +# # }. +# # A good idea is to use go mod vendor and download all go packages in the vendor directory and edit it one time there. +# # nano $FPC_PATH/vendor/github.com/hyperledger-labs/cc-tools/mock/mockstub.go +# # // PurgePrivateData ... +# # func (stub *MockStub) PurgePrivateData(collection, key string) error { +# # return errors.New("Not Implemented") +# # } + +cd $FPC_PATH/samples/deployment/test-network +docker compose down + +cd $FPC_PATH/samples/deployment/test-network/fabric-samples/test-network +./network.sh down +docker system prune +sleep 5 + +cd $FPC_PATH/samples/chaincode/cc-tools-demo/ +export CC_NAME=fpc-cc-tools-demo +make + +# - run docker images | grep fpc-cc-tools-demo to make sure of the image +# - complete the tutorial normally: +cd $FPC_PATH/samples/deployment/test-network +./setup.sh + +cd $FPC_PATH/samples/deployment/test-network/fabric-samples/test-network +./network.sh up createChannel -ca -c mychannel +sleep 5 + +export CC_ID=cc-tools-demo +export CC_PATH="$FPC_PATH/samples/chaincode/cc-tools-demo/" +export CC_VER=$(cat "$FPC_PATH/samples/chaincode/cc-tools-demo/mrenclave") + +cd $FPC_PATH/samples/deployment/test-network +./installFPC.sh +sleep 5 +make ercc-ecc-start +sleep 5 + +# # prepare connections profile +cd $FPC_PATH/samples/deployment/test-network +./update-connection.sh + +# # update the connection profile for external clients outside the fpc dev environment +cd $FPC_PATH/samples/deployment/test-network +./update-external-connection.sh + +# make fpcclient +cd $FPC_PATH/samples/application/simple-cli-go +make + +# export fpcclient settings +export CC_NAME=cc-tools-demo +export CHANNEL_NAME=mychannel +export CORE_PEER_ADDRESS=localhost:7051 +export CORE_PEER_ID=peer0.org1.example.com +export CORE_PEER_LOCALMSPID=Org1MSP +export CORE_PEER_MSPCONFIGPATH=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp +export CORE_PEER_TLS_CERT_FILE=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt +export CORE_PEER_TLS_ENABLED="true" +export CORE_PEER_TLS_KEY_FILE=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key +export CORE_PEER_TLS_ROOTCERT_FILE=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt +export ORDERER_CA=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem +export GATEWAY_CONFIG=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/connection-org1.yaml + +sleep 5 +# init our enclave +./fpcclient init $CORE_PEER_ID +sleep 5 +# invoke the getSchema transaction which is implemented internally by cc-tools +./fpcclient invoke getSchema + +########################## Some transactions to test #################################### +# sleep 5 +# ./fpcclient invoke createNewLibrary "{\"name\":\"samuel\"}" +# sleep 5 +# ./fpcclient invoke createAsset "{\"asset\":[{\"@assetType\":\"person\",\"id\":\"51027337023\",\"name\":\"samuel\"}]}" +# sleep 5 +# ./fpcclient invoke createAsset "{\"asset\":[{\"@assetType\":\"book\", \"title\": \"Fairy tail\" ,\"author\":\"Martin\",\"currentTenant\":{\"@assetType\": \"person\", \"@key\": \"person:f6c10e69-32ae-5dfb-b17e-9eda4a039cee\"}}]}" +# sleep 5 +# ./fpcclient invoke getBooksByAuthor "{\"authorName\":\"samuel\"}" # --> Fails as GetQueryResult is not implemented. I tried to implement it but the fabric implementation needs what's called handler and it's not ther + + diff --git a/ecc_go/build.mk b/ecc_go/build.mk index 70d7aee2b..30a5918ff 100644 --- a/ecc_go/build.mk +++ b/ecc_go/build.mk @@ -20,7 +20,7 @@ ECC_BUNDLE ?= $(ECC_BINARY)-bundle build: ecc docker env ecc: ecc_dependencies - ego-go build $(GOTAGS) -o $(ECC_BINARY) main.go + ego-go build $(GOTAGS) -o $(ECC_BINARY) cp $(EGO_CONFIG_FILE) . ego sign ego uniqueid $(ECC_BINARY) > mrenclave diff --git a/ecc_go/chaincode/enclave_go/shim.go b/ecc_go/chaincode/enclave_go/shim.go index 86d40ea37..73b6a55a1 100644 --- a/ecc_go/chaincode/enclave_go/shim.go +++ b/ecc_go/chaincode/enclave_go/shim.go @@ -8,9 +8,12 @@ SPDX-License-Identifier: Apache-2.0 package enclave_go import ( + "fmt" + "github.com/hyperledger/fabric-chaincode-go/shim" "github.com/hyperledger/fabric-private-chaincode/internal/utils" pb "github.com/hyperledger/fabric-protos-go/peer" + "github.com/pkg/errors" timestamp "google.golang.org/protobuf/types/known/timestamppb" ) @@ -177,7 +180,11 @@ func (f *FpcStubInterface) SplitCompositeKey(compositeKey string) (string, []str } func (f *FpcStubInterface) GetQueryResult(query string) (shim.StateQueryIteratorInterface, error) { - panic("not implemented") // TODO: Implement + it, err := f.stub.GetQueryResult(query) + if err != nil { + return it, errors.Wrap(err, "stub.GetQueryResult call error") + } + return it, nil } func (f *FpcStubInterface) GetQueryResultWithPagination(query string, pageSize int32, bookmark string) (shim.StateQueryIteratorInterface, *pb.QueryResponseMetadata, error) { @@ -233,7 +240,7 @@ func (f *FpcStubInterface) GetCreator() ([]byte, error) { } func (f *FpcStubInterface) GetTransient() (map[string][]byte, error) { - panic("not implemented") // TODO: Implement + return nil, nil } func (f *FpcStubInterface) GetBinding() ([]byte, error) { @@ -248,10 +255,28 @@ func (f *FpcStubInterface) GetSignedProposal() (*pb.SignedProposal, error) { return f.stub.GetSignedProposal() } -func (f *FpcStubInterface) GetTxTimestamp() (*timestamp.Timestamp, error) { - panic("not implemented") // TODO: Implement +// GetTxTimestamp documentation can be found in interfaces.go +func (s *FpcStubInterface) GetTxTimestamp() (*timestamp.Timestamp, error) { + // hdr := &common.Header{} + // if err := proto.Unmarshal(s.proposal.Header, hdr); err != nil { + // return nil, fmt.Errorf("error unmarshaling Header: %s", err) + // } + + // chdr := &common.ChannelHeader{} + // if err := proto.Unmarshal(hdr.ChannelHeader, chdr); err != nil { + // return nil, fmt.Errorf("error unmarshaling ChannelHeader: %s", err) + // } + // return chdr.GetTimestamp(), nil + println(timestamp.Now()) + return timestamp.Now(), nil + } func (f *FpcStubInterface) SetEvent(name string, payload []byte) error { - panic("not implemented") // TODO: Implement + if name == "" { + return errors.New("event name can not be empty string") + } + fmt.Println("Trying to set event name: ", name, "\n with payload: ", payload) + fmt.Println("NO event is bieng set as function is not implemented yet") + return nil } diff --git a/ecc_go/enclave.json b/ecc_go/enclave.json index e4ccc2de1..5ffe012ca 100644 --- a/ecc_go/enclave.json +++ b/ecc_go/enclave.json @@ -16,6 +16,14 @@ "name": "CHAINCODE_PKG_ID", "fromHost": true }, + { + "name": "FPC_ENABLED", + "fromHost": true + }, + { + "name": "RUN_CCAAS", + "fromHost": true + }, { "name": "FABRIC_LOGGING_SPEC", "fromHost": true diff --git a/go.mod b/go.mod index 0150ae9b2..89973331a 100644 --- a/go.mod +++ b/go.mod @@ -22,12 +22,16 @@ replace google.golang.org/grpc => google.golang.org/grpc v1.29.1 require ( github.com/client9/misspell v0.3.4 + github.com/gin-contrib/cors v1.7.2 + github.com/gin-gonic/gin v1.10.0 github.com/golang/protobuf v1.5.3 - github.com/hyperledger/fabric v1.4.0-rc1.0.20230405174026-695dd57e01c2 + github.com/hyperledger-labs/cc-tools v1.0.0 + github.com/hyperledger/fabric v2.1.1+incompatible github.com/hyperledger/fabric-chaincode-go v0.0.0-20230228194215-b84622ba6a7a github.com/hyperledger/fabric-contract-api-go v1.2.1 + github.com/hyperledger/fabric-gateway v1.5.1 github.com/hyperledger/fabric-protos-go v0.3.0 - github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go v0.0.0-20230505123407-84f9ba1dc4ec + github.com/hyperledger/fabric-protos-go-apiv2 v0.3.3 github.com/hyperledger/fabric-sdk-go v1.0.1-0.20221020141211-7af45cede6af github.com/maxbrunsfeld/counterfeiter/v6 v6.6.1 github.com/onsi/ginkgo v1.16.5 @@ -35,10 +39,14 @@ require ( github.com/onsi/gomega v1.27.8 github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.7.0 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 + github.com/swaggo/files v1.0.1 + github.com/swaggo/gin-swagger v1.6.0 + github.com/swaggo/swag v1.16.3 golang.org/x/sync v0.5.0 golang.org/x/tools v0.14.0 - google.golang.org/protobuf v1.33.0 + google.golang.org/grpc v1.63.2 + google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v2 v2.4.0 honnef.co/go/tools v0.4.3 ) @@ -46,21 +54,17 @@ require ( require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/BurntSushi/toml v1.2.1 // indirect - github.com/IBM/idemix v0.0.2-0.20231107110441-534ea4193b8f // indirect - github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20231107110234-4cf31dd43660 // indirect - github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20231107110234-4cf31dd43660 // indirect - github.com/IBM/idemix/bccsp/types v0.0.0-20231107110234-4cf31dd43660 // indirect - github.com/IBM/mathlib v0.0.3-0.20231011094432-44ee0eb539da // indirect github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect + github.com/KyleBanks/depth v1.2.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20231023164747-f3f972769504 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.7.0 // indirect + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cloudflare/cfssl v1.4.1 // indirect - github.com/consensys/bavard v0.1.13 // indirect - github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect github.com/containerd/containerd v1.7.13 // indirect github.com/containerd/log v0.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -69,6 +73,8 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fsouza/go-dockerclient v1.10.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-kit/kit v0.10.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.3.0 // indirect @@ -76,15 +82,20 @@ require ( github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/spec v0.20.8 // indirect github.com/go-openapi/swag v0.21.1 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gobuffalo/envy v1.10.1 // indirect github.com/gobuffalo/packd v1.0.1 // indirect github.com/gobuffalo/packr v1.30.1 // indirect + github.com/goccy/go-json v0.10.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.6.0 // indirect github.com/google/certificate-transparency-go v1.0.21 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect + github.com/google/uuid v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2 // indirect @@ -93,24 +104,29 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/joho/godotenv v1.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/kilic/bls12-381 v0.1.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect - github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/sys/user v0.1.0 // indirect github.com/moby/term v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.17.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect @@ -125,6 +141,8 @@ require ( github.com/spf13/viper v1.10.1 // indirect github.com/subosito/gotenv v1.2.0 // indirect github.com/sykesm/zap-logfmt v0.0.4 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect github.com/weppos/publicsuffix-go v0.5.0 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect @@ -133,17 +151,16 @@ require ( github.com/zmap/zlint v0.0.0-20190806154020-fd021b4cfbeb // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.25.0 // indirect - golang.org/x/crypto v0.22.0 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.23.0 // indirect golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect - google.golang.org/grpc v1.59.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect gopkg.in/ini.v1 v1.66.2 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect - rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index c8b6029d2..a08c571c3 100644 --- a/go.sum +++ b/go.sum @@ -9,33 +9,22 @@ github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= -github.com/IBM/idemix v0.0.2-0.20231107110441-534ea4193b8f h1:SFWg5b/I49LcVurx/v7MFwQ4t/0wTX6TlPzxhEYEr3U= -github.com/IBM/idemix v0.0.2-0.20231107110441-534ea4193b8f/go.mod h1:nOEyL+adzVsbzAKiDV3/Qcn703tN6cdgGmVyXIfEhWg= -github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20231107110234-4cf31dd43660 h1:Np3oYfF4a6SNtiPJCP8AQ5QDpajkT8UfWTkdlh3DfPQ= -github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20231107110234-4cf31dd43660/go.mod h1:hO4IoGeT6yuwCduXpnvV4fskpjJi28ipZChV861S96E= -github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20231107110234-4cf31dd43660 h1:rdnFfRbHThWOzGcS7vR/iH67Pa9DeevsuOCHoE7dOi4= -github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20231107110234-4cf31dd43660/go.mod h1:FC0vVgNI6bv8GH0VTwjup+arwJ8Tau1iEhroWZ1oPwU= -github.com/IBM/idemix/bccsp/types v0.0.0-20231107110234-4cf31dd43660 h1:WFXPDH/S08C+/2gsV9982+Sc2FZX8ZLEpXbOS4u/pfY= -github.com/IBM/idemix/bccsp/types v0.0.0-20231107110234-4cf31dd43660/go.mod h1:IMIJ8WcUpBmV4gcOO/BYKuFYpdXCPYZjpNhFSUlO9b8= -github.com/IBM/mathlib v0.0.3-0.20231011094432-44ee0eb539da h1:qqGozq4tF6EOVnWoTgBoJGudRKKZXSAYnEtDggzTnsw= -github.com/IBM/mathlib v0.0.3-0.20231011094432-44ee0eb539da/go.mod h1:Tco9QzE3fQzjMS7nPbHDeFfydAzctStf1Pa8hsh6Hjs= github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= +github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/SmartBFT-Go/consensus v0.0.0-20230212211744-e5a79afcea81 h1:yiyJRAf/rsEu3Sl0ATWu1zREfyaj01i9VsPbGiXzZZw= -github.com/SmartBFT-Go/consensus v0.0.0-20230212211744-e5a79afcea81/go.mod h1:ZOD/ZiAdH9HpqdsJLlUTlbzYBr/qYEzyYx7wClbrH+w= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20231023164747-f3f972769504 h1:sQyFeDcHVHWJ3IeE437NSJjv0+J/6MvGQOJew4X+Cuw= -github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20231023164747-f3f972769504/go.mod h1:z5xq4Ji1RQojJLZzKeZH5+LKCVZxgQRZpQ4xAJWi8r0= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -58,10 +47,10 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo= -github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -77,13 +66,13 @@ github.com/cloudflare/cfssl v1.4.1 h1:vScfU2DrIUI9VPHBVeeAQ0q5A+9yshO1Gz+3QoUQiK github.com/cloudflare/cfssl v1.4.1/go.mod h1:KManx/OJPb5QY+y0+o/898AMcM128sF0bURvoVUSjTo= github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4= github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= -github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= -github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/containerd/containerd v1.7.13 h1:wPYKIeGMN8vaggSKuV1X0wZulpMz4CrgEsZdaCyB6Is= github.com/containerd/containerd v1.7.13/go.mod h1:zT3up6yTRfEUa6+GsITYIJNgSVL9NQ4x4h1RPzk0Wu4= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= @@ -112,8 +101,11 @@ github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6 github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -127,8 +119,18 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsouza/go-dockerclient v1.10.0 h1:ppSBsbR60I1DFbV4Ag7LlHlHakHFRNLk9XakATW1yVQ= github.com/fsouza/go-dockerclient v1.10.0/go.mod h1:+iNzAW78AzClIBTZ6WFjkaMvOgz68GyCJ236b1opLTs= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw= +github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E= +github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= +github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= @@ -152,6 +154,14 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU= github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= @@ -169,6 +179,8 @@ github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -194,6 +206,7 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -210,8 +223,9 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -234,6 +248,7 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -246,8 +261,10 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/hyperledger/fabric v1.4.0-rc1.0.20230405174026-695dd57e01c2 h1:w5BGxCYEsc9vjdDEdZGrZ5redvs263RYsdT2tqF7cNk= -github.com/hyperledger/fabric v1.4.0-rc1.0.20230405174026-695dd57e01c2/go.mod h1:LSwfuRgX/5C2uHkdT3hJtBFu/ALxuL7dFj1pmBby2R4= +github.com/hyperledger-labs/cc-tools v1.0.0 h1:o9cX7CWLKzgGhS42iUFRY37OEElIyfU5E9Z1C55Fzzg= +github.com/hyperledger-labs/cc-tools v1.0.0/go.mod h1:NQyK1wndA/L5EeKqzhLlLGrsfSQJbsvjxbaFiaE6XCI= +github.com/hyperledger/fabric v2.1.1+incompatible h1:cYYRv3vVg4kA6DmrixLxwn1nwBEUuYda8DsMwlaMKbY= +github.com/hyperledger/fabric v2.1.1+incompatible/go.mod h1:tGFAOCT696D3rG0Vofd2dyWYLySHlh0aQjf7Q1HAju0= github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2 h1:B1Nt8hKb//KvgGRprk0h1t4lCnwhE9/ryb1WqfZbV+M= github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2/go.mod h1:X+DIyUsaTmalOpmpQfIvFZjKHQedrURQ5t4YqquX7lE= github.com/hyperledger/fabric-chaincode-go v0.0.0-20230228194215-b84622ba6a7a h1:HwSCxEeiBthwcazcAykGATQ36oG9M+HEQvGLvB7aLvA= @@ -257,14 +274,16 @@ github.com/hyperledger/fabric-config v0.1.0 h1:TsR3y5xEoUmXWfp8tcDycjJhVvXEHiV5k github.com/hyperledger/fabric-config v0.1.0/go.mod h1:aeDZ0moG/qKvwLjddcqYr8+58/oNaJy3HE0tI01546c= github.com/hyperledger/fabric-contract-api-go v1.2.1 h1:Ww9cKH/qHl5s6WqF+Ts5ju5eaBxC/awB/BJE+rOsEkM= github.com/hyperledger/fabric-contract-api-go v1.2.1/go.mod h1:BhWve0gz1iH+Xc+cO3rmeIZI7YaTWOQodka9CgeUOgo= +github.com/hyperledger/fabric-gateway v1.5.1 h1:UPsOFeRMttoB6X9K4G7gGxZvYMD3mw2aRG3ax5BqMUA= +github.com/hyperledger/fabric-gateway v1.5.1/go.mod h1:8O73LAlilYkPecNrENq8zbXPKXT6beMRYSGVE62QXRE= github.com/hyperledger/fabric-lib-go v1.0.0 h1:UL1w7c9LvHZUSkIvHTDGklxFv2kTeva1QI2emOVc324= github.com/hyperledger/fabric-lib-go v1.0.0/go.mod h1:H362nMlunurmHwkYqR5uHL2UDWbQdbfz74n8kbCFsqc= github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-protos-go v0.0.0-20211118165945-23d738fc3553/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-protos-go v0.3.0 h1:MXxy44WTMENOh5TI8+PCK2x6pMj47Go2vFRKDHB2PZs= github.com/hyperledger/fabric-protos-go v0.3.0/go.mod h1:WWnyWP40P2roPmmvxsUXSvVI/CF6vwY1K1UFidnKBys= -github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go v0.0.0-20230505123407-84f9ba1dc4ec h1:drq6iuHjLc3H41zGfvljRZky45aLsWfc/J/lc52KjLY= -github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go v0.0.0-20230505123407-84f9ba1dc4ec/go.mod h1:Y4ClFGIk5nmTlFOtryAY+sC55tYCpA6YZItPaKwPY6s= +github.com/hyperledger/fabric-protos-go-apiv2 v0.3.3 h1:Xpd6fzG/KjAOHJsq7EQXY2l+qi/y8muxBaY7R6QWABk= +github.com/hyperledger/fabric-protos-go-apiv2 v0.3.3/go.mod h1:2pq0ui6ZWA0cC8J+eCErgnMDCS1kPOEYVY+06ZAK0qE= github.com/hyperledger/fabric-sdk-go v1.0.1-0.20221020141211-7af45cede6af h1:/DGxnlhN6Cg1PKj/5K01GUt4X1wN8nRVkZiJiQ05sCw= github.com/hyperledger/fabric-sdk-go v1.0.1-0.20221020141211-7af45cede6af/go.mod h1:JRplpKBeAvXjsBhOCCM/KvMRUbdDyhsAh80qbXzKc10= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -284,11 +303,11 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= -github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -296,6 +315,10 @@ github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCy github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -308,8 +331,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28/go.mod h1:T/T7jsxVqf9k/zYOqbgNAsANsjxTd1Yq3htjDhQ1H0c= -github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v0.0.0-20180201184707-88edab080323/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= @@ -325,6 +348,8 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -347,9 +372,6 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= -github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= -github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= @@ -361,9 +383,12 @@ github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4 github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= @@ -416,8 +441,11 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -453,6 +481,7 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -505,22 +534,38 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= +github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= +github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M= +github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo= +github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg= +github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk= github.com/sykesm/zap-logfmt v0.0.4 h1:U2WzRvmIWG1wDLCFY3sz8UeEmsdHQjHFNlIdmroVFaI= github.com/sykesm/zap-logfmt v0.0.4/go.mod h1:AuBd9xQjAe3URrWT1BBDk2v2onAZHkZkWRMiYZXiZWA= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -540,6 +585,7 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= @@ -558,6 +604,8 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -570,6 +618,9 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -581,8 +632,9 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a h1:Jw5wfR+h9mnIYH+OtGT2im5wV1YGGDora5vTv/aa5bE= golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -595,6 +647,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -615,9 +668,12 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -628,6 +684,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -651,26 +708,34 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -692,6 +757,7 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -707,8 +773,8 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -719,8 +785,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -757,9 +823,9 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw= honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/internal/protos/fpc.pb.go b/internal/protos/fpc.pb.go index 842fccdaf..6de669c8b 100644 --- a/internal/protos/fpc.pb.go +++ b/internal/protos/fpc.pb.go @@ -5,8 +5,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.33.0 +// protoc v4.22.3 // source: fpc/fpc.proto package protos diff --git a/internal/protos/key_dist.pb.go b/internal/protos/key_dist.pb.go index 25634cbf2..5d2eb7e1d 100644 --- a/internal/protos/key_dist.pb.go +++ b/internal/protos/key_dist.pb.go @@ -5,8 +5,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.33.0 +// protoc v4.22.3 // source: fpc/key_dist.proto package protos diff --git a/internal/protos/tl_session/tl_session.pb.go b/internal/protos/tl_session/tl_session.pb.go index d581eefe1..3b69041c8 100644 --- a/internal/protos/tl_session/tl_session.pb.go +++ b/internal/protos/tl_session/tl_session.pb.go @@ -5,8 +5,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.33.0 +// protoc v4.22.3 // source: fpc/tl_session.proto package tl_session diff --git a/internal/protos/trusted_ledger.pb.go b/internal/protos/trusted_ledger.pb.go index 7bbeff8be..ad7c9b22e 100644 --- a/internal/protos/trusted_ledger.pb.go +++ b/internal/protos/trusted_ledger.pb.go @@ -5,8 +5,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.33.0 +// protoc v4.22.3 // source: fpc/trusted_ledger.proto package protos diff --git a/samples/application/ccapi/.gitignore b/samples/application/ccapi/.gitignore new file mode 100644 index 000000000..d807ed32f --- /dev/null +++ b/samples/application/ccapi/.gitignore @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 +**/wallet/* +**/keystore/* +fpcclient +simple-cli-go diff --git a/samples/application/ccapi/Dockerfile b/samples/application/ccapi/Dockerfile new file mode 100644 index 000000000..6a62d7669 --- /dev/null +++ b/samples/application/ccapi/Dockerfile @@ -0,0 +1,11 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +ARG FPC_VERSION=main + +FROM hyperledger/fabric-private-chaincode-ccenv:${FPC_VERSION} + +COPY fpcclient /usr/local/bin + +WORKDIR /opt/gopath/src/github.com/hyperledger/fabric/peer diff --git a/samples/application/ccapi/Makefile b/samples/application/ccapi/Makefile new file mode 100644 index 000000000..286198d6a --- /dev/null +++ b/samples/application/ccapi/Makefile @@ -0,0 +1,20 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +TOP = ../../.. +include $(TOP)/build.mk + +GO_BUILD_OPT ?= + +build: + $(GO) build $(GO_BUILD_OPT) $(GOTAGS) -o fpcclient + +DOCKER_BUILD_OPTS += --build-arg FPC_VERSION=$(FPC_VERSION) +DOCKER_BUILD_OPTS += --no-cache + +docker: + $(DOCKER) build $(DOCKER_BUILD_OPTS) \ + -t fpc/fpcclient:$(FPC_VERSION) \ + -f Dockerfile \ + . diff --git a/samples/application/ccapi/api/init.go b/samples/application/ccapi/api/init.go new file mode 100644 index 000000000..155b538f5 --- /dev/null +++ b/samples/application/ccapi/api/init.go @@ -0,0 +1,17 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package api + +import ( + "github.com/hyperledger/fabric-private-chaincode/samples/application/cc-tools-demo/pkg" +) + +func InitEnclave() error { + admin := pkg.NewAdmin(config) + defer admin.Close() + return admin.InitEnclave(config.CorePeerId) +} diff --git a/samples/application/ccapi/api/invoke.go b/samples/application/ccapi/api/invoke.go new file mode 100644 index 000000000..d9df0009e --- /dev/null +++ b/samples/application/ccapi/api/invoke.go @@ -0,0 +1,19 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package api + +import ( + "fmt" + + "github.com/hyperledger/fabric-private-chaincode/samples/application/cc-tools-demo/pkg" +) + +func InvokeTransaction(args []string) { + client := pkg.NewClient(config) + res := client.Invoke(args[0], args[1:]...) + fmt.Println("~> " + res) +} diff --git a/samples/application/ccapi/api/query.go b/samples/application/ccapi/api/query.go new file mode 100644 index 000000000..91fafde07 --- /dev/null +++ b/samples/application/ccapi/api/query.go @@ -0,0 +1,20 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package api + +import ( + "fmt" + + "github.com/hyperledger/fabric-private-chaincode/samples/application/cc-tools-demo/pkg" +) + +func QueryTransaction(args []string) { + client := pkg.NewClient(config) + res := client.Query(args[0], args[1:]...) + fmt.Println("~> " + res) + +} diff --git a/samples/application/ccapi/api/root.go b/samples/application/ccapi/api/root.go new file mode 100644 index 000000000..31192a9ef --- /dev/null +++ b/samples/application/ccapi/api/root.go @@ -0,0 +1,56 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package api + +import ( + "fmt" + "os" + "strconv" + + "github.com/hyperledger/fabric-private-chaincode/samples/application/cc-tools-demo/pkg" +) + +var ( + config *pkg.Config +) + +func InitConfig() { + + getStrEnv := func(key string) string { + val := os.Getenv(key) + if val == "" { + panic(fmt.Sprintf("%s not set", key)) + } + return val + } + + getBoolEnv := func(key string) bool { + val := getStrEnv(key) + ret, err := strconv.ParseBool(val) + if err != nil { + if val == "" { + panic(fmt.Sprintf("invalid bool value for %s", key)) + } + } + return ret + } + + config = &pkg.Config{ + CorePeerAddress: getStrEnv("CORE_PEER_ADDRESS"), + CorePeerId: getStrEnv("CORE_PEER_ID"), + CorePeerLocalMSPID: getStrEnv("CORE_PEER_LOCALMSPID"), + CorePeerMSPConfigPath: getStrEnv("CORE_PEER_MSPCONFIGPATH"), + CorePeerTLSCertFile: getStrEnv("CORE_PEER_TLS_CERT_FILE"), + CorePeerTLSEnabled: getBoolEnv("CORE_PEER_TLS_ENABLED"), + CorePeerTLSKeyFile: getStrEnv("CORE_PEER_TLS_KEY_FILE"), + CorePeerTLSRootCertFile: getStrEnv("CORE_PEER_TLS_ROOTCERT_FILE"), + OrdererCA: getStrEnv("ORDERER_CA"), + ChaincodeId: getStrEnv("CC_NAME"), + ChannelId: getStrEnv("CHANNEL_NAME"), + GatewayConfigPath: getStrEnv("GATEWAY_CONFIG"), + } +} diff --git a/samples/application/ccapi/main.go b/samples/application/ccapi/main.go new file mode 100644 index 000000000..b8ef5974b --- /dev/null +++ b/samples/application/ccapi/main.go @@ -0,0 +1,29 @@ +/* +Copyright IBM Corp. All Rights Reserved. +Copyright 2020 Intel Corporation + +SPDX-License-Identifier: Apache-2.0 +*/ + +package main + +import ( + api "github.com/hyperledger/fabric-private-chaincode/samples/application/cc-tools-demo/api" +) + +func main() { + api.InitConfig() + api.InitEnclave() + + //Invoking transactions + ///createNewLibrary + args := []string{"createNewLibrary", "{\"name\":\"samuel\"}"} + api.InvokeTransaction(args) + ///createNewLibrary + args = []string{"createAsset", "{\"asset\":[{\"@assetType\":\"person\",\"id\":\"51027337023\",\"name\":\"samuel\"}]}"} + api.InvokeTransaction(args) + ///createNewLibrary + args = []string{"createAsset", "{\"asset\":[{\"@assetType\":\"book\", \"title\": \"Fairy tail\" ,\"author\":\"Martin\",\"currentTenant\":{\"@assetType\": \"person\", \"@key\": \"person:f6c10e69-32ae-5dfb-b17e-9eda4a039cee\"}}]}"} + api.InvokeTransaction(args) + +} diff --git a/samples/application/ccapi/pkg/config.go b/samples/application/ccapi/pkg/config.go new file mode 100644 index 000000000..e3e48c7b2 --- /dev/null +++ b/samples/application/ccapi/pkg/config.go @@ -0,0 +1,23 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package pkg + +type Config struct { + CorePeerAddress string + CorePeerId string + CorePeerLocalMSPID string + CorePeerMSPConfigPath string + CorePeerTLSCertFile string + CorePeerTLSEnabled bool + CorePeerTLSKeyFile string + CorePeerTLSRootCertFile string + OrdererCA string + FpcPath string + ChaincodeId string + ChannelId string + GatewayConfigPath string +} diff --git a/samples/application/ccapi/pkg/connections.go b/samples/application/ccapi/pkg/connections.go new file mode 100644 index 000000000..396f08915 --- /dev/null +++ b/samples/application/ccapi/pkg/connections.go @@ -0,0 +1,41 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package pkg + +import ( + "os" + + "gopkg.in/yaml.v2" +) + +type Connections struct { + Peers map[string]struct { + Url string + } + + Orderers map[string]struct { + Url string + } +} + +func NewConnections(path string) (*Connections, error) { + connections := &Connections{} + + file, err := os.Open(path) + if err != nil { + return nil, err + } + defer file.Close() + + d := yaml.NewDecoder(file) + + if err := d.Decode(&connections); err != nil { + return nil, err + } + + return connections, nil +} diff --git a/samples/application/ccapi/pkg/fpcadmin.go b/samples/application/ccapi/pkg/fpcadmin.go new file mode 100644 index 000000000..05d2b3caa --- /dev/null +++ b/samples/application/ccapi/pkg/fpcadmin.go @@ -0,0 +1,86 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package pkg + +import ( + "fmt" + "path/filepath" + + fpcmgmt "github.com/hyperledger/fabric-private-chaincode/client_sdk/go/pkg/client/resmgmt" + "github.com/hyperledger/fabric-private-chaincode/client_sdk/go/pkg/sgx" + "github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt" + "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry" + cfg "github.com/hyperledger/fabric-sdk-go/pkg/core/config" + "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" +) + +type Admin struct { + sdk *fabsdk.FabricSDK + client *fpcmgmt.Client + config *Config + connections *Connections +} + +func (a *Admin) Close() { + a.sdk.Close() +} + +func NewAdmin(config *Config) *Admin { + connections, err := NewConnections(filepath.Clean(config.GatewayConfigPath)) + if err != nil { + logger.Fatalf("failed to parse connections: %v", err) + } + + sdk, err := fabsdk.New(cfg.FromFile(filepath.Clean(config.GatewayConfigPath))) + if err != nil { + logger.Fatalf("failed to create sdk: %v", err) + } + //defer sdk.Close() + + orgAdmin := "Admin" + orgName := "org1" + adminContext := sdk.Context(fabsdk.WithUser(orgAdmin), fabsdk.WithOrg(orgName)) + + client, err := fpcmgmt.New(adminContext) + if err != nil { + logger.Fatalf("failed to create context: %v", err) + } + + return &Admin{sdk: sdk, client: client, config: config, connections: connections} +} + +func (a *Admin) InitEnclave(targetPeer string) error { + + logger.Infof("--> Collection attestation params ") + attestationParams, err := sgx.CreateAttestationParamsFromEnvironment() + if err != nil { + return fmt.Errorf("failed to load attestation params from environment: %v", err) + } + + initReq := fpcmgmt.LifecycleInitEnclaveRequest{ + ChaincodeID: a.config.ChaincodeId, + EnclavePeerEndpoint: targetPeer, // define the peer where we wanna init our enclave + AttestationParams: attestationParams, + } + + peers := []string{"peer0-org1", "peer0-org2", "peer0-org3"} + orderer := "orderer0" + + logger.Infof("--> LifecycleInitEnclave ") + _, err = a.client.LifecycleInitEnclave(a.config.ChannelId, initReq, + // Note that these options are currently ignored by our implementation + resmgmt.WithRetry(retry.DefaultResMgmtOpts), + resmgmt.WithTargetEndpoints(peers...), // peers that are responsible for enclave registration + resmgmt.WithOrdererEndpoint(orderer), + ) + + if err != nil { + return err + } + + return nil +} diff --git a/samples/application/ccapi/pkg/fpcclient.go b/samples/application/ccapi/pkg/fpcclient.go new file mode 100644 index 000000000..cc3c8cdb8 --- /dev/null +++ b/samples/application/ccapi/pkg/fpcclient.go @@ -0,0 +1,124 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package pkg + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + fpc "github.com/hyperledger/fabric-private-chaincode/client_sdk/go/pkg/gateway" + cfg "github.com/hyperledger/fabric-sdk-go/pkg/core/config" + "github.com/hyperledger/fabric-sdk-go/pkg/gateway" + "github.com/pkg/errors" +) + +type Client struct { + contract fpc.Contract +} + +func NewClient(config *Config) *Client { + return &Client{contract: newContract(config)} +} + +func findSigningCert(mspConfigPath string) (string, error) { + p := filepath.Join(mspConfigPath, "signcerts") + files, err := os.ReadDir(p) + if err != nil { + return "", errors.Wrapf(err, "error while searching pem in %s", mspConfigPath) + } + + // return first pem we find + for _, f := range files { + if !f.IsDir() && strings.HasSuffix(f.Name(), ".pem") { + return filepath.Join(p, f.Name()), nil + } + } + + return "", errors.Errorf("cannot find pem in %s", mspConfigPath) +} + +func populateWallet(wallet *gateway.Wallet, config *Config) error { + logger.Debugf("============ Populating wallet ============") + certPath, err := findSigningCert(config.CorePeerMSPConfigPath) + if err != nil { + return err + } + + // read the certificate pem + cert, err := os.ReadFile(filepath.Clean(certPath)) + if err != nil { + return err + } + + keyDir := filepath.Join(config.CorePeerMSPConfigPath, "keystore") + // there's a single file in this dir containing the private key + files, err := os.ReadDir(keyDir) + if err != nil { + return err + } + if len(files) != 1 { + return fmt.Errorf("keystore folder should have contain one file") + } + keyPath := filepath.Join(keyDir, files[0].Name()) + key, err := os.ReadFile(filepath.Clean(keyPath)) + if err != nil { + return err + } + + identity := gateway.NewX509Identity(config.CorePeerLocalMSPID, string(cert), string(key)) + + return wallet.Put("appUser", identity) +} + +func newContract(config *Config) fpc.Contract { + + wallet := gateway.NewInMemoryWallet() + err := populateWallet(wallet, config) + if err != nil { + logger.Fatalf("Failed to populate wallet contents: %v", err) + } + + gw, err := gateway.Connect( + gateway.WithConfig(cfg.FromFile(filepath.Clean(config.GatewayConfigPath))), + gateway.WithIdentity(wallet, "appUser"), + ) + if err != nil { + logger.Fatalf("Failed to connect to gateway: %v", err) + } + defer gw.Close() + + network, err := gw.GetNetwork(config.ChannelId) + if err != nil { + logger.Fatalf("Failed to get network: %v", err) + } + + // Get FPC Contract + contract := fpc.GetContract(network, config.ChaincodeId) + return contract +} + +func (c *Client) Invoke(function string, args ...string) string { + logger.Debugf("--> Invoke FPC chaincode with %s %s", function, args) + result, err := c.contract.SubmitTransaction(function, args...) + if err != nil { + logger.Fatalf("Failed to Submit transaction: %v", err) + } + logger.Debugf("--> Result: %s", string(result)) + return string(result) +} + +func (c *Client) Query(function string, args ...string) string { + logger.Debugf("--> Query FPC chaincode with %s %s", function, args) + result, err := c.contract.EvaluateTransaction(function, args...) + if err != nil { + logger.Fatalf("Failed to evaluate transaction: %v", err) + } + logger.Debugf("--> Result: %s", string(result)) + return string(result) +} diff --git a/samples/application/ccapi/pkg/logging.go b/samples/application/ccapi/pkg/logging.go new file mode 100644 index 000000000..717877ffa --- /dev/null +++ b/samples/application/ccapi/pkg/logging.go @@ -0,0 +1,72 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package pkg + +import ( + "fmt" + + "github.com/hyperledger/fabric-sdk-go/pkg/common/logging" + "github.com/hyperledger/fabric-sdk-go/pkg/core/logging/api" + "github.com/hyperledger/fabric/common/flogging" +) + +var logger = flogging.MustGetLogger("fpc.cli") + +func init() { + logging.Initialize(&provider{}) +} + +type provider struct { +} + +func (p *provider) GetLogger(module string) api.Logger { + name := "client.sdk-go" + e := &extendedFlogger{flogging.MustGetLogger(name)} + + return e +} + +type extendedFlogger struct { + *flogging.FabricLogger +} + +func (e *extendedFlogger) Fatalln(v ...interface{}) { + e.Fatal(v...) +} + +func (e *extendedFlogger) Panicln(v ...interface{}) { + e.Panic(v...) +} + +func (e *extendedFlogger) Print(v ...interface{}) { + fmt.Print(v...) +} + +func (e *extendedFlogger) Printf(format string, v ...interface{}) { + fmt.Printf(format, v...) +} + +func (e *extendedFlogger) Println(v ...interface{}) { + fmt.Println(v...) + +} + +func (e *extendedFlogger) Debugln(args ...interface{}) { + e.Debug(args...) +} + +func (e *extendedFlogger) Infoln(args ...interface{}) { + e.Info(args...) +} + +func (e *extendedFlogger) Warnln(args ...interface{}) { + e.Warn(args...) +} + +func (e *extendedFlogger) Errorln(args ...interface{}) { + e.Error(args...) +} diff --git a/samples/chaincode/cc-tools-demo/Dockerfile b/samples/chaincode/cc-tools-demo/Dockerfile new file mode 100644 index 000000000..caea7cd8e --- /dev/null +++ b/samples/chaincode/cc-tools-demo/Dockerfile @@ -0,0 +1,18 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +ARG GO_VER=1.21 +ARG ALPINE_VER=3.20 +ARG CC_SERVER_PORT=9999 + +FROM golang:${GO_VER}-alpine${ALPINE_VER} + +WORKDIR /go/src/github.com/hyperledger/fabric-private-chaincode/samples/chaincode/cc-tools-demo +COPY . . + +RUN go get -d -v . +RUN go build -o cc-tools-demo -v . + +EXPOSE ${CC_SERVER_PORT} +CMD ["./cc-tools-demo"] diff --git a/samples/chaincode/cc-tools-demo/META-INF/.gitkeep b/samples/chaincode/cc-tools-demo/META-INF/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/samples/chaincode/cc-tools-demo/META-INF/statedb/couchdb/indexes/example.json b/samples/chaincode/cc-tools-demo/META-INF/statedb/couchdb/indexes/example.json new file mode 100644 index 000000000..b273ac687 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/META-INF/statedb/couchdb/indexes/example.json @@ -0,0 +1,10 @@ +{ + "index":{ + "fields":[ + {"@assetType": "asc"} + ] + }, + "ddoc":"indexAssetTypeDoc", + "name":"indexAssetType", + "type":"json" +} \ No newline at end of file diff --git a/samples/chaincode/cc-tools-demo/Makefile b/samples/chaincode/cc-tools-demo/Makefile new file mode 100644 index 000000000..c469cc4c5 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/Makefile @@ -0,0 +1,4 @@ +TOP = ../../.. +include $(TOP)/ecc_go/build.mk + +CC_NAME ?= fpc-cc-tools-demo \ No newline at end of file diff --git a/samples/chaincode/cc-tools-demo/README.md b/samples/chaincode/cc-tools-demo/README.md new file mode 100644 index 000000000..b5f73f9fc --- /dev/null +++ b/samples/chaincode/cc-tools-demo/README.md @@ -0,0 +1,274 @@ +# CC-Tools-Demo Tutorial + +This tutorial shows how to build, install and test a Go Chaincode developed using the [CC-Tools]() framework and integrating it with the Fabric Private Chaincode (FPC) framework. + +This tutorial illustrates a simple use case where we follow the [cc-tools-demo]() chaincode which is based on standard fabric and then convert it to an FPC chaincode achieving FPC security capabilities. + +This tutorial is based on the [FPC with CC-Tools integration project]() and all our design choices are explained here in the [design document]() +Here are the steps to accomplish this: + +* Clone and copy the cc-tools-demo chaincode +* Edit the chaincode to became an FPC chaincode instead of normal fabric +* Build your FPC Go Chaincode +* Launch a Fabric network +* Install and instantiate your chaincode +* Invoke transactions by using the FPC simple-cli + +## Prerequisites + +This tutorial presumes that you have installed FPC on your `$GOPATH` as described in the FPC [README.md](../../../README.md#clone-fabric-private-chaincode) and `$FPC_PATH` is set accordingly. + +We also need a working FPC development environment. As described in the "Setup your Development Environment" Section of the FPC [README.md](../../../README.md#setup-your-development-environment), you can use our docker-based dev environment (Option 1) or setup your local development environment (Option 2). +We recommend using the docker-based development environment and continue this tutorial within the dev container terminal. + +Moreover, within your FPC development you have already installed the FPC Go Chaincode Support components. +See the installation steps in [ecc_go/README.md](../../../ecc_go/README.md#installation). + +We also assume that you are familiar with Fabric chaincode development in go. +Most of the steps in this tutorial follow the normal Fabric chaincode development process, however, there are a few differences that we will highlight here. + +## Clone and copy the cc-tools-demo chaincode + +Clone the [cc-tools-demo]() repository and copy the [chaincode]() folder. Then paste it in the root directory for cc-tools-demo here. + +```bash +cd ~ +git clone https://github.com/hyperledger-labs/cc-tools-demo.git +cp -a ~/cc-tools-demo/chaincode/. $FPC_PATH/samples/chaincode/cc-tools-demo/ +cd $FPC_PATH/samples/chaincode/cc-tools-demo +``` + +The chaincode code structure is different than normal chaincode as it's using the cc-tools framework + +**Note**: remove all test files (`*_test.go`) you find like `txdefs_createNewLibrary_test.go` as they are not part of the chaincode. + +## Edit the chaincode to became an FPC chaincode instead of normal fabric + +Go to `$FPC_PATH/samples/chaincode/cc-tools-demo/main.go` and create the project structure. + +```bash +cd $FPC_PATH/samples/chaincode/cc-tools-demo +``` + +The code presented here is not different from traditional Go Chaincode developed with CC-Tools framework. All the FPC specific protection mechanisms are handled by the FPC framework transparently. + +The `main.go` contains the starting point of the chaincode. + +To use FPC, we need to add some logic to instantiate our private chaincode and start it. +To do so, we use `fpc.NewPrivateChaincode(&chaincode.AssetExample{})` and since we're already in the FPC repo, remove the `go.mod` and `go.sum` files so we use the chaincode as part of the FPC package. + +CC-tools-demo chaincode has its own packages that are needed, so we run `go get` in the `cc-tools-demo` folder. + +Then, add the following code to `$FPC_PATH/samples/chaincode/cc-tools-demo/main.go` in functions `main()` and `runCCaaS()`: + +```go +package main + +import ( + "github.com/hyperledger/fabric-private-chaincode/samples/chaincode/cc-tools-demo/assettypes" + "github.com/hyperledger/fabric-private-chaincode/samples/chaincode/cc-tools-demo/datatypes" + "github.com/hyperledger/fabric-private-chaincode/samples/chaincode/cc-tools-demo/header" + + fpc "github.com/hyperledger/fabric-private-chaincode/ecc_go/chaincode" +) + +func main() { + + //*CC-Tools Specific code (DO NOT OVERWRITE)*// + + if os.Getenv("RUN_CCAAS") == "true" { + err = runCCaaS() + } else { + if os.Getenv("FPC_ENABLED") == "true" { + err = shim.Start(fpc.NewPrivateChaincode(new(CCDemo))) + } else { + err = shim.Start(new(CCDemo)) + } + } + + //*CC-Tools Specific code (DO NOT OVERWRITE)*// + +} + +func runCCaaS() error { + address := os.Getenv("CHAINCODE_SERVER_ADDRESS") + ccid := os.Getenv("CHAINCODE_PKG_ID") //This needs to be replaced + + //*CC-Tools Specific code (DO NOT OVERWRITE)*// + + var cc shim.Chaincode + if os.Getenv("FPC_ENABLED") == "true" { + cc = fpc.NewPrivateChaincode(new(CCDemo)) + } else { + cc = new(CCDemo) + } + + + server := &shim.ChaincodeServer{ + CCID: ccid, + Address: address, + CC: cc, + TLSProps: *tlsProps, + } + + //*CC-Tools Specific code (DO NOT OVERWRITE)*// + +} + +``` + +## Set the needed env vars in the docker-compose file + +From the code above, we need to set two env variables for the chaincode application to work and use FPC and chaincode-as-a-service (CCAAS). One way to do this is to go to `$FPC_PATH/samples/deployment/test-network/docker-compose.yml` and edit both `ecc.peer0.org1.example.com` and `ecc.peer0.org2.example.com` environment block to have +```yaml +- RUN_CCAAS=true +- FPC_ENABLED=true +``` + + +## Building FPC Go Chaincode + +Create a `Makefile` (i.e., `touch $FPC_PATH/samples/chaincode/cc-tools-demo/Makefile`) with the following content: + +```Makefile +TOP = ../../.. +include $(TOP)/ecc_go/build.mk + +CC_NAME ?= fpc-cc-tools-demo +``` + +Please make sure that in the file above the variable `TOP` points to the FPC root directory (i.e., `$FPC_PATH`) as it uses the `$FPC_PATH/ecc_go/build.mk` file. + +**Note**: In our case, we need to change the build command in the `$FPC_PATH/ecc_go/build.mk` file at the `ecc` target to be `ego-go build $(GOTAGS) -o $(ECC_BINARY)` instead of `ego-go build $(GOTAGS) -o $(ECC_BINARY) main.go` + + +In `$FPC_PATH/samples/chaincode/cc-tools-demo` directory, to build the chaincode and package it as docker image, execute: + +```bash +make +``` +Note: this command runs inside the FPC dev environment and not your local host. + +**Note**: If you faced this error: +```bash +/project/pkg/mod/github.com/hyperledger-labs/cc-tools@v1.0.1/mock/mockstub.go:146:22: cannot use stub (variable of type *MockStub) as shim.ChaincodeStubInterface value in argument to stub.cc.Init: *MockStub does not implement shim.ChaincodeStubInterface (missing method PurgePrivateData) +``` +This is because a minor difference between the `ChaincodeStubInterface` used in the cc-tools `Mockstub` as it's missing the `PurgePrivateData` method. +To solve this, run `go mod vendor` in the `$FPC_PATH` root directory to download all used packages and go to the file of the error to add the missing method there. +```bash +nano $FPC_PATH/vendor/github.com/hyperledger-labs/cc-tools/mock/mockstub.go +``` +add the following function +```go + // PurgePrivateData ... + func (stub *MockStub) PurgePrivateData(collection, key string) error { + return errors.New("Not Implemented") + } + +``` + +After building, you can check that the `fpc/fpc-cc-tools-demo` image exists in your local docker registry using: + +```bash +docker images | grep fpc-cc-tools-demo +``` + +## Time to test! + +Next step is to test the chaincode by invoking transactions, for which you need a basic Fabric network with a channel. +We will use the test network provided in [`$FPC_PATH/samples/deployment/test-network`](../../deployment/test-network). +To invoke the chaincode, we will use the `simple-cli` application in [`$FPC_PATH/samples/application/simple-cli-go`](../../pplication/simple-cli-go). + +### Enclave Registry + +To run any FPC chaincode we need to prepare the docker images for the FPC Enclave Registry (ERCC). +In case you have not yet created them, run `make -C $FPC_PATH/ercc build docker`. + +### Prepare the test network + +We already provide a detailed tutorial how to use FPC with the test network in [`$FPC_PATH/samples/deployment/test-network`](../../deployment/test-network). +However, for completeness, let's go through the required steps once again. + +```bash +cd $FPC_PATH/samples/deployment/test-network +./setup.sh +``` + +### Start the test network + +Now we are ready to launch the fabric test network and install the FPC chaincode on it. +We begin with setting up the network with a single channel `mychannel`. + +```bash +cd $FPC_PATH/samples/deployment/test-network/fabric-samples/test-network +./network.sh up -ca +./network.sh createChannel -c mychannel +``` + +Once the network is up and running, we install the simple asset chaincode and the FPC Enclave Registry. +We provide a small shell script to make this task a bit easier. + +```bash +export CC_ID=cc-tools-demo +export CC_PATH="$FPC_PATH/samples/chaincode/cc-tools-demo/" +export CC_VER=$(cat "$FPC_PATH/samples/chaincode/cc-tools-demo/mrenclave") +cd $FPC_PATH/samples/deployment/test-network +./installFPC.sh +``` + +Note that the `installFPC.sh` script returns an export statement you need to copy and paste in the terminal. +This sets environment variables for the package IDs for each chaincode container. +Continue by running: + +```bash +make ercc-ecc-start +``` + +You should see now four containers running (i.e., `cc-tools-demo.peer0.org1`, `cc-tools-demo.peer0.org2`, `ercc.peer0.org1`, and `ercc.peer0.org2`). + +### Invoke simple asset + +Open a new terminal and connect to the `fpc-development-go-support` container by running + +```bash +docker exec -it fpc-development-go-support /bin/bash +``` + +```bash +# prepare connections profile +cd $FPC_PATH/samples/deployment/test-network +./update-connection.sh + +# # update the connection profile for external clients outside the fpc dev environment +cd $FPC_PATH/samples/deployment/test-network +./update-external-connection.sh + +# make fpcclient +cd $FPC_PATH/samples/application/simple-cli-go +make + +# export fpcclient settings +export CC_NAME=cc-tools-demo +export CHANNEL_NAME=mychannel +export CORE_PEER_ADDRESS=localhost:7051 +export CORE_PEER_ID=peer0.org1.example.com +export CORE_PEER_LOCALMSPID=Org1MSP +export CORE_PEER_MSPCONFIGPATH=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp +export CORE_PEER_TLS_CERT_FILE=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt +export CORE_PEER_TLS_ENABLED="true" +export CORE_PEER_TLS_KEY_FILE=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key +export CORE_PEER_TLS_ROOTCERT_FILE=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt +export ORDERER_CA=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem +export GATEWAY_CONFIG=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/connection-org1.yaml +export FPC_ENABLED=true +export RUN_CCAAS=true + +# init our enclave +./fpcclient init $CORE_PEER_ID + +# interact with the FPC-CC-Tools Chaincode. The getSchema is a built-in cc-tools transaction +./fpcclient invoke getSchema + +``` + +Congratulations! You have successfully created a FPC chaincode with go and invoked it using our simple cli. diff --git a/samples/chaincode/cc-tools-demo/assetTypeList.go b/samples/chaincode/cc-tools-demo/assetTypeList.go new file mode 100644 index 000000000..f4324ae58 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/assetTypeList.go @@ -0,0 +1,13 @@ +package main + +import ( + "github.com/hyperledger-labs/cc-tools/assets" + "github.com/hyperledger/fabric-private-chaincode/samples/chaincode/cc-tools-demo/assettypes" +) + +var assetTypeList = []assets.AssetType{ + assettypes.Person, + assettypes.Book, + assettypes.Library, + assettypes.Secret, +} diff --git a/samples/chaincode/cc-tools-demo/assettypes/book.go b/samples/chaincode/cc-tools-demo/assettypes/book.go new file mode 100644 index 000000000..d887d36c3 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/assettypes/book.go @@ -0,0 +1,55 @@ +package assettypes + +import "github.com/hyperledger-labs/cc-tools/assets" + +// Description of a book +var Book = assets.AssetType{ + Tag: "book", + Label: "Book", + Description: "Book", + + Props: []assets.AssetProp{ + { + // Composite Key + Required: true, + IsKey: true, + Tag: "title", + Label: "Book Title", + DataType: "string", + Writers: []string{`org2MSP`, "Org1MSP"}, // This means only org2 can create the asset (others can edit) + }, + { + // Composite Key + Required: true, + IsKey: true, + Tag: "author", + Label: "Book Author", + DataType: "string", + Writers: []string{`org2MSP`, "Org1MSP"}, // This means only org2 can create the asset (others can edit) + }, + { + /// Reference to another asset + Tag: "currentTenant", + Label: "Current Tenant", + DataType: "->person", + }, + { + // String list + Tag: "genres", + Label: "Genres", + DataType: "[]string", + }, + { + // Date property + Tag: "published", + Label: "Publishment Date", + DataType: "datetime", + }, + { + // Custom data type + Tag: "bookType", + Label: "Book Type", + DataType: "bookType", + }, + }, +} diff --git a/samples/chaincode/cc-tools-demo/assettypes/customAssets.go b/samples/chaincode/cc-tools-demo/assettypes/customAssets.go new file mode 100644 index 000000000..30da5aa33 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/assettypes/customAssets.go @@ -0,0 +1,10 @@ +package assettypes + +import ( + "github.com/hyperledger-labs/cc-tools/assets" +) + +// CustomAssets contains all assets inserted via GoFabric's Template mode. +// For local development, this can be empty or could contain assets that +// are supposed to be defined via the Template mode. +var CustomAssets = []assets.AssetType{} diff --git a/samples/chaincode/cc-tools-demo/assettypes/dynamicAssetTypes.go b/samples/chaincode/cc-tools-demo/assettypes/dynamicAssetTypes.go new file mode 100644 index 000000000..65739c9d2 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/assettypes/dynamicAssetTypes.go @@ -0,0 +1,11 @@ +package assettypes + +import ( + "github.com/hyperledger-labs/cc-tools/assets" +) + +// DynamicAssetTypes contains the configuration for the Dynamic AssetTypes feature. +var DynamicAssetTypes = assets.DynamicAssetType{ + Enabled: true, + AssetAdmins: []string{`org1MSP`, "Org1MSP"}, +} diff --git a/samples/chaincode/cc-tools-demo/assettypes/library.go b/samples/chaincode/cc-tools-demo/assettypes/library.go new file mode 100644 index 000000000..cc78cb4ec --- /dev/null +++ b/samples/chaincode/cc-tools-demo/assettypes/library.go @@ -0,0 +1,34 @@ +package assettypes + +import "github.com/hyperledger-labs/cc-tools/assets" + +// Description of a Library as a collection of books +var Library = assets.AssetType{ + Tag: "library", + Label: "Library", + Description: "Library as a collection of books", + + Props: []assets.AssetProp{ + { + // Primary Key + Required: true, + IsKey: true, + Tag: "name", + Label: "Library Name", + DataType: "string", + Writers: []string{`org3MSP`, "Org1MSP"}, // This means only org3 can create the asset (others can edit) + }, + { + // Asset reference list + Tag: "books", + Label: "Book Collection", + DataType: "[]->book", + }, + { + // Asset reference list + Tag: "entranceCode", + Label: "Entrance Code for the Library", + DataType: "->secret", + }, + }, +} diff --git a/samples/chaincode/cc-tools-demo/assettypes/person.go b/samples/chaincode/cc-tools-demo/assettypes/person.go new file mode 100644 index 000000000..9c5c9748f --- /dev/null +++ b/samples/chaincode/cc-tools-demo/assettypes/person.go @@ -0,0 +1,53 @@ +package assettypes + +import ( + "fmt" + + "github.com/hyperledger-labs/cc-tools/assets" +) + +var Person = assets.AssetType{ + Tag: "person", + Label: "Person", + Description: "Personal data of someone", + + Props: []assets.AssetProp{ + { + // Primary key + Required: true, + IsKey: true, + Tag: "id", + Label: "CPF (Brazilian ID)", + DataType: "cpf", // Datatypes are identified at datatypes folder + Writers: []string{`org1MSP`, "Org1MSP"}, // This means only org1 can create the asset (others can edit) + }, + { + // Mandatory property + Required: true, + Tag: "name", + Label: "Name of the person", + DataType: "string", + // Validate funcion + Validate: func(name interface{}) error { + nameStr := name.(string) + if nameStr == "" { + return fmt.Errorf("name must be non-empty") + } + return nil + }, + }, + { + // Optional property + Tag: "dateOfBirth", + Label: "Date of Birth", + DataType: "datetime", + }, + { + // Property with default value + Tag: "height", + Label: "Person's height", + DefaultValue: 0, + DataType: "number", + }, + }, +} diff --git a/samples/chaincode/cc-tools-demo/assettypes/secret.go b/samples/chaincode/cc-tools-demo/assettypes/secret.go new file mode 100644 index 000000000..02bcf61b0 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/assettypes/secret.go @@ -0,0 +1,30 @@ +package assettypes + +import "github.com/hyperledger-labs/cc-tools/assets" + +// Secret is and information available only for org2 and org3 +// Collections.json configuration is necessary +var Secret = assets.AssetType{ + Tag: "secret", + Label: "Secret", + Description: "Secret between Org2 and Org3", + + Readers: []string{"org2MSP", "org3MSP", "Org1MSP"}, + Props: []assets.AssetProp{ + { + // Primary Key + IsKey: true, + Tag: "secretName", + Label: "Secret Name", + DataType: "string", + Writers: []string{`org2MSP`, "Org1MSP"}, // This means only org2 can create the asset (org3 can edit) + }, + { + // Mandatory Property + Required: true, + Tag: "secret", + Label: "Secret", + DataType: "string", + }, + }, +} diff --git a/samples/chaincode/cc-tools-demo/datatypes/bookType.go b/samples/chaincode/cc-tools-demo/datatypes/bookType.go new file mode 100644 index 000000000..4f6265752 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/datatypes/bookType.go @@ -0,0 +1,72 @@ +package datatypes + +import ( + "fmt" + "strconv" + + "github.com/hyperledger-labs/cc-tools/assets" + "github.com/hyperledger-labs/cc-tools/errors" +) + +// Example of a custom data type using enum-like structure (iota) +// This allows the use of verification by const values instead of float64, improving readability +// Example: +// if assetMap["bookType"].(float64) == (float64)(BookTypeHardcover) +// ... + +type BookType float64 + +const ( + BookTypeHardcover BookType = iota + BookTypePaperback + BookTypeEbook +) + +// CheckType checks if the given value is defined as valid BookType consts +func (b BookType) CheckType() errors.ICCError { + switch b { + case BookTypeHardcover: + return nil + case BookTypePaperback: + return nil + case BookTypeEbook: + return nil + default: + return errors.NewCCError("invalid type", 400) + } + +} + +var bookType = assets.DataType{ + AcceptedFormats: []string{"number"}, + DropDownValues: map[string]interface{}{ + "Hardcover": BookTypeHardcover, + "Paperback": BookTypePaperback, + "Ebook": BookTypeEbook, + }, + Description: ``, + + Parse: func(data interface{}) (string, interface{}, errors.ICCError) { + var dataVal float64 + switch v := data.(type) { + case float64: + dataVal = v + case int: + dataVal = (float64)(v) + case BookType: + dataVal = (float64)(v) + case string: + var err error + dataVal, err = strconv.ParseFloat(v, 64) + if err != nil { + return "", nil, errors.WrapErrorWithStatus(err, "asset property must be an integer, is %t", 400) + } + default: + return "", nil, errors.NewCCError("asset property must be an integer, is %t", 400) + } + + retVal := (BookType)(dataVal) + err := retVal.CheckType() + return fmt.Sprint(retVal), retVal, err + }, +} diff --git a/samples/chaincode/cc-tools-demo/datatypes/cpf.go b/samples/chaincode/cc-tools-demo/datatypes/cpf.go new file mode 100644 index 000000000..ec13ab6da --- /dev/null +++ b/samples/chaincode/cc-tools-demo/datatypes/cpf.go @@ -0,0 +1,59 @@ +package datatypes + +import ( + "strings" + + "github.com/hyperledger-labs/cc-tools/assets" + "github.com/hyperledger-labs/cc-tools/errors" +) + +var cpf = assets.DataType{ + AcceptedFormats: []string{"string"}, + Parse: func(data interface{}) (string, interface{}, errors.ICCError) { + cpf, ok := data.(string) + if !ok { + return "", nil, errors.NewCCError("property must be a string", 400) + } + + cpf = strings.ReplaceAll(cpf, ".", "") + cpf = strings.ReplaceAll(cpf, "-", "") + + if len(cpf) != 11 { + return "", nil, errors.NewCCError("CPF must have 11 digits", 400) + } + + var vd0 int + for i, d := range cpf { + if i >= 9 { + break + } + dnum := int(d) - '0' + vd0 += (10 - i) * dnum + } + vd0 = 11 - vd0%11 + if vd0 > 9 { + vd0 = 0 + } + if int(cpf[9])-'0' != vd0 { + return "", nil, errors.NewCCError("Invalid CPF", 400) + } + + var vd1 int + for i, d := range cpf { + if i >= 10 { + break + } + dnum := int(d) - '0' + vd1 += (11 - i) * dnum + } + vd1 = 11 - vd1%11 + if vd1 > 9 { + vd1 = 0 + } + if int(cpf[10])-'0' != vd1 { + return "", nil, errors.NewCCError("Invalid CPF", 400) + } + + return cpf, cpf, nil + }, +} diff --git a/samples/chaincode/cc-tools-demo/datatypes/datatypes.go b/samples/chaincode/cc-tools-demo/datatypes/datatypes.go new file mode 100644 index 000000000..2024554c8 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/datatypes/datatypes.go @@ -0,0 +1,11 @@ +package datatypes + +import ( + "github.com/hyperledger-labs/cc-tools/assets" +) + +// CustomDataTypes contain the user-defined primary data types +var CustomDataTypes = map[string]assets.DataType{ + "cpf": cpf, + "bookType": bookType, +} diff --git a/samples/chaincode/cc-tools-demo/eventTypeList.go b/samples/chaincode/cc-tools-demo/eventTypeList.go new file mode 100644 index 000000000..c3d3bc725 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/eventTypeList.go @@ -0,0 +1,10 @@ +package main + +import ( + "github.com/hyperledger-labs/cc-tools/events" + "github.com/hyperledger/fabric-private-chaincode/samples/chaincode/cc-tools-demo/eventtypes" +) + +var eventTypeList = []events.Event{ + eventtypes.CreateLibraryLog, +} diff --git a/samples/chaincode/cc-tools-demo/eventtypes/createLibraryLog.go b/samples/chaincode/cc-tools-demo/eventtypes/createLibraryLog.go new file mode 100644 index 000000000..2c7e553e2 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/eventtypes/createLibraryLog.go @@ -0,0 +1,13 @@ +package eventtypes + +import "github.com/hyperledger-labs/cc-tools/events" + +// CreateLibraryLog is a log to be emitted on the CCAPI when a library is created +var CreateLibraryLog = events.Event{ + Tag: "createLibraryLog", + Label: "Create Library Log", + Description: "Log of a library creation", + Type: events.EventLog, // Event funciton is to log on the CCAPI + BaseLog: "New library created", // BaseLog is a base message to be logged + Receivers: []string{"$org2MSP", "$Org1MSP"}, // Receivers are the MSPs that will receive the event +} diff --git a/samples/chaincode/cc-tools-demo/generateCollections.go b/samples/chaincode/cc-tools-demo/generateCollections.go new file mode 100644 index 000000000..8f9d7a85d --- /dev/null +++ b/samples/chaincode/cc-tools-demo/generateCollections.go @@ -0,0 +1,82 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" +) + +type ArrayFlags []string + +func (i *ArrayFlags) String() string { + return "my string representation" +} + +func (i *ArrayFlags) Set(value string) error { + *i = append(*i, value) + return nil +} + +type CollectionElem struct { + Name string `json:"name"` + RequiredPeerCount int `json:"requiredPeerCount"` + MaxPeerCount int `json:"maxPeerCount"` + BlockToLive int `json:"blockToLive"` + MemberOnlyRead bool `json:"memberOnlyRead"` + Policy string `json:"policy"` +} + +func generateCollection(orgs ArrayFlags) { + collection := []CollectionElem{} + + for _, a := range assetTypeList { + if len(a.Readers) > 0 { + elem := CollectionElem{ + Name: a.Tag, + RequiredPeerCount: 0, + MaxPeerCount: 3, + BlockToLive: 1000000, + MemberOnlyRead: true, + Policy: generatePolicy(a.Readers, orgs), + } + collection = append(collection, elem) + } + } + + b, err := json.MarshalIndent(collection, "", " ") + if err != nil { + fmt.Println(err) + return + } + err = os.WriteFile("collections.json", b, 0644) + if err != nil { + fmt.Println(err) + return + } +} + +func generatePolicy(readers []string, orgs ArrayFlags) string { + firstElem := true + policy := "OR(" + for _, r := range readers { + if len(orgs) > 0 { + found := false + for _, o := range orgs { + if r == o { + found = true + break + } + } + if !found { + continue + } + } + if !firstElem { + policy += ", " + } + policy += fmt.Sprintf("'%s.member'", r) + firstElem = false + } + policy += ")" + return policy +} diff --git a/samples/chaincode/cc-tools-demo/header/header.go b/samples/chaincode/cc-tools-demo/header/header.go new file mode 100644 index 000000000..72ea0eff1 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/header/header.go @@ -0,0 +1,10 @@ +package header + +var Name = "CC Tools Demo" +var Version = "1.0.0" +var Colors = map[string][]string{ + "@default": {"#4267B2", "#34495E", "#ECF0F1"}, +} +var Title = map[string]string{ + "@default": "CC Tools Demo", +} diff --git a/samples/chaincode/cc-tools-demo/main.go b/samples/chaincode/cc-tools-demo/main.go new file mode 100644 index 000000000..0c178854b --- /dev/null +++ b/samples/chaincode/cc-tools-demo/main.go @@ -0,0 +1,234 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + "time" + + "github.com/hyperledger-labs/cc-tools/assets" + "github.com/hyperledger-labs/cc-tools/events" + sw "github.com/hyperledger-labs/cc-tools/stubwrapper" + tx "github.com/hyperledger-labs/cc-tools/transactions" + "github.com/hyperledger/fabric-private-chaincode/samples/chaincode/cc-tools-demo/assettypes" + "github.com/hyperledger/fabric-private-chaincode/samples/chaincode/cc-tools-demo/datatypes" + "github.com/hyperledger/fabric-private-chaincode/samples/chaincode/cc-tools-demo/header" + + fpc "github.com/hyperledger/fabric-private-chaincode/ecc_go/chaincode" + + "github.com/hyperledger/fabric-chaincode-go/pkg/cid" + "github.com/hyperledger/fabric-chaincode-go/shim" + pb "github.com/hyperledger/fabric-protos-go/peer" +) + +var startupCheckExecuted = false + +func SetupCC() error { + tx.InitHeader(tx.Header{ + Name: header.Name, + Version: header.Version, + Colors: header.Colors, + Title: header.Title, + }) + + assets.InitDynamicAssetTypeConfig(assettypes.DynamicAssetTypes) + + tx.InitTxList(txList) + + err := assets.CustomDataTypes(datatypes.CustomDataTypes) + if err != nil { + fmt.Printf("Error injecting custom data types: %s", err) + return err + } + assets.InitAssetList(append(assetTypeList, assettypes.CustomAssets...)) + + events.InitEventList(eventTypeList) + + return nil +} + +// main function starts up the chaincode in the container during instantiate +func main() { + // Generate collection json + genFlag := flag.Bool("g", false, "Enable collection generation") + flag.Bool("orgs", false, "List of orgs to generate collection for") + flag.Parse() + if *genFlag { + listOrgs := flag.Args() + generateCollection(listOrgs) + return + } + + log.Printf("Starting chaincode %s version %s\n", header.Name, header.Version) + + err := SetupCC() + if err != nil { + return + } + + if os.Getenv("RUN_CCAAS") == "true" { + err = runCCaaS() + } else { + if os.Getenv("FPC_ENABLED") == "true" { + err = shim.Start(fpc.NewPrivateChaincode(new(CCDemo))) + } else { + err = shim.Start(new(CCDemo)) + } + } + + if err != nil { + fmt.Printf("Error starting chaincode: %s", err) + } +} + +func runCCaaS() error { + address := os.Getenv("CHAINCODE_SERVER_ADDRESS") + ccid := os.Getenv("CHAINCODE_PKG_ID") + + tlsProps, err := getTLSProperties() + if err != nil { + return err + } + + var cc shim.Chaincode + + if os.Getenv("FPC_ENABLED") == "true" { + cc = fpc.NewPrivateChaincode(new(CCDemo)) + } else { + cc = new(CCDemo) + } + + server := &shim.ChaincodeServer{ + CCID: ccid, + Address: address, + CC: cc, + TLSProps: *tlsProps, + } + + return server.Start() +} + +func getTLSProperties() (*shim.TLSProperties, error) { + if enableTLS := os.Getenv("TLS_ENABLED"); enableTLS != "true" { + return &shim.TLSProperties{ + Disabled: true, + }, nil + } + + log.Printf("TLS enabled") + + // Get key + keyPath := os.Getenv("KEY_PATH") + key, err := os.ReadFile(keyPath) + + if err != nil { + fmt.Println("Failed to read key file") + return nil, err + } + + // Get cert + certPath := os.Getenv("CERT_PATH") + cert, err := os.ReadFile(certPath) + if err != nil { + fmt.Println("Failed to read cert file") + return nil, err + } + + // Get CA cert + clientCertPath := os.Getenv("CA_CERT_PATH") + caCert, err := os.ReadFile(clientCertPath) + if err != nil { + fmt.Println("Failed to read CA cert file") + return nil, err + } + + return &shim.TLSProperties{ + Disabled: false, + Key: key, + Cert: cert, + ClientCACerts: caCert, + }, nil +} + +// CCDemo implements the shim.Chaincode interface +type CCDemo struct{} + +// Init is called during chaincode instantiation to initialize any +// data. Note that chaincode upgrade also calls this function to reset +// or to migrate data. +func (t *CCDemo) Init(stub shim.ChaincodeStubInterface) (response pb.Response) { + + res := InitFunc(stub) + startupCheckExecuted = true + if res.Status != 200 { + return res + } + + response = shim.Success(nil) + return +} + +func InitFunc(stub shim.ChaincodeStubInterface) (response pb.Response) { + // Defer logging function + defer logTx(stub, time.Now(), &response) + + if assettypes.DynamicAssetTypes.Enabled { + sw := &sw.StubWrapper{ + Stub: stub, + } + err := assets.RestoreAssetList(sw, true) + if err != nil { + response = err.GetErrorResponse() + return + } + } + + err := assets.StartupCheck() + if err != nil { + response = err.GetErrorResponse() + return + } + + err = tx.StartupCheck() + if err != nil { + response = err.GetErrorResponse() + return + } + + response = shim.Success(nil) + return +} + +// Invoke is called per transaction on the chaincode. +func (t *CCDemo) Invoke(stub shim.ChaincodeStubInterface) (response pb.Response) { + // Defer logging function + defer logTx(stub, time.Now(), &response) + myId, _ := cid.GetMSPID(stub) + fmt.Println("org is.......", myId) + + if !startupCheckExecuted { + fmt.Println("Running startup check...") + res := InitFunc(stub) + if res.Status != 200 { + return res + } + startupCheckExecuted = true + } + + var result []byte + + result, err := tx.Run(stub) + + if err != nil { + response = err.GetErrorResponse() + return + } + response = shim.Success([]byte(result)) + return +} + +func logTx(stub shim.ChaincodeStubInterface, beginTime time.Time, response *pb.Response) { + fn, _ := stub.GetFunctionAndParameters() + log.Printf("%d %s %s %s\n", response.Status, fn, time.Since(beginTime), response.Message) +} diff --git a/samples/chaincode/cc-tools-demo/txList.go b/samples/chaincode/cc-tools-demo/txList.go new file mode 100644 index 000000000..fc1177717 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/txList.go @@ -0,0 +1,17 @@ +package main + +import ( + txdefs "github.com/hyperledger/fabric-private-chaincode/samples/chaincode/cc-tools-demo/txdefs" + + tx "github.com/hyperledger-labs/cc-tools/transactions" +) + +var txList = []tx.Transaction{ + tx.CreateAsset, + tx.UpdateAsset, + tx.DeleteAsset, + txdefs.CreateNewLibrary, + txdefs.GetNumberOfBooksFromLibrary, + txdefs.UpdateBookTenant, + txdefs.GetBooksByAuthor, +} diff --git a/samples/chaincode/cc-tools-demo/txdefs/createNewLibrary.go b/samples/chaincode/cc-tools-demo/txdefs/createNewLibrary.go new file mode 100644 index 000000000..698dc9b35 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/txdefs/createNewLibrary.go @@ -0,0 +1,77 @@ +package txdefs + +import ( + "encoding/json" + "fmt" + + "github.com/hyperledger-labs/cc-tools/accesscontrol" + "github.com/hyperledger-labs/cc-tools/assets" + "github.com/hyperledger-labs/cc-tools/errors" + "github.com/hyperledger-labs/cc-tools/events" + sw "github.com/hyperledger-labs/cc-tools/stubwrapper" + tx "github.com/hyperledger-labs/cc-tools/transactions" +) + +// Create a new Library on channel +// POST Method +var CreateNewLibrary = tx.Transaction{ + Tag: "createNewLibrary", + Label: "Create New Library", + Description: "Create a New Library", + Method: "POST", + Callers: []accesscontrol.Caller{ // Only org3 admin can call this transaction + { + MSP: "org3MSP", + OU: "admin", + }, + { + MSP: "Org1MSP", + OU: "admin", + }, + }, + + Args: []tx.Argument{ + { + Tag: "name", + Label: "Name", + Description: "Name of the library", + DataType: "string", + Required: true, + }, + }, + Routine: func(stub *sw.StubWrapper, req map[string]interface{}) ([]byte, errors.ICCError) { + name, _ := req["name"].(string) + + libraryMap := make(map[string]interface{}) + libraryMap["@assetType"] = "library" + libraryMap["name"] = name + + libraryAsset, err := assets.NewAsset(libraryMap) + if err != nil { + return nil, errors.WrapError(err, "Failed to create a new asset") + } + + // Save the new library on channel + _, err = libraryAsset.PutNew(stub) + if err != nil { + return nil, errors.WrapErrorWithStatus(err, "Error saving asset on blockchain", err.Status()) + } + + // Marshal asset back to JSON format + libraryJSON, nerr := json.Marshal(libraryAsset) + if nerr != nil { + return nil, errors.WrapError(nil, "failed to encode asset to JSON format") + } + + // Marshall message to be logged + logMsg, ok := json.Marshal(fmt.Sprintf("New library name: %s", name)) + if ok != nil { + return nil, errors.WrapError(nil, "failed to encode asset to JSON format") + } + + // Call event to log the message + events.CallEvent(stub, "createLibraryLog", logMsg) + + return libraryJSON, nil + }, +} diff --git a/samples/chaincode/cc-tools-demo/txdefs/getBooksByAuthor.go b/samples/chaincode/cc-tools-demo/txdefs/getBooksByAuthor.go new file mode 100644 index 000000000..39aa9b11e --- /dev/null +++ b/samples/chaincode/cc-tools-demo/txdefs/getBooksByAuthor.go @@ -0,0 +1,74 @@ +package txdefs + +import ( + "encoding/json" + + "github.com/hyperledger-labs/cc-tools/accesscontrol" + "github.com/hyperledger-labs/cc-tools/assets" + "github.com/hyperledger-labs/cc-tools/errors" + sw "github.com/hyperledger-labs/cc-tools/stubwrapper" + tx "github.com/hyperledger-labs/cc-tools/transactions" +) + +// Return the all books from an specific author +// GET method +var GetBooksByAuthor = tx.Transaction{ + Tag: "getBooksByAuthor", + Label: "Get Books by the Author Name", + Description: "Return all the books from an author", + Method: "GET", + Callers: []accesscontrol.Caller{ // Only org1 and org2 can call this transaction + {MSP: "org1MSP"}, + {MSP: "org2MSP"}, + {MSP: "Org1MSP"}, + }, + + Args: []tx.Argument{ + { + Tag: "authorName", + Label: "Author Name", + Description: "Author Name", + DataType: "string", + Required: true, + }, + { + Tag: "limit", + Label: "Limit", + Description: "Limit", + DataType: "number", + }, + }, + Routine: func(stub *sw.StubWrapper, req map[string]interface{}) ([]byte, errors.ICCError) { + authorName, _ := req["authorName"].(string) + limit, hasLimit := req["limit"].(float64) + + if hasLimit && limit <= 0 { + return nil, errors.NewCCError("limit must be greater than 0", 400) + } + + // Prepare couchdb query + query := map[string]interface{}{ + "selector": map[string]interface{}{ + "@assetType": "book", + "author": authorName, + }, + } + + if hasLimit { + query["limit"] = limit + } + + var err error + response, err := assets.Search(stub, query, "", true) + if err != nil { + return nil, errors.WrapErrorWithStatus(err, "error searching for book's author", 500) + } + + responseJSON, err := json.Marshal(response) + if err != nil { + return nil, errors.WrapErrorWithStatus(err, "error marshaling response", 500) + } + + return responseJSON, nil + }, +} diff --git a/samples/chaincode/cc-tools-demo/txdefs/getNumberOfBooksFromLibrary.go b/samples/chaincode/cc-tools-demo/txdefs/getNumberOfBooksFromLibrary.go new file mode 100644 index 000000000..83608d959 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/txdefs/getNumberOfBooksFromLibrary.go @@ -0,0 +1,60 @@ +package txdefs + +import ( + "encoding/json" + + "github.com/hyperledger-labs/cc-tools/accesscontrol" + "github.com/hyperledger-labs/cc-tools/assets" + "github.com/hyperledger-labs/cc-tools/errors" + sw "github.com/hyperledger-labs/cc-tools/stubwrapper" + tx "github.com/hyperledger-labs/cc-tools/transactions" +) + +// Return the number of books of a library +// GET method +var GetNumberOfBooksFromLibrary = tx.Transaction{ + Tag: "getNumberOfBooksFromLibrary", + Label: "Get Number Of Books From Library", + Description: "Return the number of books of a library", + Method: "GET", + Callers: []accesscontrol.Caller{ // Only org2 can call this transaction + {MSP: "org2MSP"}, + {MSP: "Org1MSP"}, + }, + + Args: []tx.Argument{ + { + Tag: "library", + Label: "Library", + Description: "Library", + DataType: "->library", + Required: true, + }, + }, + Routine: func(stub *sw.StubWrapper, req map[string]interface{}) ([]byte, errors.ICCError) { + libraryKey, _ := req["library"].(assets.Key) + + // Returns Library from channel + libraryMap, err := libraryKey.GetMap(stub) + if err != nil { + return nil, errors.WrapErrorWithStatus(err, "failed to get asset from the ledger", err.Status()) + } + + numberOfBooks := 0 + books, ok := libraryMap["books"].([]interface{}) + if ok { + numberOfBooks = len(books) + } + + returnMap := make(map[string]interface{}) + returnMap["numberOfBooks"] = numberOfBooks + + // Marshal asset back to JSON format + returnJSON, nerr := json.Marshal(returnMap) + if nerr != nil { + return nil, errors.WrapError(err, "failed to marshal response") + } + + return returnJSON, nil + }, +} diff --git a/samples/chaincode/cc-tools-demo/txdefs/updateBookTentant.go b/samples/chaincode/cc-tools-demo/txdefs/updateBookTentant.go new file mode 100644 index 000000000..6aef79774 --- /dev/null +++ b/samples/chaincode/cc-tools-demo/txdefs/updateBookTentant.go @@ -0,0 +1,84 @@ +package txdefs + +import ( + "encoding/json" + + "github.com/hyperledger-labs/cc-tools/accesscontrol" + "github.com/hyperledger-labs/cc-tools/assets" + "github.com/hyperledger-labs/cc-tools/errors" + sw "github.com/hyperledger-labs/cc-tools/stubwrapper" + tx "github.com/hyperledger-labs/cc-tools/transactions" +) + +// Updates the tenant of a Book +// POST Method +var UpdateBookTenant = tx.Transaction{ + Tag: "updateBookTenant", + Label: "Update Book Tenant", + Description: "Change the tenant of a book", + Method: "PUT", + Callers: []accesscontrol.Caller{ // Any org can call this transaction + {MSP: `$org\dMSP`}, + {MSP: "Org1MSP"}, + }, + + Args: []tx.Argument{ + { + Tag: "book", + Label: "Book", + Description: "Book", + DataType: "->book", + Required: true, + }, + { + Tag: "tenant", + Label: "tenant", + Description: "New tenant of the book", + DataType: "->person", + }, + }, + Routine: func(stub *sw.StubWrapper, req map[string]interface{}) ([]byte, errors.ICCError) { + bookKey, ok := req["book"].(assets.Key) + if !ok { + return nil, errors.WrapError(nil, "Parameter book must be an asset") + } + tenantKey, ok := req["tenant"].(assets.Key) + if !ok { + return nil, errors.WrapError(nil, "Parameter tenant must be an asset") + } + + // Returns Book from channel + bookAsset, err := bookKey.Get(stub) + if err != nil { + return nil, errors.WrapErrorWithStatus(err, "failed to get asset from the ledger", err.Status()) + } + bookMap := (map[string]interface{})(*bookAsset) + + // Returns person from channel + tenantAsset, err := tenantKey.Get(stub) + if err != nil { + return nil, errors.WrapErrorWithStatus(err, "failed to get asset from the ledger", err.Status()) + } + tenantMap := (map[string]interface{})(*tenantAsset) + + updatedTenantKey := make(map[string]interface{}) + updatedTenantKey["@assetType"] = "person" + updatedTenantKey["@key"] = tenantMap["@key"] + + // Update data + bookMap["currentTenant"] = updatedTenantKey + + bookMap, err = bookAsset.Update(stub, bookMap) + if err != nil { + return nil, errors.WrapError(err, "failed to update asset") + } + + // Marshal asset back to JSON format + bookJSON, nerr := json.Marshal(bookMap) + if nerr != nil { + return nil, errors.WrapError(err, "failed to marshal response") + } + + return bookJSON, nil + }, +} diff --git a/samples/deployment/test-network/.gitignore b/samples/deployment/test-network/.gitignore index f97a41488..a6ca92d3d 100644 --- a/samples/deployment/test-network/.gitignore +++ b/samples/deployment/test-network/.gitignore @@ -1,4 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -**/packages/* -blockchain-explorer \ No newline at end of file +blockchain-explorer/ +fabric-samples/ +.env diff --git a/samples/deployment/test-network/Makefile b/samples/deployment/test-network/Makefile index 1ab5c2af9..d676ae50d 100644 --- a/samples/deployment/test-network/Makefile +++ b/samples/deployment/test-network/Makefile @@ -22,8 +22,13 @@ ecc-container: if [ "${SGX_MODE}" = "HW" ]; then \ export HW_EXTENSION="-hw" ; \ fi && \ + if [ "${WITH_GO}" = "YES" ]; then \ + export ECC_PATH=${CC_PATH}/mrenclave ; \ + else \ + export ECC_PATH=${CC_PATH}/_build/lib ; \ + fi && \ make -C ${CC_PATH} && \ - make -C ${FPC_PATH}/ecc DOCKER_IMAGE=fpc/fpc-${CC_ID}$${HW_EXTENSION} DOCKER_ENCLAVE_SO_PATH=${CC_PATH}/_build/lib all docker + make -C ${FPC_PATH}/ecc DOCKER_IMAGE=fpc/fpc-${CC_ID}$${HW_EXTENSION} DOCKER_ENCLAVE_SO_PATH=${ECC_PATH} all docker ercc-ecc-start: if [ ! -z "${DOCKERD_FPC_PATH}" ]; then \ @@ -35,7 +40,10 @@ ercc-ecc-start: SGX_DEVICE_PATH=$$(if [ -e "/dev/isgx" ]; then echo "/dev/isgx"; elif [ -e "/dev/sgx/enclave" ]; then echo "/dev/sgx/enclave"; else echo "none"; fi) && \ [ "$${SGX_DEVICE_PATH}" != "none" ] || ( echo "ERROR: SGX_MODE is HW but no sgx device found"; exit 1; ) \ fi && \ - env CC_ID=${CC_ID} FPC_VERSION=${FPC_VERSION} docker-compose up + env CC_ID=${CC_ID} FPC_VERSION=${FPC_VERSION} ${DOCKER_COMPOSE} up -d ercc-ecc-stop: - env CC_ID=${CC_ID} FPC_VERSION=${FPC_VERSION} docker-compose down + env CC_ID=${CC_ID} FPC_VERSION=${FPC_VERSION} ${DOCKER_COMPOSE} down + +clobber: + rm -rf blockchain-explorer fabric-samples .env diff --git a/samples/deployment/test-network/README.md b/samples/deployment/test-network/README.md index bdbf76109..8b921c054 100644 --- a/samples/deployment/test-network/README.md +++ b/samples/deployment/test-network/README.md @@ -1,12 +1,13 @@ # FPC and the Fabric-Samples Test Network This guide shows how to deploy and run a FPC Chaincode on test-network provided by [fabric-samples](https://github.com/hyperledger/fabric-samples). -We provide fabric-samples as a submodule in `$FPC_PATH/samples/deployment/test-network/fabric-samples`. -Before moving forward, follow the main [README](../../../README.md) to set up your environment. This guide works also with -the FPC Dev docker container. +Before moving forward, follow the main [README](../../../README.md) to set up your environment. +This guide works also with the FPC Dev docker container. -## Prepare FPC Containers and the Test Network +## Prepare FPC Containers + +[//]: # (TODO lets work this section) FPC requires a special docker container to execute a FPC chaincode, similar to Fabric's `ccenv` container image but with additional support for Intel SGX. You can pull the FPC chaincode environment image (`fabric-private-chaincode-ccenv`) from our Github repository or build them manually as follows: @@ -26,68 +27,52 @@ Use `CC_ID` and `CC_PATH` to define the FPC Chaincode you want to build. cd $FPC_PATH/samples/deployment/test-network export CC_ID=echo export CC_PATH=$FPC_PATH/samples/chaincode/echo +# TODO this needs to be changed! +export CC_VER=$(cat CC_PATH/) make build ``` Note: If you want to build with [mock-enclave](../../../ecc/chaincode/enclave/mock_enclave.go) rather than the real enclave-based one, build with `make build GOTAGS="-tags mock_ecc"` instead. -Next, setup fabric sample network, binaries and docker images. Here we follow the official Fabric [instructions](https://hyperledger-fabric.readthedocs.io/en/release-2.3/install.html). -```bash -cd $FPC_PATH/samples/deployment/test-network -git clone https://github.com/hyperledger/fabric-samples -cd $FPC_PATH/samples/deployment/test-network/fabric-samples -git checkout -b "works" 98028c7 -curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.5.4 1.5.7 -s -``` +## Prepare the Test Network -Before we can start the network, we need to update the Fabric peer configuration to enable FPC support. -That is, we need to install the external builders by adding the following lines to the peers `core.yaml`: -```yaml -chaincode: - externalBuilders: - - path: /opt/gopath/src/github.com/hyperledger/fabric-private-chaincode/fabric/externalBuilder/chaincode_server - name: fpc-external-launcher - propagateEnvironment: - - CORE_PEER_ID - - FABRIC_LOGGING_SPEC -``` +Next, we set up the Fabric samples [test-network](https://github.com/hyperledger/fabric-samples/tree/main/test-network). -Since the Fabric-Samples test network uses docker and docker-compose, we need to ensure that the external Builder -scripts are also available inside the peer container. For this reason, we mount `$FPC_PATH/fabric/externalBuilder/chaincode_server` into -`/opt/gopath/src/github.com/hyperledger/fabric-private-chaincode/fabric/externalBuilder/chaincode_server`. +Since the Fabric samples test network uses docker (and docker-compose) to run the Fabric components, we need to make sure that it works within our FPC dev container environment. +In particular, as we use the host docker daemon, there may be issues with docker mounts. -For convenience, we provide a `setup.sh` script to update the `core.yaml` and the docker compose files to mount the external -Builder. +For convenience, we provide a `setup.sh` script that clones the fabric samples repository, downloads all required fabric container images and binaries, and replaces all relative mount paths in the compose files with absolute path on the host system. ```bash cd $FPC_PATH/samples/deployment/test-network ./setup.sh ``` -## Start the Network + +## Start the Test Network Let's start the Fabric-Samples test network. + ```bash cd $FPC_PATH/samples/deployment/test-network/fabric-samples/test-network -./network.sh up -ca -./network.sh createChannel -c mychannel +./network.sh up createChannel -ca -c mychannel ``` -Next, we install the FPC Enclave Registry and our FPC Chaincode on the network by using the standard Lifecycle commands, -including chaincode `package`, `install`, `approveformyorg`, and `commit`. An important detail here is that the -chaincode packaging differs from traditional chaincode. Since we are using the external Builder and run the FPC Chaincode -as `Chaincode as a Service (CaaS)`, the packaging artifact will contain information including the CaaS endpoint rather -than the actual Chaincode. + +### Install and run the FPC Chaincode + +Next, we install the FPC Enclave Registry and the FPC Chaincode on the network by using the [Chaincode as a Service deployment method](https://github.com/hyperledger/fabric-samples/blob/main/test-network/CHAINCODE_AS_A_SERVICE_TUTORIAL.md). +For convenience, the test network provides a single command `./network.sh deployCCAAS` that executes the necessary steps of the [Fabric chaincode lifecycle](https://hyperledger-fabric.readthedocs.io/en/latest/chaincode_lifecycle.html), +in particular, it internally calls `package`, `install`, `approveformyorg`, and `commit`. + We continue with the following command to install the FPC Chaincode as just described. +Please make sure that you have set `CC_ID` and `CC_VER` variables correctly as described before. + ```bash cd $FPC_PATH/samples/deployment/test-network ./installFPC.sh -# IMPORTANT: a successfully install will show you an `export ...` -# statement as stdout on the command-line. Copy/Paste this statement -# into your shell or below starting of FPC containers will not work properly -# (but also would not give you clear errors that it doesn't!!) ``` Now we have the FPC Chaincode installed on the Fabric peers, but we still need to start our chaincode containers. @@ -97,7 +82,9 @@ Make sure you have set `CC_ID` to the same chaincode ID as used in the earlier s # Start FPC container make ercc-ecc-start ``` + You should see two instances of the FPC Echo chaincode and two instances of the FPC Enclave Registry chaincode running such as in the following example: + ```bash Creating ercc.peer0.org2.example.com ... done Creating ercc.peer0.org1.example.com ... done @@ -111,9 +98,11 @@ ercc.peer0.org1.example.com | 2021-05-11 16:11:32.108 UTC [cgo] 0 -> INFO 001 ercc.peer0.org2.example.com | 2021-05-11 16:11:32.170 UTC [ercc] main -> INFO 002 starting enclave registry (ercc_1.0:db2e97768a87d2b9ed9d86a729a767ef1040fb2e20d2f2a907e727ece7256028) ercc.peer0.org1.example.com | 2021-05-11 16:11:32.199 UTC [ercc] main -> INFO 002 starting enclave registry (ercc_1.0:0919bd1be2e779a582a537da8e29fba241972c3531472006b170b0c26a1d71fb) ``` + The FPC Chaincode is now up and running, ready for processing invocations! Note that the containers are running in foreground in your terminal using docker-compose. + ## Interact with the FPC Chaincode Now we show how to use the [FPC Client SDK](../../../client_sdk/go) to interact with the FPC Chaincode running on the test network. @@ -136,7 +125,6 @@ cd $FPC_PATH/samples/deployment/test-network Now we will use the go app in `$FPC_PATH/samples/application/simple-go` to demonstrate the usage of the FPC Client SDK. In order to initiate the FPC Chaincode enclave and register it with the FPC Enclave Registry, run the app with the `-withLifecycleInitEnclave` flag. - ```bash # for SGX HW mode make sure you set the SGX_CREDENTIALS_PATH path; for simulation mode this is not necessary export SGX_CREDENTIALS_PATH=$FPC_PATH/config/ias @@ -144,9 +132,11 @@ export SGX_CREDENTIALS_PATH=$FPC_PATH/config/ias cd $FPC_PATH/samples/application/simple-go CC_ID=echo ORG_NAME=Org1 go run . -withLifecycleInitEnclave ``` + Note that we execute the go app as `Org1`, thereby creating and registering the FPC Chaincode enclave at `peer0.org1.example.com`. Alternatively, we could run this as `Org2` to initiate the enclave at `peer0.org2.example.com`. Afterwards you _must_ run the application without the `withLifecycleInitEnclave` flag and you can play with multiple organizations. + ```bash cd $FPC_PATH/samples/application/simple-go CC_ID=echo ORG_NAME=Org1 go run . @@ -188,7 +178,9 @@ export SGX_CREDENTIALS_PATH=$FPC_PATH/config/ias ``` ## Shutdown network + Since we opened a new terminal to interact with the FPC Chaincode, to be able to shutdown the FPC chaincode you need to define the environment variables that set the chaincode name and path. + ```bash export CC_ID=echo export CC_PATH=$FPC_PATH/samples/chaincode/echo @@ -198,12 +190,16 @@ cd $FPC_PATH/samples/deployment/test-network/fabric-samples/test-network ``` ## Using HelloWorld chaincode on the test-network + In this section we show how you can run a different FPC chaincode on the test network. For example, you can use the [HelloWorld](../../chaincode/helloworld/README.md) code instead of the echo code. To do so you have to change the values of the environment variables set at the beginning `CC_ID` and `CC_PATH`. + ```bash export CC_ID=helloworld export CC_PATH=$FPC_PATH/samples/chaincode/helloworld ``` + Afterwards to test you would use [simple-cli-go](#How-to-use-simple-cli-go). You would need to verify that the `CC_NAME` variable is set to helloworld and then to interact you would execute the chaincode as follows: + ```bash # interact with the FPC Chaincode ./fpcclient invoke storeAsset asset1 100 @@ -213,6 +209,7 @@ Afterwards to test you would use [simple-cli-go](#How-to-use-simple-cli-go). You ## Debugging For diagnostics, you can run the following to see logs for `peer0.org1.example.com`. + ```bash docker logs -f peer0.org1.example.com docker logs -f ercc.peer0.org1.example.com @@ -220,6 +217,7 @@ docker logs -f ecc.peer0.org1.example.com ``` To interact with the peer using the `peer CLI`, run the following + ```bash cd $FPC_PATH/samples/deployment/test-network/fabric-samples/test-network; export FABRIC_CFG_PATH=$FPC_PATH/samples/deployment/test-network/fabric-samples/config @@ -227,11 +225,15 @@ export PATH=$(readlink -f ../bin):$PATH source ./scripts/envVar.sh; \ setGlobals 1; ``` + and you will be able to run the usual peer cli commands, e.g., + ```bash peer lifecycle chaincode queryinstalled ``` + and, in particular, also access ercc to see the registry state, e.g., + ```bash peer chaincode query -C mychannel -n ercc -c '{"Function": "queryChaincodeEndPoints", "Args" : ["echo"]}' peer chaincode query -C mychannel -n ercc -c '{"Function": "queryListProvisionedEnclaves", "Args" : ["echo"]}' @@ -252,9 +254,10 @@ You can find the Blockchain Explorer configuration files in the `blockchain-expl Note that `setup.sh` may ask you to override any existing configuration files in `blockchain-explorer` and restore the default configuration. To start Blockchain Explorer we use docker compose. Just run the following + ```bash cd $FPC_PATH/samples/deployment/test-network/blockchain-explorer -docker-compose up -d +docker compose up -d ``` Once it is up and running you can access the web interface using your browser. diff --git a/samples/deployment/test-network/core_ext.yaml b/samples/deployment/test-network/core_ext.yaml deleted file mode 100644 index 0143fb6b1..000000000 --- a/samples/deployment/test-network/core_ext.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright IBM Corp. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 - -chaincode: - externalBuilders: - - path: /opt/gopath/src/github.com/hyperledger/fabric-private-chaincode/fabric/externalBuilder/chaincode_server - name: fpc-external-launcher - propagateEnvironment: - - CORE_PEER_ID - - FABRIC_LOGGING_SPEC diff --git a/samples/deployment/test-network/docker-compose.yml b/samples/deployment/test-network/docker-compose.yml index a07d84ef1..e685f34ff 100644 --- a/samples/deployment/test-network/docker-compose.yml +++ b/samples/deployment/test-network/docker-compose.yml @@ -3,19 +3,18 @@ # # SPDX-License-Identifier: Apache-2.0 -version: '3' - services: # org1 ecc.peer0.org1.example.com: - container_name: ${CC_ID}.peer0.org1.example.com - hostname: ${CC_ID}.peer0.org1.example.com + container_name: peer0org1_${CC_ID}_ccaas image: fpc/fpc-${CC_ID}${HW_EXTENSION:-}:${FPC_VERSION} environment: - - CHAINCODE_SERVER_ADDRESS=${CC_ID}.peer0.org1.example.com:9999 + - CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 - CHAINCODE_PKG_ID=${ORG1_ECC_PKG_ID} - FABRIC_LOGGING_SPEC=${FABRIC_LOGGING_SPEC:-DEBUG} - SGX_MODE=${SGX_MODE:-SIM} + - RUN_CCAAS=true + - FPC_ENABLED=true networks: - default volumes: @@ -25,11 +24,10 @@ services: - ${SGX_DEVICE_PATH:-/dev/null}:${SGX_DEVICE_PATH:-/dev/null} ercc.peer0.org1.example.com: - container_name: ercc.peer0.org1.example.com - hostname: ercc.peer0.org1.example.com + container_name: peer0org1_ercc_ccaas image: fpc/ercc:${FPC_VERSION} environment: - - CHAINCODE_SERVER_ADDRESS=ercc.peer0.org1.example.com:9999 + - CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 - CHAINCODE_PKG_ID=${ORG1_ERCC_PKG_ID} - FABRIC_LOGGING_SPEC=${FABRIC_LOGGING_SPEC:-DEBUG} - SGX_MODE=${SGX_MODE:-SIM} @@ -38,14 +36,15 @@ services: # org2 ecc.peer0.org2.example.com: - container_name: ${CC_ID}.peer0.org2.example.com - hostname: ${CC_ID}.peer0.org2.example.com + container_name: peer0org2_${CC_ID}_ccaas image: fpc/fpc-${CC_ID}${HW_EXTENSION:-}:${FPC_VERSION} environment: - - CHAINCODE_SERVER_ADDRESS=${CC_ID}.peer0.org2.example.com:9999 + - CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 - CHAINCODE_PKG_ID=${ORG2_ECC_PKG_ID} - FABRIC_LOGGING_SPEC=${FABRIC_LOGGING_SPEC:-DEBUG} - SGX_MODE=${SGX_MODE:-SIM} + - RUN_CCAAS=true + - FPC_ENABLED=true networks: - default volumes: @@ -55,11 +54,10 @@ services: - ${SGX_DEVICE_PATH:-/dev/null}:${SGX_DEVICE_PATH:-/dev/null} ercc.peer0.org2.example.com: - container_name: ercc.peer0.org2.example.com - hostname: ercc.peer0.org2.example.com + container_name: peer0org2_ercc_ccaas image: fpc/ercc:${FPC_VERSION} environment: - - CHAINCODE_SERVER_ADDRESS=ercc.peer0.org2.example.com:9999 + - CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 - CHAINCODE_PKG_ID=${ORG2_ERCC_PKG_ID} - FABRIC_LOGGING_SPEC=${FABRIC_LOGGING_SPEC:-DEBUG} - SGX_MODE=${SGX_MODE:-SIM} @@ -68,5 +66,5 @@ services: networks: default: - external: - name: fabric_test + name: fabric_test + external: true diff --git a/samples/deployment/test-network/fabric-samples b/samples/deployment/test-network/fabric-samples deleted file mode 160000 index 36ad01012..000000000 --- a/samples/deployment/test-network/fabric-samples +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 36ad010124bc9b96a680dedf296a06ea789fe16d diff --git a/samples/deployment/test-network/installFPC.sh b/samples/deployment/test-network/installFPC.sh index 077aea60d..64139df6c 100755 --- a/samples/deployment/test-network/installFPC.sh +++ b/samples/deployment/test-network/installFPC.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Copyright IBM Corp. All Rights Reserved. # Copyright 2020 Intel Corporation @@ -7,161 +7,43 @@ set -euo pipefail -#DEBUG=true # uncomment (or define when calling script) to show debug output -# Note: to see only log and not peer command output (which is all on stderr), -# run the script with '... 2>/dev/null' .. +CHANNEL_NAME=${CHANNEL_NAME:-mychannel} +FABRIC_SAMPLES=${FPC_PATH}/samples/deployment/test-network/fabric-samples +NETWORK_CMD=${FABRIC_SAMPLES}/test-network/network.sh -if [[ -z "${FPC_PATH}" ]]; then - echo "Error: FPC_PATH not set" - exit 1 +if [ ! -f "${NETWORK_CMD}" ]; then + echo "Error: ${NETWORK_CMD} does not exist" + exit 1 fi -if [[ -z "${CC_ID}" ]]; then - echo "Error: CC_ID not set" - exit 1 -fi -if [[ -z "${CC_PATH}" ]]; then - echo "Error: CC_PATH not set" - exit 1 -fi -CHANNEL_ID=mychannel -PEERS=("peer0.org1.example.com" "peer0.org2.example.com") +# define endorsement policies +ERCC_EP="OutOf(2,'Org1MSP.peer','Org2MSP.peer')" +ECC_EP="OutOf(2,'Org1MSP.peer','Org2MSP.peer')" -ERCC_EP="OutOf(2, 'Org1MSP.peer', 'Org2MSP.peer')" -ECC_EP="OutOf(2, 'Org1MSP.peer', 'Org2MSP.peer')" - -CC_VER="${CC_VER:-$(cat "${CC_PATH}/_build/lib/mrenclave")}" +# define chaincode details ERCC_ID="ercc" ERCC_VER="1.0" -: ${SEQ_NUM:=1} - - - -# Prepare -#------------ - -TEST_NET_SCRIPT_PATH=${FPC_PATH}/samples/deployment/test-network -SAMPLES_PATH=${TEST_NET_SCRIPT_PATH}/fabric-samples -NETWORK_PATH=${SAMPLES_PATH}/test-network -export FABRIC_CFG_PATH=${SAMPLES_PATH}/config -export PATH=${SAMPLES_PATH}/bin:$PATH - -# Orderer address and certs, including hostname override as we access via localhost -ORDERER_ARGS="-o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${NETWORK_PATH}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" - -# Commit (but not approveformyorg) requires TLS Root CAs for all peers -PEER1_ARGS="--peerAddresses localhost:7051 --tlsRootCertFiles ${NETWORK_PATH}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" -PEER2_ARGS="--peerAddresses localhost:9051 --tlsRootCertFiles ${NETWORK_PATH}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -PEER_ARGS="${PEER1_ARGS} ${PEER2_ARGS}" - -# read test-network settings - -cd ${NETWORK_PATH} || exit -. ./scripts/envVar.sh -# scripts defined in fail if some vars are not defined (due to 'set -e...') -# -> make sure they are at least defined as empty (but allow override by caller) -OVERRIDE_ORG=${OVERRIDE_ORG:-} -VERBOSE=${VERBOSE:-} - - - -# Install ERCC and ECC -#--------------------- -echo "" -echo "Packaging chaincodes: ERCC (id=${ERCC_ID}/version=${ERCC_VER}) and ECC (id=${CC_ID}/version=${CC_VER}) for peers ${PEERS[@]}" - -PKG_PATH=${TEST_NET_SCRIPT_PATH}/packages - -# as Org 1 -${TEST_NET_SCRIPT_PATH}/package.sh "${PKG_PATH}" "${ERCC_ID}" "${ERCC_VER}" "${CC_ID}" "${CC_VER}" "${PEERS[0]}" - -# as Org 2 -${TEST_NET_SCRIPT_PATH}/package.sh "${PKG_PATH}" "${ERCC_ID}" "${ERCC_VER}" "${CC_ID}" "${CC_VER}" "${PEERS[1]}" - - -# Install ERCC and ECC -#--------------------- -echo "" -echo "Installing chaincodes" - -# as Org 1 -setGlobals 1 -peer lifecycle chaincode install $PKG_PATH/${ERCC_ID}.${PEERS[0]}.tgz -peer lifecycle chaincode install $PKG_PATH/${CC_ID}.${PEERS[0]}.tgz -peer lifecycle chaincode queryinstalled -ORG1_ALL_INSTALLED=/tmp/installed_chaincodes.org1 -peer lifecycle chaincode queryinstalled > ${ORG1_ALL_INSTALLED} -ORG1_ERCC_PKG_ID=$(cat ${ORG1_ALL_INSTALLED} | grep ${ERCC_ID} | awk '{print $3}' | sed 's/.$//') -ORG1_ECC_PKG_ID=$(cat ${ORG1_ALL_INSTALLED} | grep ${CC_ID} | awk '{print $3}' | sed 's/.$//') - -# as Org 2 -setGlobals 2 -peer lifecycle chaincode install $PKG_PATH/${ERCC_ID}.${PEERS[1]}.tgz -peer lifecycle chaincode install $PKG_PATH/${CC_ID}.${PEERS[1]}.tgz -peer lifecycle chaincode queryinstalled -ORG2_ALL_INSTALLED=/tmp/installed_chaincodes.org2 -peer lifecycle chaincode queryinstalled > ${ORG2_ALL_INSTALLED} -ORG2_ERCC_PKG_ID=$(cat ${ORG2_ALL_INSTALLED} | grep ${ERCC_ID} | awk '{print $3}' | sed 's/.$//') -ORG2_ECC_PKG_ID=$(cat ${ORG2_ALL_INSTALLED} | grep ${CC_ID} | awk '{print $3}' | sed 's/.$//') - - -# Approve -#------------ -echo "" -echo "Approving both chaincodes" - -# as Org 1 -setGlobals 1 -peer lifecycle chaincode approveformyorg ${ORDERER_ARGS} --channelID ${CHANNEL_ID} --name ${ERCC_ID} --signature-policy "${ERCC_EP}" --version ${ERCC_VER} --package-id ${ORG1_ERCC_PKG_ID} --sequence ${SEQ_NUM} -peer lifecycle chaincode approveformyorg ${ORDERER_ARGS} --channelID ${CHANNEL_ID} --name ${CC_ID} --signature-policy "${ECC_EP}" --version ${CC_VER} --package-id ${ORG1_ECC_PKG_ID} --sequence ${SEQ_NUM} - -# as Org 2 -setGlobals 2 -peer lifecycle chaincode approveformyorg ${ORDERER_ARGS} --channelID ${CHANNEL_ID} --name ${ERCC_ID} --signature-policy "${ERCC_EP}" --version ${ERCC_VER} --package-id ${ORG2_ERCC_PKG_ID} --sequence ${SEQ_NUM} -peer lifecycle chaincode approveformyorg ${ORDERER_ARGS} --channelID ${CHANNEL_ID} --name ${CC_ID} --signature-policy "${ECC_EP}" --version ${CC_VER} --package-id ${ORG2_ECC_PKG_ID} --sequence ${SEQ_NUM} - - -# Commit -#------------ -echo "" -echo "Committing both chaincodes" - -# as Org 1 (as only org) -setGlobals 1 -# DEBUG / TODO clean-me up -peer lifecycle chaincode commit ${ORDERER_ARGS} ${PEER_ARGS} --channelID ${CHANNEL_ID} --name ${ERCC_ID} --signature-policy "${ERCC_EP}" --version ${ERCC_VER} --sequence ${SEQ_NUM} -peer lifecycle chaincode commit ${ORDERER_ARGS} ${PEER_ARGS} --channelID ${CHANNEL_ID} --name ${CC_ID} --signature-policy "${ECC_EP}" --version ${CC_VER} --sequence ${SEQ_NUM} - - -# Show committed chaincodes -# on Org 1 -setGlobals 1 -echo "" -echo "Check committed chaincodes on peer from Org1" -peer lifecycle chaincode querycommitted --output json ${ORDERER_ARGS} --channelID ${CHANNEL_ID} --name ${ERCC_ID} -peer lifecycle chaincode querycommitted --output json ${ORDERER_ARGS} --channelID ${CHANNEL_ID} --name ${CC_ID} +# this is important +CC_ID=${CC_ID} +CC_VER=${CC_VER} -# on Org 2 -setGlobals 2 -echo "" -echo "Check committed chaincodes on peer from Org2" -peer lifecycle chaincode querycommitted --output json ${ORDERER_ARGS} --channelID ${CHANNEL_ID} --name ${ERCC_ID} -peer lifecycle chaincode querycommitted --output json ${ORDERER_ARGS} --channelID ${CHANNEL_ID} --name ${CC_ID} +CC_PATH="." # the actual path is not needed here since we build the container images manually +# install ercc and ecc +${NETWORK_CMD} deployCCAAS -c "$CHANNEL_NAME" -ccn "$ERCC_ID" -ccp "$CC_PATH" -ccv "$ERCC_VER" -ccep "$ERCC_EP" -ccaasdocker false +${NETWORK_CMD} deployCCAAS -c "$CHANNEL_NAME" -ccn "$CC_ID" -ccp "$CC_PATH" -ccv "$CC_VER" -ccep "$ECC_EP" -ccaasdocker false -# Note: above does _not_ yet complete the FPC chaincode initialization. -# The missing 'peer lifecycle chaincode initEnclave' command for CaaS -# must be executed after docker-compose is started. For the test-scenario -# this is done '$FPC_PATH/client_sdk/go/test/main.go' +# export chaincode package ids +ORG1_ERCC_PKG_ID=$(${NETWORK_CMD} cc list -org 1 | grep "Label: ${ERCC_ID}_${ERCC_VER}" | awk '{print $3}' | sed 's/.$//') +ORG2_ERCC_PKG_ID=$(${NETWORK_CMD} cc list -org 2 | grep "Label: ${ERCC_ID}_${ERCC_VER}" | awk '{print $3}' | sed 's/.$//') +ORG1_ECC_PKG_ID=$(${NETWORK_CMD} cc list -org 1 | grep "Label: ${CC_ID}_${CC_VER}" | awk '{print $3}' | sed 's/.$//') +ORG2_ECC_PKG_ID=$(${NETWORK_CMD} cc list -org 2 | grep "Label: ${CC_ID}_${CC_VER}" | awk '{print $3}' | sed 's/.$//') -cat < .env << EOF +ORG1_ECC_PKG_ID="${ORG1_ECC_PKG_ID}" +ORG1_ERCC_PKG_ID="${ORG1_ERCC_PKG_ID}" +ORG2_ECC_PKG_ID="${ORG2_ECC_PKG_ID}" +ORG2_ERCC_PKG_ID="${ORG2_ERCC_PKG_ID}" EOF diff --git a/samples/deployment/test-network/package.sh b/samples/deployment/test-network/package.sh deleted file mode 100755 index 40dc6bd4e..000000000 --- a/samples/deployment/test-network/package.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -# Copyright IBM Corp. All Rights Reserved. -# Copyright 2020 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 - -# Package a fpc chaincode for CaaS mode -# (for normal external-builder, use '$FPC_PATH/fabric/bin/peer.sh lifecycle chaincode package') - -set -euo pipefail - -#DEBUG=true # uncomment (or define when calling script) to show debug output - -if [[ -z "${FPC_PATH}" ]]; then - echo "Error: FPC_PATH not set" - exit 1 -fi - -. "${FPC_PATH}"/utils/packaging/utils.sh - -if [ "$#" -ne 6 ]; then - echo "ERROR: incorrect number of parameters" >&2 - echo "Use: ./package.sh " >&2 - - exit 1 -fi - - -DEPLOYMENT_PATH="$1" -ERCC_ID="$2" -ERCC_VER="$3" -CC_ID="$4" -CC_VER="$5" -PEER="$6" - -TYPE="external" -CHAINCODE_SERVER_PORT=9999 - -endpoint="${ERCC_ID}.${PEER}:${CHAINCODE_SERVER_PORT}" -packageName="${ERCC_ID}.${PEER}.tgz" -packageChaincode "${DEPLOYMENT_PATH}" "${packageName}" "${ERCC_ID}" "${ERCC_VER}" "${TYPE}" "${endpoint}" "${PEER}" - -endpoint="${CC_ID}.${PEER}:${CHAINCODE_SERVER_PORT}" -packageName="${CC_ID}.${PEER}.tgz" -packageChaincode "${DEPLOYMENT_PATH}" "${packageName}" "${CC_ID}" "${CC_VER}" "${TYPE}" "${endpoint}" "${PEER}" diff --git a/samples/deployment/test-network/setup.sh b/samples/deployment/test-network/setup.sh index 43d320662..d67723af2 100755 --- a/samples/deployment/test-network/setup.sh +++ b/samples/deployment/test-network/setup.sh @@ -23,33 +23,33 @@ backup() { fi } +############################################################################################## +# Get the fabric samples repo and fetch binaries and container images +############################################################################################## + echo "Prepare fabric samples test-network for FPC" FABRIC_SAMPLES=${FPC_PATH}/samples/deployment/test-network/fabric-samples -CORE_PATH=${FABRIC_SAMPLES}/config/core.yaml -DOCKER_PATH=${FABRIC_SAMPLES}/test-network/docker -DOCKER_COMPOSE_TEST_NET=${DOCKER_PATH}/docker-compose-test-net.yaml -DOCKER_COMPOSE_CA=${DOCKER_PATH}/docker-compose-ca.yaml -if [ ! -d "${FABRIC_SAMPLES}/bin" ]; then - echo "Error: no fabric binaries found, see README.md" - exit 1 +if [ ! -d "${FABRIC_SAMPLES}" ]; then + echo "Fabric samples not found! cloning now!" + git clone https://github.com/hyperledger/fabric-samples "${FABRIC_SAMPLES}" + pushd "${FABRIC_SAMPLES}" + git checkout -b "works" 50b69f6 + popd fi - -############################################### -# Adding FPC support to core.yaml -############################################### - -echo "Adding FPC external builder to core.yaml" -# Create a backup copy of `core.yaml` first and always work from there. -backup ${CORE_PATH} -yq eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' -i ${CORE_PATH} core_ext.yaml +if [ ! -d "${FABRIC_SAMPLES}/bin" ]; then + echo "Error: no fabric binaries found. Let's run 'network.sh prereq'" + pushd "${FABRIC_SAMPLES}/test-network" + ./network.sh prereq + popd +fi -############################################### +############################################################################################## # Resolve relative paths for docker volumes -############################################### +############################################################################################## # Also there is another issue with this approach here. When working completely inside the FPC dev-container, # the volume mounts won't work. The reason is that the docker daemon provided by the host cannot parse volume paths. @@ -57,7 +57,7 @@ yq eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' -i ${CORE_PATH} co # The correct path from the docker daemon perspective is something like # `/Users/marcusbrandenburger/Developer/gocode/src/github.com/hyperledger/fabric-private-chaincode/` (in my case on the mac). # For this reason we use DOCKERD_FPC_PATH to resolve relative host paths. -if [ ! -z ${DOCKERD_FPC_PATH+x} ]; then +if [ -n "${DOCKERD_FPC_PATH+x}" ]; then echo "Oo we are in docker mode! we need to use the host fpc path" FPC_PATH_HOST=${DOCKERD_FPC_PATH} else @@ -65,28 +65,24 @@ else fi echo "set FPC_PATH_HOST = ${FPC_PATH_HOST}" -FABRIC_SAMPLES_HOST=${FPC_PATH_HOST}/samples/deployment/test-network/fabric-samples +FABRIC_SAMPLES_HOST=${FPC_PATH}/samples/deployment/test-network/fabric-samples +DOCKERD_FABRIC_SAMPLES_HOST=${DOCKERD_FPC_PATH}samples/deployment/test-network/fabric-samples +TEST_NETWORK_HOST=${FABRIC_SAMPLES_HOST}/test-network +DOCKERD_TEST_NETWORK_HOST=${DOCKERD_FABRIC_SAMPLES_HOST}/test-network -echo "Resolving relative docker volume paths in ..." +echo "set DOCKERD_TEST_NETWORK_HOST = ${DOCKERD_TEST_NETWORK_HOST}" +echo "set TEST_NETWORK_HOST = ${TEST_NETWORK_HOST}" +echo "Resolving relative docker volume paths" -echo "${DOCKER_COMPOSE_TEST_NET}" -backup ${DOCKER_COMPOSE_TEST_NET} -sed -i "s+\.\./+${FABRIC_SAMPLES_HOST}/test-network/+g" "${DOCKER_COMPOSE_TEST_NET}" +# replace "../" with absolute path +find "${TEST_NETWORK_HOST}/compose" -maxdepth 1 \( -name '*compose*.yaml' -o -name '*compose*.yml' \) -exec sed -i -E 's+(- )(\.\.)(/)+\1'"${DOCKERD_TEST_NETWORK_HOST}"'\3+g' {} \; +# replace "./" with absolute path +find "${TEST_NETWORK_HOST}/compose" -mindepth 2 -maxdepth 2 \( -name '*compose*.yaml' -o -name '*compose*.yml' \) -exec sed -i -E 's+(- )(\.)(/)+\1'"${DOCKERD_TEST_NETWORK_HOST}/compose"'\3+g' {} \; -echo "${DOCKER_COMPOSE_CA}" -backup ${DOCKER_COMPOSE_CA} -sed -i "s+\.\./+${FABRIC_SAMPLES_HOST}/test-network/+g" "${DOCKER_COMPOSE_CA}" -echo "${DOCKER_COMPOSE_TEST_NET}" -peers=("peer0.org1.example.com" "peer0.org2.example.com") -for p in "${peers[@]}"; do - yq ".services.\"$p\".volumes += [\"${FPC_PATH_HOST}:/opt/gopath/src/github.com/hyperledger/fabric-private-chaincode\"]" -i "${DOCKER_COMPOSE_TEST_NET}" - yq ".services.\"$p\".volumes += [\"${FABRIC_SAMPLES_HOST}/config/core.yaml:/etc/hyperledger/fabric/core.yaml\"]" -i "${DOCKER_COMPOSE_TEST_NET}" -done - -############################################### +############################################################################################## # setup blockchain explorer -############################################### +############################################################################################## echo "Preparing blockchain explorer" BE_PATH="${FPC_PATH}/samples/deployment/test-network/blockchain-explorer" @@ -108,19 +104,20 @@ if [[ -f "${BE_CONFIG}" ]] && [[ -f "${BE_CONNECTIONS_PROFILE}" ]] && [[ -f "${B fi # create folders -mkdir -p ${BE_PATH}/connection-profile +mkdir -p "${BE_PATH}/connection-profile" # download configuration files -wget -O ${BE_CONFIG} https://raw.githubusercontent.com/hyperledger/blockchain-explorer/main/examples/net1/config.json -wget -O ${BE_CONNECTIONS_PROFILE} https://raw.githubusercontent.com/hyperledger/blockchain-explorer/main/examples/net1/connection-profile/test-network.json -wget -O ${BE_DOCKER_COMPOSE} https://raw.githubusercontent.com/hyperledger/blockchain-explorer/main/docker-compose.yaml +wget -O "${BE_CONFIG}" https://raw.githubusercontent.com/hyperledger/blockchain-explorer/main/examples/net1/config.json +wget -O "${BE_CONNECTIONS_PROFILE}" https://raw.githubusercontent.com/hyperledger/blockchain-explorer/main/examples/net1/connection-profile/test-network.json +wget -O "${BE_DOCKER_COMPOSE}" https://raw.githubusercontent.com/hyperledger/blockchain-explorer/main/docker-compose.yaml + +cat > "${BE_PATH}/.env" << EOF +EXPLORER_CONFIG_FILE_PATH=${BE_PATH}/config.json +EXPLORER_PROFILE_DIR_PATH=${BE_PATH}/connection-profile +FABRIC_CRYPTO_PATH=${TEST_NETWORK_HOST}/organizations +EOF -# prepare BE docker compose file to be used in FPC docker dev environment and with localhost -echo "Resolving relative volume paths in ..." -echo "${BE_DOCKER_COMPOSE}" -sed -i "s+./examples/net1+${BE_PATH_HOST}+g" "${BE_DOCKER_COMPOSE}" -sed -i "s+/fabric-path/fabric-samples+${FABRIC_SAMPLES_HOST}+g" "${BE_DOCKER_COMPOSE}" -############################################### +############################################################################################## echo "Setup done!" diff --git a/samples/deployment/test-network/update-connection.sh b/samples/deployment/test-network/update-connection.sh index 742641a4e..f2f37c57c 100755 --- a/samples/deployment/test-network/update-connection.sh +++ b/samples/deployment/test-network/update-connection.sh @@ -51,9 +51,9 @@ for org in "${orgs[@]}"; do yq ".organizations.${org^}.users.${user}.cert.path = \"${CERTS[0]}\"" -i "${CONNECTIONS_PATH}" yq ".organizations.${org^}.users.${user}.key.path = \"${KEYS[0]}\"" -i "${CONNECTIONS_PATH}" - # add channels and entity matcher - yq eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' -i ${CONNECTIONS_PATH} < "${temp_yaml}" <> "${tmp_dir}/peers-${org}.yaml" done diff --git a/samples/deployment/test-network/update-external-connection.sh b/samples/deployment/test-network/update-external-connection.sh new file mode 100755 index 000000000..054be662f --- /dev/null +++ b/samples/deployment/test-network/update-external-connection.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +# Copyright IBM Corp. All Rights Reserved. +# Copyright 2020 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +set -euo pipefail + +if [[ -z "${FPC_PATH}" ]]; then + echo "Error: FPC_PATH not set" + exit 1 +fi + +trap cleanup SIGINT SIGTERM ERR EXIT +cleanup() { + trap - SIGINT SIGTERM ERR EXIT +} + +backup() { + FILE=$1 + BACKUP="${FILE}.backup" + + if [[ -e "${BACKUP}" ]]; then + cp "${BACKUP}" "${FILE}" + else + cp "${FILE}" "${BACKUP}" + fi +} + +orgs=("org1" "org2") +user="Admin" + +shopt -s nullglob + +for org in "${orgs[@]}"; do + + ORG_PATH=${FPC_PATH}/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/${org}.example.com + EXTERNAL_CONNECTIONS_PATH=${ORG_PATH}/external-connection-${org}.yaml + CONNECTIONS_PATH=${ORG_PATH}/connection-${org}.yaml + + # Copy the file from the connection profile + cp "${CONNECTIONS_PATH}" "${EXTERNAL_CONNECTIONS_PATH}" + + backup "${EXTERNAL_CONNECTIONS_PATH}" + + + # This is needed in both files + yq eval ".\"peer0.org1.example.com\".url = \"grpcs://peer0.org1.example.com:7051\"" -i "$EXTERNAL_CONNECTIONS_PATH" + yq eval ".\"peer0.org2.example.com\".url = \"grpcs://peer0.org2.example.com:9051\"" -i "$EXTERNAL_CONNECTIONS_PATH" + # Check if the org is org1 + if [[ "$org" == "org1" ]]; then + # edit localhost urls to use hostnames for org1 + yq eval ".peers.\"peer0.org1.example.com\".url = \"grpcs://peer0.org1.example.com:7051\"" -i "$EXTERNAL_CONNECTIONS_PATH" + yq eval ".certificateAuthorities.\"ca.org1.example.com\".url = \"https://ca.org1.example.com:7054\"" -i "$EXTERNAL_CONNECTIONS_PATH" + + # Check if the org is org2 + elif [[ "$org" == "org2" ]]; then + # edit localhost urls to use hostnames for org2 + yq eval ".peers.\"peer0.org2.example.com\".url = \"grpcs://peer0.org2.example.com:9051\"" -i "$EXTERNAL_CONNECTIONS_PATH" + yq eval ".certificateAuthorities.\"ca.org2.example.com\".url = \"https://ca.org2.example.com:8054\"" -i "$EXTERNAL_CONNECTIONS_PATH" + fi + # remove entity matcher + yq eval 'del(.entityMatchers)' -i "$EXTERNAL_CONNECTIONS_PATH" + +done + +echo "Updated!"