From cb886be4668a9cbafdde3253b844a78823e24106 Mon Sep 17 00:00:00 2001 From: Matthew B White Date: Mon, 30 Jan 2023 15:12:15 +0000 Subject: [PATCH] Commercial Paper The Commercial Paper example code hasn't kept pace with the state-of-the-art of writing applications and chaincode Whilst the scenario is still a valid usecase, the example itself is not helping - in fact causing confusion. Signed-off-by: Matthew B White --- commercial-paper/.gitignore | 4 - commercial-paper/README.md | 646 ------------------ commercial-paper/img/overview.png | Bin 122143 -> 0 bytes commercial-paper/img/transaction-flow.png | Bin 21986 -> 0 bytes commercial-paper/network-clean.sh | 26 - commercial-paper/network-starter.sh | 36 - .../organization/digibank/.gitignore | 1 - .../digibank/application-java/.gitignore | 1 - .../.settings/org.eclipse.jdt.core.prefs | 6 - .../.settings/org.eclipse.m2e.core.prefs | 4 - .../digibank/application-java/pom.xml | 96 --- .../src/org/digibank/AddToWallet.java | 68 -- .../src/org/digibank/Buy.java | 74 -- .../src/org/digibank/Redeem.java | 73 -- .../src/org/papernet/CommercialPaper.java | 183 ----- .../src/org/papernet/ledgerapi/State.java | 60 -- .../digibank/application/.eslintrc.js | 37 - .../digibank/application/.gitignore | 1 - .../digibank/application/addToWallet.js | 55 -- .../organization/digibank/application/buy.js | 105 --- .../digibank/application/buy_request.js | 105 --- .../digibank/application/enrollUser.js | 56 -- .../digibank/application/package.json | 20 - .../digibank/application/queryapp.js | 155 ----- .../digibank/application/redeem.js | 106 --- .../configuration/cli/docker-compose.yml | 37 - .../configuration/cli/monitordocker.sh | 31 - .../contract-go/commercial-paper/paper.go | 139 ---- .../commercial-paper/paper_test.go | 125 ---- .../commercial-paper/papercontext.go | 35 - .../commercial-paper/papercontext_test.go | 31 - .../commercial-paper/papercontract.go | 96 --- .../commercial-paper/papercontract_test.go | 185 ----- .../contract-go/commercial-paper/paperlist.go | 55 -- .../commercial-paper/paperlist_test.go | 103 --- .../organization/digibank/contract-go/go.mod | 39 -- .../organization/digibank/contract-go/go.sum | 486 ------------- .../digibank/contract-go/ledger-api/state.go | 27 - .../contract-go/ledger-api/statelist.go | 61 -- .../organization/digibank/contract-go/main.go | 35 - .../digibank/contract-java/.gitignore | 10 - .../digibank/contract-java/build.gradle | 37 - .../gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../digibank/contract-java/gradlew | 188 ----- .../digibank/contract-java/gradlew.bat | 100 --- .../digibank/contract-java/settings.gradle | 2 - .../contract-java/shadow-build.gradle | 49 -- .../java/org/example/CommercialPaper.java | 183 ----- .../org/example/CommercialPaperContext.java | 15 - .../org/example/CommercialPaperContract.java | 170 ----- .../src/main/java/org/example/PaperList.java | 31 - .../java/org/example/ledgerapi/State.java | 60 -- .../example/ledgerapi/StateDeserializer.java | 6 - .../java/org/example/ledgerapi/StateList.java | 48 -- .../example/ledgerapi/impl/StateListImpl.java | 100 --- .../digibank/contract/.editorconfig | 16 - .../digibank/contract/.eslintignore | 5 - .../digibank/contract/.eslintrc.js | 37 - .../organization/digibank/contract/.npmignore | 77 --- .../organization/digibank/contract/index.js | 10 - .../digibank/contract/ledger-api/state.js | 105 --- .../digibank/contract/ledger-api/statelist.js | 74 -- .../digibank/contract/lib/paper.js | 121 ---- .../digibank/contract/lib/papercontract.js | 339 --------- .../digibank/contract/lib/paperlist.js | 35 - .../digibank/contract/lib/queries.js | 217 ------ .../digibank/contract/package.json | 49 -- .../digibank/contract/test/contract.js | 43 -- .../organization/digibank/digibank.sh | 38 -- .../organization/digibank/gateway/.gitkeep | 0 .../organization/magnetocorp/.gitignore | 1 - .../magnetocorp/application-java/.gitignore | 1 - .../org.eclipse.core.resources.prefs | 3 - .../.settings/org.eclipse.m2e.core.prefs | 4 - .../magnetocorp/application-java/pom.xml | 96 --- .../src/org/magnetocorp/AddToWallet.java | 68 -- .../src/org/magnetocorp/Issue.java | 75 -- .../src/org/papernet/CommercialPaper.java | 185 ----- .../src/org/papernet/ledgerapi/State.java | 60 -- .../magnetocorp/application/.eslintrc.js | 37 - .../magnetocorp/application/.gitignore | 1 - .../magnetocorp/application/addToWallet.js | 55 -- .../magnetocorp/application/cpListener.js | 103 --- .../magnetocorp/application/enrollUser.js | 56 -- .../magnetocorp/application/issue.js | 103 --- .../magnetocorp/application/package.json | 20 - .../magnetocorp/application/transfer.js | 103 --- .../configuration/cli/docker-compose.yml | 37 - .../configuration/cli/monitordocker.sh | 31 - .../contract-go/commercial-paper/paper.go | 139 ---- .../commercial-paper/paper_test.go | 125 ---- .../commercial-paper/papercontext.go | 35 - .../commercial-paper/papercontext_test.go | 31 - .../commercial-paper/papercontract.go | 96 --- .../commercial-paper/papercontract_test.go | 185 ----- .../contract-go/commercial-paper/paperlist.go | 55 -- .../commercial-paper/paperlist_test.go | 103 --- .../magnetocorp/contract-go/go.mod | 39 -- .../magnetocorp/contract-go/go.sum | 486 ------------- .../contract-go/ledger-api/state.go | 27 - .../contract-go/ledger-api/statelist.go | 61 -- .../magnetocorp/contract-go/main.go | 35 - .../magnetocorp/contract-java/build.gradle | 49 -- .../gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../magnetocorp/contract-java/gradlew | 188 ----- .../magnetocorp/contract-java/gradlew.bat | 100 --- .../magnetocorp/contract-java/settings.gradle | 2 - .../java/org/example/CommercialPaper.java | 183 ----- .../org/example/CommercialPaperContext.java | 15 - .../org/example/CommercialPaperContract.java | 170 ----- .../src/main/java/org/example/PaperList.java | 31 - .../java/org/example/ledgerapi/State.java | 60 -- .../example/ledgerapi/StateDeserializer.java | 6 - .../java/org/example/ledgerapi/StateList.java | 48 -- .../example/ledgerapi/impl/StateListImpl.java | 100 --- .../magnetocorp/contract/.editorconfig | 16 - .../magnetocorp/contract/.eslintignore | 5 - .../magnetocorp/contract/.eslintrc.js | 37 - .../magnetocorp/contract/.npmignore | 77 --- .../magnetocorp/contract/index.js | 10 - .../magnetocorp/contract/ledger-api/state.js | 105 --- .../contract/ledger-api/statelist.js | 74 -- .../magnetocorp/contract/lib/paper.js | 121 ---- .../magnetocorp/contract/lib/papercontract.js | 339 --------- .../magnetocorp/contract/lib/paperlist.js | 35 - .../magnetocorp/contract/lib/queries.js | 216 ------ .../magnetocorp/contract/package.json | 49 -- .../magnetocorp/contract/test/contract.js | 43 -- .../organization/magnetocorp/gateway/.gitkeep | 0 .../organization/magnetocorp/magnetocorp.sh | 38 -- .../organization/magnetocorp/t.js | 1 - 133 files changed, 10152 deletions(-) delete mode 100644 commercial-paper/.gitignore delete mode 100644 commercial-paper/README.md delete mode 100644 commercial-paper/img/overview.png delete mode 100644 commercial-paper/img/transaction-flow.png delete mode 100755 commercial-paper/network-clean.sh delete mode 100755 commercial-paper/network-starter.sh delete mode 100644 commercial-paper/organization/digibank/.gitignore delete mode 100644 commercial-paper/organization/digibank/application-java/.gitignore delete mode 100644 commercial-paper/organization/digibank/application-java/.settings/org.eclipse.jdt.core.prefs delete mode 100644 commercial-paper/organization/digibank/application-java/.settings/org.eclipse.m2e.core.prefs delete mode 100644 commercial-paper/organization/digibank/application-java/pom.xml delete mode 100644 commercial-paper/organization/digibank/application-java/src/org/digibank/AddToWallet.java delete mode 100644 commercial-paper/organization/digibank/application-java/src/org/digibank/Buy.java delete mode 100644 commercial-paper/organization/digibank/application-java/src/org/digibank/Redeem.java delete mode 100644 commercial-paper/organization/digibank/application-java/src/org/papernet/CommercialPaper.java delete mode 100644 commercial-paper/organization/digibank/application-java/src/org/papernet/ledgerapi/State.java delete mode 100644 commercial-paper/organization/digibank/application/.eslintrc.js delete mode 100644 commercial-paper/organization/digibank/application/.gitignore delete mode 100644 commercial-paper/organization/digibank/application/addToWallet.js delete mode 100644 commercial-paper/organization/digibank/application/buy.js delete mode 100644 commercial-paper/organization/digibank/application/buy_request.js delete mode 100644 commercial-paper/organization/digibank/application/enrollUser.js delete mode 100644 commercial-paper/organization/digibank/application/package.json delete mode 100644 commercial-paper/organization/digibank/application/queryapp.js delete mode 100644 commercial-paper/organization/digibank/application/redeem.js delete mode 100644 commercial-paper/organization/digibank/configuration/cli/docker-compose.yml delete mode 100755 commercial-paper/organization/digibank/configuration/cli/monitordocker.sh delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/paper.go delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/paper_test.go delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/papercontext.go delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/papercontext_test.go delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/papercontract.go delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/papercontract_test.go delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/paperlist.go delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/paperlist_test.go delete mode 100644 commercial-paper/organization/digibank/contract-go/go.mod delete mode 100644 commercial-paper/organization/digibank/contract-go/go.sum delete mode 100644 commercial-paper/organization/digibank/contract-go/ledger-api/state.go delete mode 100644 commercial-paper/organization/digibank/contract-go/ledger-api/statelist.go delete mode 100644 commercial-paper/organization/digibank/contract-go/main.go delete mode 100644 commercial-paper/organization/digibank/contract-java/.gitignore delete mode 100644 commercial-paper/organization/digibank/contract-java/build.gradle delete mode 100644 commercial-paper/organization/digibank/contract-java/gradle/wrapper/gradle-wrapper.jar delete mode 100644 commercial-paper/organization/digibank/contract-java/gradle/wrapper/gradle-wrapper.properties delete mode 100755 commercial-paper/organization/digibank/contract-java/gradlew delete mode 100644 commercial-paper/organization/digibank/contract-java/gradlew.bat delete mode 100644 commercial-paper/organization/digibank/contract-java/settings.gradle delete mode 100644 commercial-paper/organization/digibank/contract-java/shadow-build.gradle delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaper.java delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContext.java delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContract.java delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/PaperList.java delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/State.java delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/StateDeserializer.java delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/StateList.java delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/impl/StateListImpl.java delete mode 100755 commercial-paper/organization/digibank/contract/.editorconfig delete mode 100644 commercial-paper/organization/digibank/contract/.eslintignore delete mode 100644 commercial-paper/organization/digibank/contract/.eslintrc.js delete mode 100644 commercial-paper/organization/digibank/contract/.npmignore delete mode 100644 commercial-paper/organization/digibank/contract/index.js delete mode 100644 commercial-paper/organization/digibank/contract/ledger-api/state.js delete mode 100644 commercial-paper/organization/digibank/contract/ledger-api/statelist.js delete mode 100644 commercial-paper/organization/digibank/contract/lib/paper.js delete mode 100644 commercial-paper/organization/digibank/contract/lib/papercontract.js delete mode 100644 commercial-paper/organization/digibank/contract/lib/paperlist.js delete mode 100644 commercial-paper/organization/digibank/contract/lib/queries.js delete mode 100644 commercial-paper/organization/digibank/contract/package.json delete mode 100644 commercial-paper/organization/digibank/contract/test/contract.js delete mode 100755 commercial-paper/organization/digibank/digibank.sh delete mode 100644 commercial-paper/organization/digibank/gateway/.gitkeep delete mode 100644 commercial-paper/organization/magnetocorp/.gitignore delete mode 100644 commercial-paper/organization/magnetocorp/application-java/.gitignore delete mode 100644 commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.core.resources.prefs delete mode 100644 commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.m2e.core.prefs delete mode 100644 commercial-paper/organization/magnetocorp/application-java/pom.xml delete mode 100644 commercial-paper/organization/magnetocorp/application-java/src/org/magnetocorp/AddToWallet.java delete mode 100644 commercial-paper/organization/magnetocorp/application-java/src/org/magnetocorp/Issue.java delete mode 100644 commercial-paper/organization/magnetocorp/application-java/src/org/papernet/CommercialPaper.java delete mode 100644 commercial-paper/organization/magnetocorp/application-java/src/org/papernet/ledgerapi/State.java delete mode 100644 commercial-paper/organization/magnetocorp/application/.eslintrc.js delete mode 100644 commercial-paper/organization/magnetocorp/application/.gitignore delete mode 100644 commercial-paper/organization/magnetocorp/application/addToWallet.js delete mode 100644 commercial-paper/organization/magnetocorp/application/cpListener.js delete mode 100644 commercial-paper/organization/magnetocorp/application/enrollUser.js delete mode 100644 commercial-paper/organization/magnetocorp/application/issue.js delete mode 100644 commercial-paper/organization/magnetocorp/application/package.json delete mode 100644 commercial-paper/organization/magnetocorp/application/transfer.js delete mode 100644 commercial-paper/organization/magnetocorp/configuration/cli/docker-compose.yml delete mode 100755 commercial-paper/organization/magnetocorp/configuration/cli/monitordocker.sh delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paper.go delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paper_test.go delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontext.go delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontext_test.go delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontract.go delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontract_test.go delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paperlist.go delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paperlist_test.go delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/go.mod delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/go.sum delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/ledger-api/state.go delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/ledger-api/statelist.go delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/main.go delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/build.gradle delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/gradle/wrapper/gradle-wrapper.jar delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/gradle/wrapper/gradle-wrapper.properties delete mode 100755 commercial-paper/organization/magnetocorp/contract-java/gradlew delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/gradlew.bat delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/settings.gradle delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaper.java delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContext.java delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContract.java delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/PaperList.java delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/State.java delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/StateDeserializer.java delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/StateList.java delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/impl/StateListImpl.java delete mode 100755 commercial-paper/organization/magnetocorp/contract/.editorconfig delete mode 100644 commercial-paper/organization/magnetocorp/contract/.eslintignore delete mode 100644 commercial-paper/organization/magnetocorp/contract/.eslintrc.js delete mode 100644 commercial-paper/organization/magnetocorp/contract/.npmignore delete mode 100644 commercial-paper/organization/magnetocorp/contract/index.js delete mode 100644 commercial-paper/organization/magnetocorp/contract/ledger-api/state.js delete mode 100644 commercial-paper/organization/magnetocorp/contract/ledger-api/statelist.js delete mode 100644 commercial-paper/organization/magnetocorp/contract/lib/paper.js delete mode 100644 commercial-paper/organization/magnetocorp/contract/lib/papercontract.js delete mode 100644 commercial-paper/organization/magnetocorp/contract/lib/paperlist.js delete mode 100644 commercial-paper/organization/magnetocorp/contract/lib/queries.js delete mode 100644 commercial-paper/organization/magnetocorp/contract/package.json delete mode 100644 commercial-paper/organization/magnetocorp/contract/test/contract.js delete mode 100644 commercial-paper/organization/magnetocorp/gateway/.gitkeep delete mode 100755 commercial-paper/organization/magnetocorp/magnetocorp.sh delete mode 100644 commercial-paper/organization/magnetocorp/t.js diff --git a/commercial-paper/.gitignore b/commercial-paper/.gitignore deleted file mode 100644 index 65971ce8..00000000 --- a/commercial-paper/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -cp.tar.gz -**/.gradle -**/gateway/connection-org1.yaml -**/gateway/connection-org2.yaml diff --git a/commercial-paper/README.md b/commercial-paper/README.md deleted file mode 100644 index b3e513ca..00000000 --- a/commercial-paper/README.md +++ /dev/null @@ -1,646 +0,0 @@ - - -# Commercial Paper Tutorial & Samples - -## Introduction - -This folder contains a structured set of smart contracts and application clients (ie. in a choice of languages, eg Node.js, Java, Go etc) relating to *Commercial Paper*, a finance 'instrument' (in Global Finance). At present, the Node.js sample contract in particular has further added functionality: an optional two-step authority check (see diagram below), when redeeming a commercial paper instance - and a range of sample ledger queries, to help consolidate your learning; both can be explored using the Node.js application client. - -While a more detailed 'explainer' of the Commercial Paper scenario (including use case analysis, code walkthrough & practices, logical/physical representation of ledger data etc) can be found in the [Hyperledger Fabric Commercial Paper Tutorial](https://hyperledger-fabric.readthedocs.io/en/latest/tutorial/commercial_paper.html), you don't have to read through this, just to try out this sample. There's also a [Wikipedia page](https://en.wikipedia.org/wiki/Commercial_paper) - -
Key Objectives - - * see a Commercial Paper use case in action - - * explore the key 'takeaways': understand differences between asset _state_ changes ('e.g. 'lifecycle') and transaction _inputs_* (e.g. 'inputs' during lifecycle) - - * try out a number of different query types: asset history, asset state, ownership, partial key, named query (criteria-based), ad-hoc queries (you supply a query string) - presently available in the Node.js sample only. - - \* the smart contract uses these (along with business logic) to decide outcomes; some inputs change the asset _state_ (like 'ownership') ; some don't. - -

-
- -
Blockchain: benefits to Commercial Paper marketplaces? - - * replace long-winded, time consuming processing between multiple organisations - the network makes it one centralized hub and helps simplify workflow. - - * full transparency, traceability and ownership of issued papers - - * speed up a process that can take days - e. make same-day issuance a reality, or even a market paradigm. - - * in asset-backed commercial paper markets, blockchain can help increase accessibility (to a marketplace) to SMEs to partake in issuance, where otherwise it was inaccessible. - - * integration to other areas, like supply chain finance - -

-
- - - Expand the twisty below to see an overview diagram of a 'sample' Commercial paper marketplace - transactions, queries being executed by different organisations (we'll focus on two of these organisations) - -
PaperNet Overview diagram - The sample commercial paper marketplace - -![PaperNet Overview](img/overview.png) - -

-
- -But first, it might useful to explain Commercial Paper, an unsecured promissory note issued to obtain capital, and operates in global financial markets. A Commercial Paper instance is represented as an asset with a lifecycle, recorded on the blockchain - transactions change its _state_ (over time) and those transactions, naturally - have _inputs_. - - -#### Explainers - -
Commercial Paper - what is it briefly? - -
-It is a type of unsecured promissory note, issued by established companies (eg big manufacturers, blue chip corporations) to gain short-term capital - usually no more than 6-9 months. Why? To meet short-term financial obligations. Commercial paper is generally purchased by money market funds and banks - in fact, it becomes a more important investment strategy during financial recessions :-) . A corporation issues a paper (in the form of a promissory note) for specific projects, such as big capital investments, to pay contractors or even to exercise debt restructuring. The tutorial describes MagnetoCorp (car manufacturer) who have landed a huge contract, and will need approx. $5m in capital (payroll obligations), to hire 1000 car workers for at least 6 months (with no car revenues yet - its a financial strain). Underpinning this, of course, is that MagnetoCorp, has every confidence that (say, in 6 months time) it will be in a position to pay out the face value ($5m in this case) when the commercial paper is redeemd by an owner of the paper, upon maturity :-). -

-
- -
Ins and Outs, Attractions of Commercial Paper Investment? - -
-Investors (who buy Commercial Paper) are attracted as they agree to buy them at a discount (say $4.94m) on the face value (eg $5m) and moreso, they obtain a higher yield than if they were simply gaining interest in a bank (eg. 2% interest on $4.95m today = $5m in 6 months time). But there is a 'premium' attached, with carrying the risk of a debt/loan that is essentially unsecured (unlike a bank) - which is where credit risk and ratings comes in. As a result, the actual yield from the investment chosen is in effect $10k greater (than pure interest, in the example given). -

-Once an issuing corporation becomes established in the commercial paper marketplace, it builds a high credit rating (risk affects how much of a premium investors seek and therefore discount accordingly) - in fact, it is often cheaper (for a blue chip company) to draw on a commercial paper than on a bank line of credit. But that rating reflects the issuer's ability to pay back on maturity. -

-I mentioned marketplace: even during the typical 6-9 month period, a commercial paper can be bought and sold multiple times (its quoted, at the discounted price on money markets), before the Commercial Paper reaches its maturity date. On that date, the current investor (or owner) 'redeems' the paper bond with MagnetoCorp, the issuer and gets the face value of $5m. - -
- -[_back to top_](#top) - -## Scenario Overview - -![](https://hyperledger-fabric.readthedocs.io/en/latest/_images/commercial_paper.diagram.1.png) - -In this tutorial two organizations, MagnetoCorp and DigiBank, trade commercial paper with each other on 'PaperNet', the marketplace represented by a Hyperledger Fabric blockchain network. Note that there are two alternative transaction flows - one which mirrors the [Commercial Paper Tutorial](https://hyperledger-fabric.readthedocs.io/en/latest/tutorial/commercial_paper.html) as described in Fabric documentation, and one which requires the authorised owner of the paper to complete a transfer following a request to buy the commercial paper - the latter example features an authorization check in the smart contract that ensures the transactor is from the organization that currently owns the commercial paper - they approve and complete the buy request. These are the commercial paper transaction lifecycles you can try out: - -![Transaction Flow alternatives](img/transaction-flow.png) - -The tutorial exercises the commercial paper asset lifecycle: _issue_, _buy_ ( 1 to _n_ ) (or _buy_request_ / _transfer_ alternative), and _redeem_ transactions: the key 'takeaways' from the scenario are: - -- understanding the _changes in state_ in the commercial paper asset (reflected in the ledger world state) which reaches maturity after 6 months. -- understanding the _transaction inputs_ for each transaction (some inputs change the asset _state_ - eg. ownership) and some _don't_ (e.g. purchase price) and not part of the asset - but importantly, the _inputs_ for a given transaction are recorded on the blockchain). -- understanding the importance of _queries_ such as: asset history, rich queries (criteria matching etc), transaction history (where the inputs are recorded) - -Client applications (CLI based) are used: - -- to perform the transactions -- run queries (Node.js sample only) -- examine the transaction inputs (as opposed to _states_) that are written to the ledger after you perform a transaction (using the Node.js listener). - -This sample uses the `test-network` . You’ll act as Isabella, an employee of MagnetoCorp (Org2), who will issue a commercial paper on its behalf. You’ll then 'switch hats' to take the role of Balaji, an employee of DigiBank (Org1), who will buy this commercial paper, hold it for a period of time, and then redeem it with MagnetoCorp for a small profit or yield. Note that the smart contract sample doesn't enforce the actual hold period ; the user can, in fact, redeem the paper immediately. - - -## Quick Start - -Below are the quick start instructions for running the tutorial. As mentioned, if you're interested in a 'deeper dive' analysis and importance of the concepts, design, structure and implementation of the smart contract, they can be found in the [Hyperledger Fabric Commercial Paper Tutorial](https://hyperledger-fabric.readthedocs.io/en/latest/tutorial/commercial_paper.html). Suffice to say, you DON'T have to have read this, to do this tutorial. - -This `README.md` file is in the `commercial-paper` directory, the source code for client applications and the contracts is in the `organization` directory. - -### High-Level Overview of Steps - -1) Install Binaries, Start the Hyperledger Fabric infrastructure - - The Fabric 'test-network' will be used - this has two organizations 'Org1' and 'Org2' DigiBank will be Org1, and MagnetoCorp will be Org2. - -2) Install and Instantiate the Contracts - -3) Run client applications in the roles of MagnetoCorp and DigiBank to trade the commercial paper - - - Issue the Paper as Magnetocorp (org2) - - Buy the paper as DigiBank (org1) - - Redeem the paper as DigiBank (org1) - - See also the transaction flow and alternatives in the Scenario Overview below. - -[_back to top_](#top) - -## Setup - -You will need a machine with the following - -- Docker and docker-compose installed -- Node.js v12 if you want to run JavaScript client applications -- Java v8 if you want to run Java client applications -- Maven to build the Java applications - -You will need to install the `peer` cli binaries and cloned the `fabric-samples` repository. For more information see -[Install the Samples, Binaries and Docker Images](https://hyperledger-fabric.readthedocs.io/en/latest/install.html) in the Hyperledger Fabric documentation. Once you have installed the cli binaries, ensure you have added the `bin` directory (for your `peer` commands used by scripts below) to your exported `PATH` variable in your `.bashrc` or `.profile` directory (per below). This is important as you will be opening a number of windows which will need PATH set. Finally, check that it finds the `peer` command in your PATH using the `which` command eg. - -``` -export PATH=:$PATH -which peer -``` - - -It is advised to have 3 terminal windows (consoles) open; - -* one to monitor the infrastructure -* one for MagnetoCorp -* one for DigiBank. - -Once you've cloned the `fabric-samples` - change to the `commercial-paper` directory in each window. - -``` -git clone https://github.com/hyperledger/fabric-samples.git -``` - -``` -cd fabric-samples/commercial-paper -``` - -## Running the Infrastructure - -In one console window, run the network starter script - this will start the two organization `test-network` blockchain network. - -``` -./network-starter.sh -``` - -You can re-use this console window if you wish, but it is recommended to run a docker container monitoring script in its own window. This will let you view what Fabric is doing and help diagnose any failures. - -```bash -./organization/magnetocorp/configuration/cli/monitordocker.sh fabric_test -``` - -### Setup the Organizations' environments - -The contract code is available as either JavaScript, Java or Go. You can use either one, and the choice of contract language does not affect the choice of client language. With the v2.0 Fabric chaincode lifecycle, this requires operations for both MagnetoCorp and Digibank admin. Open two windows in the fabric-samples/commercial paper directory, one for each organization. - -In your 'MagnetoCorp' window run the following commands, to set the shell environment variables needed to act as that organization. The leading '.' in the command sequence sets in your current environment - if you do not run this, you will not be able to package the chaincode. - -``` -cd fabric-samples/commercial-paper/organization/magnetocorp -. ./magnetocorp.sh -``` - -You can either copy and paste them directly into the terminal, or invoke directly in your own command shell. For example if you are using bash or zsh on Linux you can use this command. - -``` -source <(./magnetocorp.sh) -``` - -Similarly in your 'DigiBank' window run the following commands as shown: - -``` -cd fabric-samples/commercial-paper/organization/digibank -. ./digibank.sh -``` - -[_back to top_](#top) - - -### Deploy the smart contract to the channel - -You need to perform similar operations for _both_ organizations and for your language choice from the instructions below. For the different contract languages, the steps are very similar - the full set of steps are actually shown in the JavaScript section (see twisty). However, you will perform one or two different initial steps for Java or Go before completing the remaining common steps as instructed in those language sections. - -Note that the commands below make use of the `jq` utility for parsing output - download and install it from [the jq download page](https://stedolan.github.io/jq/download/). - - -**
For a JavaScript Contract** - - -Running in MagnetoCorp directory: - -``` -# MAGNETOCORP - -peer lifecycle chaincode package cp.tar.gz --lang node --path ./contract --label cp_0 -peer lifecycle chaincode install cp.tar.gz - -export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id') -echo $PACKAGE_ID # FYI may look like this: 'cp_0:nnnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -``` - -``` - -peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name papercontract \ - -v 0 \ - --package-id $PACKAGE_ID \ - --sequence 1 \ - --tls \ - --cafile "$ORDERER_CA" - -peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1 -``` - -Running in Digibank directory: - -``` - -# DIGIBANK - -peer lifecycle chaincode package cp.tar.gz --lang node --path ./contract --label cp_0 -peer lifecycle chaincode install cp.tar.gz - -export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id') -echo $PACKAGE_ID - -peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name papercontract \ - -v 0 \ - --package-id $PACKAGE_ID \ - --sequence 1 \ - --tls \ - --cafile "$ORDERER_CA" - -peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1 - -``` - -Once both organizations have installed, and approved the chaincode, it can be committed. - -``` -# MAGNETOCORP - -peer lifecycle chaincode commit -o localhost:7050 \ - --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \ - --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \ - --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel --name papercontract -v 0 \ - --sequence 1 \ - --tls --cafile "$ORDERER_CA" --waitForEvent - -``` - -To test, try sending some simple transactions. - -``` - -peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \ - --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \ - --channelID mychannel --name papercontract \ - -c '{"Args":["org.papernet.commercialpaper:instantiate"]}' ${PEER_ADDRESS_ORG1} ${PEER_ADDRESS_ORG2} \ - --tls --cafile "$ORDERER_CA" --waitForEvent - -peer chaincode query -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name papercontract \ - -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' \ - --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \ - --tls --cafile "$ORDERER_CA" | jq '.' -C | more -``` -

-
- - -**
For a Java Contract:** - - -Before the `peer lifecycle chaincode package` command below, you will first need to change into each organization's `contract-java` directory and issue - -``` -./gradlew build -``` - -Then complete the steps below. - - -Running in MagnetoCorp contract directory: - -``` -# MAGNETOCORP - -peer lifecycle chaincode package cp.tar.gz --lang java --path ./contract-java --label cp_0 -peer lifecycle chaincode install cp.tar.gz - -export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id') -echo $PACKAGE_ID # FYI may look like this: 'cp_0:nnnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -``` - -``` - -peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name papercontract \ - -v 0 \ - --package-id $PACKAGE_ID \ - --sequence 1 \ - --tls \ - --cafile "$ORDERER_CA" - -peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1 -``` - -Running in Digibank - -``` - -# DIGIBANK - -peer lifecycle chaincode package cp.tar.gz --lang java --path ./contract-java --label cp_0 -peer lifecycle chaincode install cp.tar.gz - -export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id') -echo $PACKAGE_ID - -peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name papercontract \ - -v 0 \ - --package-id $PACKAGE_ID \ - --sequence 1 \ - --tls \ - --cafile "$ORDERER_CA" - -peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1 - -``` - -Once both organizations have installed, and approved the chaincode, it can be committed. - -``` -# MAGNETOCORP - -peer lifecycle chaincode commit -o localhost:7050 \ - --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \ - --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \ - --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel --name papercontract -v 0 \ - --sequence 1 \ - --tls --cafile "$ORDERER_CA" --waitForEvent - -``` - -To test, try sending some simple transactions. - -``` - -peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \ - --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \ - --channelID mychannel --name papercontract \ - -c '{"Args":["org.papernet.commercialpaper:instantiate"]}' ${PEER_ADDRESS_ORG1} ${PEER_ADDRESS_ORG2} \ - --tls --cafile "$ORDERER_CA" --waitForEvent - -peer chaincode query -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name papercontract \ - -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' \ - --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \ - --tls --cafile "$ORDERER_CA" | jq '.' -C | more -``` - -

-
- -**
For a Go Contract** - - -Before the `peer lifecycle chaincode package` command step, you will need to change into each organization's `contract-go` directory and issue - -``` -go mod vendor -``` - -Then complete the steps below. - - -Running in MagnetoCorp contract directory: - -``` -# MAGNETOCORP - -peer lifecycle chaincode package cp.tar.gz --lang golang --path ./contract-go --label cp_0 -peer lifecycle chaincode install cp.tar.gz - -export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id') -echo $PACKAGE_ID # FYI may look like this: 'cp_0:nnnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -``` - -``` - -peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name papercontract \ - -v 0 \ - --package-id $PACKAGE_ID \ - --sequence 1 \ - --tls \ - --cafile "$ORDERER_CA" - -peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1 -``` - -Running in Digibank - -``` - -# DIGIBANK - -peer lifecycle chaincode package cp.tar.gz --lang golang --path ./contract-go --label cp_0 -peer lifecycle chaincode install cp.tar.gz - -export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id') -echo $PACKAGE_ID - -peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name papercontract \ - -v 0 \ - --package-id $PACKAGE_ID \ - --sequence 1 \ - --tls \ - --cafile "$ORDERER_CA" - -peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1 - -``` - -Once both organizations have installed, and approved the chaincode, it can be committed. - -``` -# MAGNETOCORP - -peer lifecycle chaincode commit -o localhost:7050 \ - --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \ - --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \ - --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel --name papercontract -v 0 \ - --sequence 1 \ - --tls --cafile "$ORDERER_CA" --waitForEvent - -``` - -To test, try sending some simple transactions. - -``` - -peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \ - --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \ - --channelID mychannel --name papercontract \ - -c '{"Args":["org.papernet.commercialpaper:instantiate"]}' ${PEER_ADDRESS_ORG1} ${PEER_ADDRESS_ORG2} \ - --tls --cafile "$ORDERER_CA" --waitForEvent - -peer chaincode query -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name papercontract \ - -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' \ - --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \ - --tls --cafile "$ORDERER_CA" | jq '.' -C | more -``` - - - -

-
- - -[_back to top_](#top) - - -## Client Applications - -Note for Java applications, you will need to compile the Java Code using `maven`. Use this command in each application-java directory - -``` -mvn clean package -``` - -Note for JavaScript applications, you will need to install the dependencies first. Use this command in each application directory - -``` -npm install -``` -> Note that there is NO dependency between the language of any one client application and any contract. Mix and match as you wish! - -The docker containers don't contain the node or Java runtimes; so it is best to exit the docker containers - but keep the windows open and run the applications locally. - -As mentioned earlier in the Sample introduction section, transaction _inputs_ are recorded on the ledger, as well as any asset _state_ changes. Just *before* you run the _issue_ application script below - you need to launch a block 'listener' application that will show you these _inputs_, as you complete each transaction in the commercial paper lifecycle (eg. Paper Number: 00001, 00002 etc) . - -For the listener, its best to open a *new* terminal for this in the `commercial-paper/organization/magnetocorp/application` directory (javascript). Next, run the `addToWallet` step in the `issue` transaction below, to add Isabella's identity to the wallet - the listener will use this wallet. Once the listener is launched, it will show the inputs for transactions you will perform and which are committed to blocks (ie part of the ledger). Note: initially, the listener may show a spurious message, and then go into a _listening_ or 'wait' state. As transactions complete below, messages will be displayed by the listener - so keep an eye out. *After* adding Isabella's wallet, you can then launch the listener as follows: - -``` -node cpListener.js -``` - -**
Issue the commercial paper** - -The paper is issued by *MagnetoCorp* - -You can now run the applications to issue the commercial paper. Change to either the -`commercial-paper/organization/magnetocorp/application` directory (javascript) or `commercial-paper/organization/magnetocorp/application-java` directory (java) - -*Add the Identity to be used to the wallet* - -``` -node addToWallet.js -# or -java -cp target/commercial-paper-0.0.1-SNAPSHOT.jar org.magnetocorp.AddToWallet -``` - -*Issue the Commercial Paper* - -``` -node issue.js -# or -java -cp target/commercial-paper-0.0.1-SNAPSHOT.jar org.magnetocorp.Issue -``` - -Don't forget to check the application listener for messages above! - -

-
- - -**
Buy the commercial paper** - -_Buy_ is performed as *Digibank*; - -You can now run the applications to buy the paper. Change to either the -`commercial-paper/organization/digibank/application` directory or `commercial-paper/organization/digibank/application-java` - -*Add the Identity to be used* - -``` -node addToWallet.js -# or -java -cp target/commercial-paper-0.0.1-SNAPSHOT.jar org.digibank.AddToWallet -``` - -*Buy the paper* - -``` -node buy.js -# or -java -cp target/commercial-paper-0.0.1-SNAPSHOT.jar org.digibank.Buy -``` - -If you have just executed a `buy` transaction above - jump to the `redeem` transaction below - otherwise execute the _buy_/_transfer_ sequence as described earlier. - -*Alternative: Request to Buy the paper (buy/transfer)* - -``` -node buy_request.js -``` - -Now complete the _request_ by switching to the `MagnetoCorp` application directory (javascript) and execute a `transfer` transaction as MagnetoCorp: - -``` -cd ../../magnetocorp/application - -node transfer.js -``` - -

-
- -**
Redeem the commercial paper** - -_Redeem_ is performed as *Digibank* - the current owner (buyer) in the lifecycle. - -You can now run the applications to redeem the paper. Change to either the -`commercial-paper/organization/digibank/application` directory or `commercial-paper/organization/digibank/application-java` - - -*Redeem* - -``` -node redeem.js -# or -java -cp target/commercial-paper-0.0.1-SNAPSHOT.jar org.digibank.Redeem -``` - -

-
- - -**
Perform Queries: Ownership, Asset History etc (Node.js sample only) ** - - Having completed the full commercial paper lifecycle for one paper (paper number: 00001) some queries below won't show a lot of data - as an optional exercise, you can change the scripts above (paper number: 00002) to create another paper lifecycle and run the `queryapp` application below (change query 1 to the new CP number FYI), with more data available. As indicated, the query transactions mentioned are presently only available in the Node.js sample. - - Execute the Node.js application client script, which will run the following 5 queries, in order: - - - History of Commercial Paper (Note: the paper state is shown more descriptively eg. 'ISSUED', 'TRADING' and based on currentState values on ledger) - - Ownership of Commercial Papers - - Partial Key query, for Commercial papers in org.papernet.papers namespace belonging to MagnetoCorp - - Named Query: all redeemed papers in a state of 'redeemed' (currentState = 4) - - Named Query: all commercial papers with a face value > $4m - - From the `digibank/application` subdirectory run: - - ``` - node queryapp.js - ``` - -

-
- -When you're done with this section, return to the terminal where your Node.js _listener_ application is running, and terminate the process. - -## Clean up -When you are finished using the Fabric test network and the commercial paper smart contract and applications, you can use the following command to clean up the network: - -``` -./network-clean.sh -``` - -[_back to top_](#top) diff --git a/commercial-paper/img/overview.png b/commercial-paper/img/overview.png deleted file mode 100644 index 9da7aced3a6f91968535c95aa52433bff87881cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122143 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%0AM-pdkFTW=ixLJa?v{5dpI0M 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≪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 diff --git a/commercial-paper/network-clean.sh b/commercial-paper/network-clean.sh deleted file mode 100755 index 5fe6c087..00000000 --- a/commercial-paper/network-clean.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: Apache-2.0 - -function _exit(){ - printf "Exiting:%s\n" "$1" - exit -1 -} - -# Exit on first error, print all commands. -set -ev -set -o pipefail - -# Where am I? -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -export FABRIC_CFG_PATH="${DIR}/../config" - -cd "${DIR}/../test-network/" - -docker kill cliDigiBank cliMagnetoCorp logspout || true -./network.sh down - -# remove any stopped containers -docker rm $(docker ps -aq) - diff --git a/commercial-paper/network-starter.sh b/commercial-paper/network-starter.sh deleted file mode 100755 index fd70be90..00000000 --- a/commercial-paper/network-starter.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: Apache-2.0 - -function _exit(){ - printf "Exiting:%s\n" "$1" - exit -1 -} - -# Exit on first error, print all commands. -set -ev -set -o pipefail - -# Where am I? -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -export FABRIC_CFG_PATH="${DIR}/../config" - -cd "${DIR}/../test-network/" - -docker kill cliDigiBank cliMagnetoCorp logspout || true -./network.sh down -./network.sh up createChannel -ca -s couchdb - -# Copy the connection profiles so they are in the correct organizations. -cp "${DIR}/../test-network/organizations/peerOrganizations/org1.example.com/connection-org1.yaml" "${DIR}/organization/digibank/gateway/" -cp "${DIR}/../test-network/organizations/peerOrganizations/org2.example.com/connection-org2.yaml" "${DIR}/organization/magnetocorp/gateway/" - -cp "${DIR}/../test-network/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/"* "${DIR}/../test-network/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/User1@org1.example.com-cert.pem" -cp "${DIR}/../test-network/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/"* "${DIR}/../test-network/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/priv_sk" - -cp "${DIR}/../test-network/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/signcerts/"* "${DIR}/../test-network/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/signcerts/User1@org2.example.com-cert.pem" -cp "${DIR}/../test-network/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/keystore/"* "${DIR}/../test-network/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/keystore/priv_sk" - -echo Suggest that you monitor the docker containers by running -echo "./organization/magnetocorp/configuration/cli/monitordocker.sh fabric_test" diff --git a/commercial-paper/organization/digibank/.gitignore b/commercial-paper/organization/digibank/.gitignore deleted file mode 100644 index 7d139014..00000000 --- a/commercial-paper/organization/digibank/.gitignore +++ /dev/null @@ -1 +0,0 @@ -identity \ No newline at end of file diff --git a/commercial-paper/organization/digibank/application-java/.gitignore b/commercial-paper/organization/digibank/application-java/.gitignore deleted file mode 100644 index 2f7896d1..00000000 --- a/commercial-paper/organization/digibank/application-java/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target/ diff --git a/commercial-paper/organization/digibank/application-java/.settings/org.eclipse.jdt.core.prefs b/commercial-paper/organization/digibank/application-java/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index b8947ec6..00000000 --- a/commercial-paper/organization/digibank/application-java/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,6 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/commercial-paper/organization/digibank/application-java/.settings/org.eclipse.m2e.core.prefs b/commercial-paper/organization/digibank/application-java/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f1..00000000 --- a/commercial-paper/organization/digibank/application-java/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/commercial-paper/organization/digibank/application-java/pom.xml b/commercial-paper/organization/digibank/application-java/pom.xml deleted file mode 100644 index 71cd8e10..00000000 --- a/commercial-paper/organization/digibank/application-java/pom.xml +++ /dev/null @@ -1,96 +0,0 @@ - - 4.0.0 - commercial-paper - commercial-paper - 0.0.1-SNAPSHOT - - - - - 1.8 - UTF-8 - UTF-8 - - - 2.1.0 - - 2.1.0 - - - - - src - - - maven-compiler-plugin - 3.8.0 - - 1.8 - 1.8 - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.0 - - - - package - - shade - - - - - false - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - - - - - - jitpack.io - https://jitpack.io - - - - - - org.hyperledger.fabric - fabric-gateway-java - ${fabric-gateway-java.version} - - - - - org.hyperledger.fabric-chaincode-java - fabric-chaincode-shim - ${fabric-chaincode-java.version} - compile - - - - - org.json - json - 20180813 - - - - diff --git a/commercial-paper/organization/digibank/application-java/src/org/digibank/AddToWallet.java b/commercial-paper/organization/digibank/application-java/src/org/digibank/AddToWallet.java deleted file mode 100644 index 6a3fa121..00000000 --- a/commercial-paper/organization/digibank/application-java/src/org/digibank/AddToWallet.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package org.digibank; - -import java.io.IOException; -import java.io.Reader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.InvalidKeyException; -import java.security.PrivateKey; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import org.hyperledger.fabric.gateway.Identities; -import org.hyperledger.fabric.gateway.Identity; -import org.hyperledger.fabric.gateway.Wallet; -import org.hyperledger.fabric.gateway.Wallets; - -public class AddToWallet { - - private static X509Certificate readX509Certificate(final Path certificatePath) throws IOException, CertificateException { - try (Reader certificateReader = Files.newBufferedReader(certificatePath, StandardCharsets.UTF_8)) { - return Identities.readX509Certificate(certificateReader); - } - } - - private static PrivateKey getPrivateKey(final Path privateKeyPath) throws IOException, InvalidKeyException { - try (Reader privateKeyReader = Files.newBufferedReader(privateKeyPath, StandardCharsets.UTF_8)) { - return Identities.readPrivateKey(privateKeyReader); - } - } - - public static void main(String[] args) { - try { - // A wallet stores a collection of identities - Path walletPath = Paths.get(".", "wallet"); - Wallet wallet = Wallets.newFileSystemWallet(walletPath); - - Path credentialPath = Paths.get("..", "..", "..",".." ,"test-network", "organizations", - "peerOrganizations", "org1.example.com", "users", "User1@org1.example.com", "msp"); - System.out.println("credentialPath: " + credentialPath.toString()); - Path certificatePath = credentialPath.resolve(Paths.get("signcerts", - "User1@org1.example.com-cert.pem")); - System.out.println("certificatePem: " + certificatePath.toString()); - Path privateKeyPath = credentialPath.resolve(Paths.get("keystore", - "priv_sk")); - - X509Certificate certificate = readX509Certificate(certificatePath); - PrivateKey privateKey = getPrivateKey(privateKeyPath); - - Identity identity = Identities.newX509Identity("Org1MSP", certificate, privateKey); - - - String identityLabel = "User1@org1.example.com"; - wallet.put(identityLabel, identity); - - System.out.println("Write wallet info into " + walletPath.toString() + " successfully."); - - } catch (IOException | CertificateException | InvalidKeyException e) { - System.err.println("Error adding to wallet"); - e.printStackTrace(); - } - } - -} diff --git a/commercial-paper/organization/digibank/application-java/src/org/digibank/Buy.java b/commercial-paper/organization/digibank/application-java/src/org/digibank/Buy.java deleted file mode 100644 index 5e09bbd1..00000000 --- a/commercial-paper/organization/digibank/application-java/src/org/digibank/Buy.java +++ /dev/null @@ -1,74 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package org.digibank; - -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Map; -import java.util.concurrent.TimeoutException; - -import org.hyperledger.fabric.gateway.Contract; -import org.hyperledger.fabric.gateway.Gateway; -import org.hyperledger.fabric.gateway.GatewayException; -import org.hyperledger.fabric.gateway.Network; -import org.hyperledger.fabric.gateway.Wallet; -import org.hyperledger.fabric.gateway.Wallets; -import org.papernet.CommercialPaper; - -public class Buy { - - private static final String ENVKEY="CONTRACT_NAME"; - - public static void main(String[] args) { - Gateway.Builder builder = Gateway.createBuilder(); - - String contractName="papercontract"; - // get the name of the contract, in case it is overridden - Map envvar = System.getenv(); - if (envvar.containsKey(ENVKEY)){ - contractName=envvar.get(ENVKEY); - } - - try { - // A wallet stores a collection of identities - Path walletPath = Paths.get(".", "wallet"); - Wallet wallet = Wallets.newFileSystemWallet(walletPath); - System.out.println("Read wallet info from: " + walletPath); - - String userName = "User1@org1.example.com"; - - Path connectionProfile = Paths.get("..", "gateway", "connection-org1.yaml"); - - // Set connection options on the gateway builder - builder.identity(wallet, userName).networkConfig(connectionProfile).discovery(false); - - // Connect to gateway using application specified parameters - try(Gateway gateway = builder.connect()) { - - // Access PaperNet network - System.out.println("Use network channel: mychannel."); - Network network = gateway.getNetwork("mychannel"); - - // Get addressability to commercial paper contract - System.out.println("Use org.papernet.commercialpaper smart contract."); - Contract contract = network.getContract(contractName, "org.papernet.commercialpaper"); - - // Buy commercial paper - System.out.println("Submit commercial paper buy transaction."); - byte[] response = contract.submitTransaction("buy", "MagnetoCorp", "00001", "MagnetoCorp", "DigiBank", "4900000", "2020-05-31"); - - // Process response - System.out.println("Process buy transaction response."); - CommercialPaper paper = CommercialPaper.deserialize(response); - System.out.println(paper); - } - } catch (GatewayException | IOException | TimeoutException | InterruptedException e) { - e.printStackTrace(); - System.exit(-1); - } - } - -} diff --git a/commercial-paper/organization/digibank/application-java/src/org/digibank/Redeem.java b/commercial-paper/organization/digibank/application-java/src/org/digibank/Redeem.java deleted file mode 100644 index 62eb9d9e..00000000 --- a/commercial-paper/organization/digibank/application-java/src/org/digibank/Redeem.java +++ /dev/null @@ -1,73 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package org.digibank; - -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Map; -import java.util.concurrent.TimeoutException; - -import org.hyperledger.fabric.gateway.Contract; -import org.hyperledger.fabric.gateway.Gateway; -import org.hyperledger.fabric.gateway.GatewayException; -import org.hyperledger.fabric.gateway.Network; -import org.hyperledger.fabric.gateway.Wallet; -import org.hyperledger.fabric.gateway.Wallets; -import org.papernet.CommercialPaper; - -public class Redeem { - - private static final String ENVKEY="CONTRACT_NAME"; - - public static void main(String[] args) { - Gateway.Builder builder = Gateway.createBuilder(); - - String contractName="papercontract"; - // get the name of the contract, in case it is overridden - Map envvar = System.getenv(); - if (envvar.containsKey(ENVKEY)){ - contractName=envvar.get(ENVKEY); - } - - try { - // A wallet stores a collection of identities - Path walletPath = Paths.get(".", "wallet"); - Wallet wallet = Wallets.newFileSystemWallet(walletPath); - - String userName = "User1@org1.example.com"; - - Path connectionProfile = Paths.get("..", "gateway", "connection-org1.yaml"); - - // Set connection options on the gateway builder - builder.identity(wallet, userName).networkConfig(connectionProfile).discovery(false); - - // Connect to gateway using application specified parameters - try(Gateway gateway = builder.connect()) { - - // Access PaperNet network - System.out.println("Use network channel: mychannel."); - Network network = gateway.getNetwork("mychannel"); - - // Get addressability to commercial paper contract - System.out.println("Use org.papernet.commercialpaper smart contract."); - Contract contract = network.getContract("papercontract", "org.papernet.commercialpaper"); - - // Redeem commercial paper - System.out.println("Submit commercial paper redeem transaction."); - byte[] response = contract.submitTransaction("redeem", "MagnetoCorp", "00001", "DigiBank", "2020-11-30"); - - // Process response - System.out.println("Process redeem transaction response."); - CommercialPaper paper = CommercialPaper.deserialize(response); - System.out.println(paper); - } - } catch (GatewayException | IOException | TimeoutException | InterruptedException e) { - e.printStackTrace(); - System.exit(-1); - } - } - -} diff --git a/commercial-paper/organization/digibank/application-java/src/org/papernet/CommercialPaper.java b/commercial-paper/organization/digibank/application-java/src/org/papernet/CommercialPaper.java deleted file mode 100644 index 179d1bdf..00000000 --- a/commercial-paper/organization/digibank/application-java/src/org/papernet/CommercialPaper.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * SPDX-License-Identifier: - */ - -package org.papernet; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.papernet.ledgerapi.State; -import org.hyperledger.fabric.contract.annotation.DataType; -import org.hyperledger.fabric.contract.annotation.Property; -import org.json.JSONObject; -import org.json.JSONPropertyIgnore; - -@DataType() -public class CommercialPaper extends State { - // Enumerate commercial paper state values - public final static String ISSUED = "ISSUED"; - public final static String TRADING = "TRADING"; - public final static String REDEEMED = "REDEEMED"; - public final static String[] STATES = new String[] {ISSUED, TRADING, REDEEMED}; - - @Property() - private String state=""; - - public String getState() { - return state; - } - - public CommercialPaper setState(String state) { - this.state = state; - return this; - } - - @JSONPropertyIgnore() - public boolean isIssued() { - return this.state.equals(CommercialPaper.ISSUED); - } - - @JSONPropertyIgnore() - public boolean isTrading() { - return this.state.equals(CommercialPaper.TRADING); - } - - @JSONPropertyIgnore() - public boolean isRedeemed() { - return this.state.equals(CommercialPaper.REDEEMED); - } - - public CommercialPaper setIssued() { - this.state = CommercialPaper.ISSUED; - return this; - } - - public CommercialPaper setTrading() { - this.state = CommercialPaper.TRADING; - return this; - } - - public CommercialPaper setRedeemed() { - this.state = CommercialPaper.REDEEMED; - return this; - } - - @Property() - private String paperNumber; - - @Property() - private String issuer; - - @Property() - private String issueDateTime; - - @Property() - private int faceValue; - - @Property() - private String maturityDateTime; - - @Property() - private String owner; - - public String getOwner() { - return owner; - } - - public CommercialPaper setOwner(String owner) { - this.owner = owner; - return this; - } - - public CommercialPaper() { - super(); - } - - public CommercialPaper setKey() { - this.key = State.makeKey(new String[] { this.paperNumber }); - return this; - } - - public String getPaperNumber() { - return paperNumber; - } - - public CommercialPaper setPaperNumber(String paperNumber) { - this.paperNumber = paperNumber; - return this; - } - - public String getIssuer() { - return issuer; - } - - public CommercialPaper setIssuer(String issuer) { - this.issuer = issuer; - return this; - } - - public String getIssueDateTime() { - return issueDateTime; - } - - public CommercialPaper setIssueDateTime(String issueDateTime) { - this.issueDateTime = issueDateTime; - return this; - } - - public int getFaceValue() { - return faceValue; - } - - public CommercialPaper setFaceValue(int faceValue) { - this.faceValue = faceValue; - return this; - } - - public String getMaturityDateTime() { - return maturityDateTime; - } - - public CommercialPaper setMaturityDateTime(String maturityDateTime) { - this.maturityDateTime = maturityDateTime; - return this; - } - - @Override - public String toString() { - return "Paper::" + this.key + " " + this.getPaperNumber() + " " + getIssuer() + " " + getFaceValue(); - } - - /** - * Deserialize a state data to commercial paper - * - * @param {Buffer} data to form back into the object - */ - public static CommercialPaper deserialize(byte[] data) { - JSONObject json = new JSONObject(new String(data, UTF_8)); - - String issuer = json.getString("issuer"); - String paperNumber = json.getString("paperNumber"); - String issueDateTime = json.getString("issueDateTime"); - String maturityDateTime = json.getString("maturityDateTime"); - String owner = json.getString("owner"); - int faceValue = json.getInt("faceValue"); - int currentState = json.getInt("currentState"); - String state = STATES[currentState-1]; - return createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, faceValue, owner, state); - } - - public static byte[] serialize(CommercialPaper paper) { - return State.serialize(paper); - } - - /** - * Factory method to create a commercial paper object - */ - public static CommercialPaper createInstance(String issuer, String paperNumber, String issueDateTime, - String maturityDateTime, int faceValue, String owner, String state) { - return new CommercialPaper().setIssuer(issuer).setPaperNumber(paperNumber).setMaturityDateTime(maturityDateTime) - .setFaceValue(faceValue).setKey().setIssueDateTime(issueDateTime).setOwner(owner).setState(state); - } - -} diff --git a/commercial-paper/organization/digibank/application-java/src/org/papernet/ledgerapi/State.java b/commercial-paper/organization/digibank/application-java/src/org/papernet/ledgerapi/State.java deleted file mode 100644 index a32abc02..00000000 --- a/commercial-paper/organization/digibank/application-java/src/org/papernet/ledgerapi/State.java +++ /dev/null @@ -1,60 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ -package org.papernet.ledgerapi; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.json.JSONObject; - -/** - * State class. States have a class, unique key, and a lifecycle current state - * the current state is determined by the specific subclass - */ -public class State { - - protected String key; - - /** - * @param {String|Object} class An identifiable class of the instance - * @param {keyParts[]} elements to pull together to make a key for the objects - */ - public State() { - - } - - String getKey() { - return this.key; - } - - public String[] getSplitKey() { - return State.splitKey(this.key); - } - - /** - * Convert object to buffer containing JSON data serialization Typically used - * before putState()ledger API - * - * @param {Object} JSON object to serialize - * @return {buffer} buffer with the data to store - */ - public static byte[] serialize(Object object) { - String jsonStr = new JSONObject(object).toString(); - return jsonStr.getBytes(UTF_8); - } - - /** - * Join the keyParts to make a unififed string - * - * @param (String[]) keyParts - */ - public static String makeKey(String[] keyParts) { - return String.join(":", keyParts); - } - - public static String[] splitKey(String key) { - System.out.println("splitting key " + key + " " + java.util.Arrays.asList(key.split(":"))); - return key.split(":"); - } - -} diff --git a/commercial-paper/organization/digibank/application/.eslintrc.js b/commercial-paper/organization/digibank/application/.eslintrc.js deleted file mode 100644 index 22fbefc8..00000000 --- a/commercial-paper/organization/digibank/application/.eslintrc.js +++ /dev/null @@ -1,37 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -module.exports = { - env: { - node: true, - mocha: true - }, - parserOptions: { - ecmaVersion: 8, - sourceType: 'script' - }, - extends: "eslint:recommended", - rules: { - indent: ['error', 4], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], - 'no-unused-vars': ['error', { args: 'none' }], - 'no-console': 'off', - curly: 'error', - eqeqeq: 'error', - 'no-throw-literal': 'error', - strict: 'error', - 'no-var': 'error', - 'dot-notation': 'error', - 'no-tabs': 'error', - 'no-trailing-spaces': 'error', - 'no-use-before-define': 'error', - 'no-useless-call': 'error', - 'no-with': 'error', - 'operator-linebreak': 'error', - yoda: 'error', - 'quote-props': ['error', 'as-needed'] - } -}; \ No newline at end of file diff --git a/commercial-paper/organization/digibank/application/.gitignore b/commercial-paper/organization/digibank/application/.gitignore deleted file mode 100644 index b512c09d..00000000 --- a/commercial-paper/organization/digibank/application/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file diff --git a/commercial-paper/organization/digibank/application/addToWallet.js b/commercial-paper/organization/digibank/application/addToWallet.js deleted file mode 100644 index 9517e393..00000000 --- a/commercial-paper/organization/digibank/application/addToWallet.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -// Bring key classes into scope, most importantly Fabric SDK network class -const fs = require('fs'); -const { Wallets } = require('fabric-network'); -const path = require('path'); - -const fixtures = path.resolve(__dirname, '../../../../test-network'); - -async function main() { - - // Main try/catch block - try { - - // A wallet stores a collection of identities - const wallet = await Wallets.newFileSystemWallet('../identity/user/balaji/wallet'); - - // Identity to credentials to be stored in the wallet - const credPath = path.join(fixtures, '/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com'); - const certificate = fs.readFileSync(path.join(credPath, '/msp/signcerts/User1@org1.example.com-cert.pem')).toString(); - const privateKey = fs.readFileSync(path.join(credPath, '/msp/keystore/priv_sk')).toString(); - - // Load credentials into wallet - const identityLabel = 'balaji'; - - const identity = { - credentials: { - certificate, - privateKey - }, - mspId: 'Org1MSP', - type: 'X.509' - } - - await wallet.put(identityLabel, identity); - - } catch (error) { - console.log(`Error adding to wallet. ${error}`); - console.log(error.stack); - } -} - -main().then(() => { - console.log('done'); -}).catch((e) => { - console.log(e); - console.log(e.stack); - process.exit(-1); -}); diff --git a/commercial-paper/organization/digibank/application/buy.js b/commercial-paper/organization/digibank/application/buy.js deleted file mode 100644 index b052b75d..00000000 --- a/commercial-paper/organization/digibank/application/buy.js +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -/* - * This application has 6 basic steps: - * 1. Select an identity from a wallet - * 2. Connect to network gateway - * 3. Access PaperNet network - * 4. Construct request to buy commercial paper - * 5. Submit transaction - * 6. Process response - */ - -'use strict'; - -// Bring key classes into scope, most importantly Fabric SDK network class -const fs = require('fs'); -const yaml = require('js-yaml'); -const { Wallets, Gateway } = require('fabric-network'); -const CommercialPaper = require('../../magnetocorp/contract/lib/paper.js'); - - -// Main program function -async function main () { - - // A wallet stores a collection of identities for use - const wallet = await Wallets.newFileSystemWallet('../identity/user/balaji/wallet'); - - - // A gateway defines the peers used to access Fabric networks - const gateway = new Gateway(); - - // Main try/catch block - try { - - // Specify userName for network access - const userName = 'balaji'; - - // Load connection profile; will be used to locate a gateway - let connectionProfile = yaml.safeLoad(fs.readFileSync('../gateway/connection-org1.yaml', 'utf8')); - - // Set connection options; identity and wallet - let connectionOptions = { - identity: userName, - wallet: wallet, - discovery: { enabled: true, asLocalhost: true } - - }; - - // Connect to gateway using application specified parameters - console.log('Connect to Fabric gateway.'); - - await gateway.connect(connectionProfile, connectionOptions); - - // Access PaperNet network - console.log('Use network channel: mychannel.'); - - const network = await gateway.getNetwork('mychannel'); - - // Get addressability to commercial paper contract - console.log('Use org.papernet.commercialpaper smart contract.'); - - const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper'); - - // buy commercial paper - console.log('Submit commercial paper buy transaction.'); - - const buyResponse = await contract.submitTransaction('buy', 'MagnetoCorp', '00001', 'MagnetoCorp', 'DigiBank', '4900000', '2020-05-31'); - - // process response - console.log('Process buy transaction response.'); - - let paper = CommercialPaper.fromBuffer(buyResponse); - - console.log(`${paper.issuer} commercial paper : ${paper.paperNumber} successfully purchased by ${paper.owner}`); - console.log('Transaction complete.'); - - } catch (error) { - - console.log(`Error processing transaction. ${error}`); - console.log(error.stack); - - } finally { - - // Disconnect from the gateway - console.log('Disconnect from Fabric gateway.'); - gateway.disconnect(); - - } -} -main().then(() => { - - console.log('Buy program complete.'); - -}).catch((e) => { - - console.log('Buy program exception.'); - console.log(e); - console.log(e.stack); - process.exit(-1); - -}); diff --git a/commercial-paper/organization/digibank/application/buy_request.js b/commercial-paper/organization/digibank/application/buy_request.js deleted file mode 100644 index 1493b806..00000000 --- a/commercial-paper/organization/digibank/application/buy_request.js +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -/* - * This application has 6 basic steps: - * 1. Select an identity from a wallet - * 2. Connect to network gateway - * 3. Access PaperNet network - * 4. Construct request to buy (buy_request) commercial paper - * 5. Submit transaction - * 6. Process response - */ - -'use strict'; - -// Bring key classes into scope, most importantly Fabric SDK network class -const fs = require('fs'); -const yaml = require('js-yaml'); -const { Wallets, Gateway } = require('fabric-network'); -const CommercialPaper = require('../../magnetocorp/contract/lib/paper.js'); - - -// Main program function -async function main () { - - // A wallet stores a collection of identities for use - const wallet = await Wallets.newFileSystemWallet('../identity/user/balaji/wallet'); - - - // A gateway defines the peers used to access Fabric networks - const gateway = new Gateway(); - - // Main try/catch block - try { - - // Specify userName for network access - const userName = 'balaji'; - - // Load connection profile; will be used to locate a gateway - let connectionProfile = yaml.safeLoad(fs.readFileSync('../gateway/connection-org1.yaml', 'utf8')); - - // Set connection options; identity and wallet - let connectionOptions = { - identity: userName, - wallet: wallet, - discovery: { enabled: true, asLocalhost: true } - - }; - - // Connect to gateway using application specified parameters - console.log('Connect to Fabric gateway.'); - - await gateway.connect(connectionProfile, connectionOptions); - - // Access PaperNet network - console.log('Use network channel: mychannel.'); - - const network = await gateway.getNetwork('mychannel'); - - // Get addressability to commercial paper contract - console.log('Use org.papernet.commercialpaper smart contract.'); - - const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper'); - - // request to buy commercial paper using buy_request / transfer two-part transaction - console.log('Submit commercial paper buy_request transaction.'); - - const buyResponse = await contract.submitTransaction('buy_request', 'MagnetoCorp', '00001', 'MagnetoCorp', 'DigiBank', '4900000', '2020-05-31'); - - // process response - console.log('Process buy_request transaction response.'); - - let paper = CommercialPaper.fromBuffer(buyResponse); - - console.log(`${paper.issuer} commercial paper : ${paper.paperNumber} has been provisionally purchased : the transfer must now be completed by paper owner`); - console.log('Transaction complete.'); - - } catch (error) { - - console.log(`Error processing transaction. ${error}`); - console.log(error.stack); - - } finally { - - // Disconnect from the gateway - console.log('Disconnect from Fabric gateway.'); - gateway.disconnect(); - - } -} -main().then(() => { - - console.log('Buy_request program complete.'); - -}).catch((e) => { - - console.log('Buy_request program exception.'); - console.log(e); - console.log(e.stack); - process.exit(-1); - -}); diff --git a/commercial-paper/organization/digibank/application/enrollUser.js b/commercial-paper/organization/digibank/application/enrollUser.js deleted file mode 100644 index 2df5d6a4..00000000 --- a/commercial-paper/organization/digibank/application/enrollUser.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const FabricCAServices = require('fabric-ca-client'); -const { Wallets } = require('fabric-network'); -const fs = require('fs'); -const yaml = require('js-yaml'); -const path = require('path'); - -async function main() { - try { - // load the network configuration - let connectionProfile = yaml.safeLoad(fs.readFileSync('../gateway/connection-org1.yaml', 'utf8')); - - // Create a new CA client for interacting with the CA. - const caInfo = connectionProfile.certificateAuthorities['ca.org1.example.com']; - const caTLSCACerts = caInfo.tlsCACerts.pem; - const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName); - - // Create a new file system based wallet for managing identities. - const walletPath = path.join(process.cwd(), '../identity/user/balaji/wallet'); - const wallet = await Wallets.newFileSystemWallet(walletPath); - console.log(`Wallet path: ${walletPath}`); - - // Check to see if we've already enrolled the admin user. - const userExists = await wallet.get('balaji'); - if (userExists) { - console.log('An identity for the client user "balaji" already exists in the wallet'); - return; - } - - // Enroll the admin user, and import the new identity into the wallet. - const enrollment = await ca.enroll({ enrollmentID: 'user1', enrollmentSecret: 'user1pw' }); - const x509Identity = { - credentials: { - certificate: enrollment.certificate, - privateKey: enrollment.key.toBytes(), - }, - mspId: 'Org1MSP', - type: 'X.509', - }; - await wallet.put('balaji', x509Identity); - console.log('Successfully enrolled client user "balaji" and imported it into the wallet'); - - } catch (error) { - console.error(`Failed to enroll client user "balaji": ${error}`); - process.exit(1); - } -} - -main(); diff --git a/commercial-paper/organization/digibank/application/package.json b/commercial-paper/organization/digibank/application/package.json deleted file mode 100644 index 176c1ec0..00000000 --- a/commercial-paper/organization/digibank/application/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "nodejs", - "version": "1.0.0", - "description": "", - "main": "buy.js", - "scripts": { - "test": "rm -rf _idwallet && node addToWallet.js && node buy.js" - }, - "keywords": [], - "author": "", - "license": "Apache-2.0", - "dependencies": { - "fabric-network": "^2.2.4", - "fabric-ca-client": "^2.2.4", - "js-yaml": "^3.12.0" - }, - "devDependencies": { - "eslint": "^5.6.0" - } -} diff --git a/commercial-paper/organization/digibank/application/queryapp.js b/commercial-paper/organization/digibank/application/queryapp.js deleted file mode 100644 index fcba8fad..00000000 --- a/commercial-paper/organization/digibank/application/queryapp.js +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -/* - * This application has 6 basic steps: - * 1. Select an identity from a wallet - * 2. Connect to network gateway - * 3. Access PaperNet network - * 4. Construct request to query the ledger - * 5. Evaluate transactions (queries) - * 6. Process responses - */ - -'use strict'; - -// Bring key classes into scope, most importantly Fabric SDK network class -const fs = require('fs'); -const yaml = require('js-yaml'); -const { Wallets, Gateway } = require('fabric-network'); - - -// Main program function -async function main() { - - // A wallet stores a collection of identities for use - const wallet = await Wallets.newFileSystemWallet('../identity/user/balaji/wallet'); - - - // A gateway defines the peers used to access Fabric networks - const gateway = new Gateway(); - - // Main try/catch block - try { - - // Specify userName for network access - const userName = 'balaji'; - - // Load connection profile; will be used to locate a gateway - let connectionProfile = yaml.safeLoad(fs.readFileSync('../gateway/connection-org1.yaml', 'utf8')); - - // Set connection options; identity and wallet - let connectionOptions = { - identity: userName, - wallet: wallet, - discovery: { enabled: true, asLocalhost: true } - - }; - - // Connect to gateway using application specified parameters - console.log('Connect to Fabric gateway.'); - - await gateway.connect(connectionProfile, connectionOptions); - - // Access PaperNet network - console.log('Use network channel: mychannel.'); - - const network = await gateway.getNetwork('mychannel'); - - // Get addressability to commercial paper contract - console.log('Use org.papernet.commercialpaper smart contract.'); - - const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper'); - - // queries - commercial paper - console.log('-----------------------------------------------------------------------------------------'); - console.log('****** Submitting commercial paper queries ****** \n\n '); - - - // 1 asset history - console.log('1. Query Commercial Paper History....'); - console.log('-----------------------------------------------------------------------------------------\n'); - let queryResponse = await contract.evaluateTransaction('queryHistory', 'MagnetoCorp', '00001'); - - let json = JSON.parse(queryResponse.toString()); - console.log(json); - console.log('\n\n'); - console.log('\n History query complete.'); - console.log('-----------------------------------------------------------------------------------------\n\n'); - - // 2 ownership query - console.log('2. Query Commercial Paper Ownership.... Papers owned by MagnetoCorp'); - console.log('-----------------------------------------------------------------------------------------\n'); - let queryResponse2 = await contract.evaluateTransaction('queryOwner', 'MagnetoCorp'); - json = JSON.parse(queryResponse2.toString()); - console.log(json); - - console.log('\n\n'); - console.log('\n Paper Ownership query complete.'); - console.log('-----------------------------------------------------------------------------------------\n\n'); - - // 3 partial key query - console.log('3. Query Commercial Paper Partial Key.... Papers in org.papernet.papers namespace and prefixed MagnetoCorp'); - console.log('-----------------------------------------------------------------------------------------\n'); - let queryResponse3 = await contract.evaluateTransaction('queryPartial', 'MagnetoCorp'); - - json = JSON.parse(queryResponse3.toString()); - console.log(json); - console.log('\n\n'); - - console.log('\n Partial Key query complete.'); - console.log('-----------------------------------------------------------------------------------------\n\n'); - - - // 4 Named query - all redeemed papers - console.log('4. Named Query: ... All papers in org.papernet.papers that are in current state of redeemed'); - console.log('-----------------------------------------------------------------------------------------\n'); - let queryResponse4 = await contract.evaluateTransaction('queryNamed', 'redeemed'); - - json = JSON.parse(queryResponse4.toString()); - console.log(json); - console.log('\n\n'); - - console.log('\n Named query "redeemed" complete.'); - console.log('-----------------------------------------------------------------------------------------\n\n'); - - - // 5 named query - by value - console.log('5. Named Query:.... All papers in org.papernet.papers with faceValue > 4000000'); - console.log('-----------------------------------------------------------------------------------------\n'); - let queryResponse5 = await contract.evaluateTransaction('queryNamed', 'value'); - - json = JSON.parse(queryResponse5.toString()); - console.log(json); - console.log('\n\n'); - - console.log('\n Named query by "value" complete.'); - console.log('-----------------------------------------------------------------------------------------\n\n'); - } catch (error) { - - console.log(`Error processing transaction. ${error}`); - console.log(error.stack); - - } finally { - - // Disconnect from the gateway - console.log('Disconnect from Fabric gateway.'); - gateway.disconnect(); - - } -} -main().then(() => { - - console.log('Queryapp program complete.'); - -}).catch((e) => { - - console.log('Queryapp program exception.'); - console.log(e); - console.log(e.stack); - process.exit(-1); - -}); diff --git a/commercial-paper/organization/digibank/application/redeem.js b/commercial-paper/organization/digibank/application/redeem.js deleted file mode 100644 index 0f6699e8..00000000 --- a/commercial-paper/organization/digibank/application/redeem.js +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -/* - * This application has 6 basic steps: - * 1. Select an identity from a wallet - * 2. Connect to network gateway - * 3. Access PaperNet network - * 4. Construct request to issue commercial paper - * 5. Submit transaction - * 6. Process response - */ - -'use strict'; - -// Bring key classes into scope, most importantly Fabric SDK network class -const fs = require('fs'); -const yaml = require('js-yaml'); -const { Wallets, Gateway } = require('fabric-network'); -const CommercialPaper = require('../contract/lib/paper.js'); - - -// Main program function -async function main() { - - // A wallet stores a collection of identities for use - const wallet = await Wallets.newFileSystemWallet('../identity/user/balaji/wallet'); - - - // A gateway defines the peers used to access Fabric networks - const gateway = new Gateway(); - - // Main try/catch block - try { - - // Specify userName for network access - // Specify userName for network access - const userName = 'balaji'; - - // Load connection profile; will be used to locate a gateway - let connectionProfile = yaml.safeLoad(fs.readFileSync('../gateway/connection-org1.yaml', 'utf8')); - - // Set connection options; identity and wallet - let connectionOptions = { - identity: userName, - wallet: wallet, - discovery: { enabled:true, asLocalhost: true } - }; - - // Connect to gateway using application specified parameters - console.log('Connect to Fabric gateway.'); - - await gateway.connect(connectionProfile, connectionOptions); - - // Access PaperNet network - console.log('Use network channel: mychannel.'); - - const network = await gateway.getNetwork('mychannel'); - - // Get addressability to commercial paper contract - console.log('Use org.papernet.commercialpaper smart contract.'); - - const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper'); - - // redeem commercial paper - console.log('Submit commercial paper redeem transaction.'); - - const redeemResponse = await contract.submitTransaction('redeem', 'MagnetoCorp', '00001', 'DigiBank', 'Org2MSP', '2020-11-30'); - - // process response - console.log('Process redeem transaction response.'); - - let paper = CommercialPaper.fromBuffer(redeemResponse); - - console.log(`${paper.issuer} commercial paper : ${paper.paperNumber} successfully redeemed with ${paper.owner}`); - - console.log('Transaction complete.'); - - } catch (error) { - - console.log(`Error processing transaction. ${error}`); - console.log(error.stack); - - } finally { - - // Disconnect from the gateway - console.log('Disconnect from Fabric gateway.') - gateway.disconnect(); - - } -} -main().then(() => { - - console.log('Redeem program complete.'); - -}).catch((e) => { - - console.log('Redeem program exception.'); - console.log(e); - console.log(e.stack); - process.exit(-1); - -}); diff --git a/commercial-paper/organization/digibank/configuration/cli/docker-compose.yml b/commercial-paper/organization/digibank/configuration/cli/docker-compose.yml deleted file mode 100644 index b33e1cac..00000000 --- a/commercial-paper/organization/digibank/configuration/cli/docker-compose.yml +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright IBM Corp All Rights Reserved -# -# SPDX-License-Identifier: Apache-2.0 -# -version: '2' - -networks: - basic: - external: - name: fabric_test - -services: - cliDigiBank: - container_name: cliDigiBank - image: hyperledger/fabric-tools:2.0.0-beta - tty: true - environment: - - GOPATH=/opt/gopath - - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - - FABRIC_LOGGING_SPEC=info - - CORE_PEER_ID=cli - - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - - CORE_PEER_LOCALMSPID=Org1MSP - - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp - - CORE_CHAINCODE_KEEPALIVE=10 - - CORE_PEER_TLS_ENABLED=true - - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt - - ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem - working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer - command: /bin/bash - volumes: - - /var/run/docker.sock:/host/var/run/docker.sock - - ./../../../../organization/digibank:/opt/gopath/src/github.com/ - - ./../../../../../test-network/organizations:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ - networks: - - test diff --git a/commercial-paper/organization/digibank/configuration/cli/monitordocker.sh b/commercial-paper/organization/digibank/configuration/cli/monitordocker.sh deleted file mode 100755 index 2cf82fbd..00000000 --- a/commercial-paper/organization/digibank/configuration/cli/monitordocker.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# This script uses the logspout and http stream tools to let you watch the docker containers -# in action. -# -# More information at https://github.com/gliderlabs/logspout/tree/master/httpstream - -if [ -z "$1" ]; then - DOCKER_NETWORK=basicnetwork_basic -else - DOCKER_NETWORK="$1" -fi - -if [ -z "$2" ]; then - PORT=8000 -else - PORT="$2" -fi - -echo Starting monitoring on all containers on the network ${DOCKER_NETWORK} - -docker kill logspout 2> /dev/null 1>&2 || true -docker rm logspout 2> /dev/null 1>&2 || true - -docker run -d --name="logspout" \ - --volume=/var/run/docker.sock:/var/run/docker.sock \ - --publish=127.0.0.1:${PORT}:80 \ - --network ${DOCKER_NETWORK} \ - gliderlabs/logspout -sleep 3 -curl http://127.0.0.1:${PORT}/logs diff --git a/commercial-paper/organization/digibank/contract-go/commercial-paper/paper.go b/commercial-paper/organization/digibank/contract-go/commercial-paper/paper.go deleted file mode 100644 index 94b072c2..00000000 --- a/commercial-paper/organization/digibank/contract-go/commercial-paper/paper.go +++ /dev/null @@ -1,139 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "encoding/json" - "fmt" - - ledgerapi "github.com/hyperledger/fabric-samples/commercial-paper/organization/digibank/contract-go/ledger-api" -) - -// State enum for commercial paper state property -type State uint - -const ( - // ISSUED state for when a paper has been issued - ISSUED State = iota + 1 - // TRADING state for when a paper is trading - TRADING - // REDEEMED state for when a paper has been redeemed - REDEEMED -) - -func (state State) String() string { - names := []string{"ISSUED", "TRADING", "REDEEMED"} - - if state < ISSUED || state > REDEEMED { - return "UNKNOWN" - } - - return names[state-1] -} - -// CreateCommercialPaperKey creates a key for commercial papers -func CreateCommercialPaperKey(issuer string, paperNumber string) string { - return ledgerapi.MakeKey(issuer, paperNumber) -} - -// Used for managing the fact status is private but want it in world state -type commercialPaperAlias CommercialPaper -type jsonCommercialPaper struct { - *commercialPaperAlias - State State `json:"currentState"` - Class string `json:"class"` - Key string `json:"key"` -} - -// CommercialPaper defines a commercial paper -type CommercialPaper struct { - PaperNumber string `json:"paperNumber"` - Issuer string `json:"issuer"` - IssueDateTime string `json:"issueDateTime"` - FaceValue int `json:"faceValue"` - MaturityDateTime string `json:"maturityDateTime"` - Owner string `json:"owner"` - state State `metadata:"currentState"` - class string `metadata:"class"` - key string `metadata:"key"` -} - -// UnmarshalJSON special handler for managing JSON marshalling -func (cp *CommercialPaper) UnmarshalJSON(data []byte) error { - jcp := jsonCommercialPaper{commercialPaperAlias: (*commercialPaperAlias)(cp)} - - err := json.Unmarshal(data, &jcp) - - if err != nil { - return err - } - - cp.state = jcp.State - - return nil -} - -// MarshalJSON special handler for managing JSON marshalling -func (cp CommercialPaper) MarshalJSON() ([]byte, error) { - jcp := jsonCommercialPaper{commercialPaperAlias: (*commercialPaperAlias)(&cp), State: cp.state, Class: "org.papernet.commercialpaper", Key: ledgerapi.MakeKey(cp.Issuer, cp.PaperNumber)} - - return json.Marshal(&jcp) -} - -// GetState returns the state -func (cp *CommercialPaper) GetState() State { - return cp.state -} - -// SetIssued returns the state to issued -func (cp *CommercialPaper) SetIssued() { - cp.state = ISSUED -} - -// SetTrading sets the state to trading -func (cp *CommercialPaper) SetTrading() { - cp.state = TRADING -} - -// SetRedeemed sets the state to redeemed -func (cp *CommercialPaper) SetRedeemed() { - cp.state = REDEEMED -} - -// IsIssued returns true if state is issued -func (cp *CommercialPaper) IsIssued() bool { - return cp.state == ISSUED -} - -// IsTrading returns true if state is trading -func (cp *CommercialPaper) IsTrading() bool { - return cp.state == TRADING -} - -// IsRedeemed returns true if state is redeemed -func (cp *CommercialPaper) IsRedeemed() bool { - return cp.state == REDEEMED -} - -// GetSplitKey returns values which should be used to form key -func (cp *CommercialPaper) GetSplitKey() []string { - return []string{cp.Issuer, cp.PaperNumber} -} - -// Serialize formats the commercial paper as JSON bytes -func (cp *CommercialPaper) Serialize() ([]byte, error) { - return json.Marshal(cp) -} - -// Deserialize formats the commercial paper from JSON bytes -func Deserialize(bytes []byte, cp *CommercialPaper) error { - err := json.Unmarshal(bytes, cp) - - if err != nil { - return fmt.Errorf("Error deserializing commercial paper. %s", err.Error()) - } - - return nil -} diff --git a/commercial-paper/organization/digibank/contract-go/commercial-paper/paper_test.go b/commercial-paper/organization/digibank/contract-go/commercial-paper/paper_test.go deleted file mode 100644 index 6af65ef7..00000000 --- a/commercial-paper/organization/digibank/contract-go/commercial-paper/paper_test.go +++ /dev/null @@ -1,125 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "testing" - - ledgerapi "github.com/hyperledger/fabric-samples/commercial-paper/organization/digibank/contract-go/ledger-api" - "github.com/stretchr/testify/assert" -) - -func TestString(t *testing.T) { - assert.Equal(t, "ISSUED", ISSUED.String(), "should return string for issued") - assert.Equal(t, "TRADING", TRADING.String(), "should return string for issued") - assert.Equal(t, "REDEEMED", REDEEMED.String(), "should return string for issued") - assert.Equal(t, "UNKNOWN", State(REDEEMED+1).String(), "should return unknown when not one of constants") -} - -func TestCreateCommercialPaperKey(t *testing.T) { - assert.Equal(t, ledgerapi.MakeKey("someissuer", "somepaper"), CreateCommercialPaperKey("someissuer", "somepaper"), "should return key comprised of passed values") -} - -func TestGetState(t *testing.T) { - cp := new(CommercialPaper) - cp.state = ISSUED - - assert.Equal(t, ISSUED, cp.GetState(), "should return set state") -} - -func TestSetIssued(t *testing.T) { - cp := new(CommercialPaper) - cp.SetIssued() - assert.Equal(t, ISSUED, cp.state, "should set state to trading") -} - -func TestSetTrading(t *testing.T) { - cp := new(CommercialPaper) - cp.SetTrading() - assert.Equal(t, TRADING, cp.state, "should set state to trading") -} - -func TestSetRedeemed(t *testing.T) { - cp := new(CommercialPaper) - cp.SetRedeemed() - assert.Equal(t, REDEEMED, cp.state, "should set state to trading") -} - -func TestIsIssued(t *testing.T) { - cp := new(CommercialPaper) - - cp.SetIssued() - assert.True(t, cp.IsIssued(), "should be true when status set to issued") - - cp.SetTrading() - assert.False(t, cp.IsIssued(), "should be false when status not set to issued") -} - -func TestIsTrading(t *testing.T) { - cp := new(CommercialPaper) - - cp.SetTrading() - assert.True(t, cp.IsTrading(), "should be true when status set to trading") - - cp.SetRedeemed() - assert.False(t, cp.IsTrading(), "should be false when status not set to trading") -} - -func TestIsRedeemed(t *testing.T) { - cp := new(CommercialPaper) - - cp.SetRedeemed() - assert.True(t, cp.IsRedeemed(), "should be true when status set to redeemed") - - cp.SetIssued() - assert.False(t, cp.IsRedeemed(), "should be false when status not set to redeemed") -} - -func TestGetSplitKey(t *testing.T) { - cp := new(CommercialPaper) - cp.PaperNumber = "somepaper" - cp.Issuer = "someissuer" - - assert.Equal(t, []string{"someissuer", "somepaper"}, cp.GetSplitKey(), "should return issuer and paper number as split key") -} - -func TestSerialize(t *testing.T) { - cp := new(CommercialPaper) - cp.PaperNumber = "somepaper" - cp.Issuer = "someissuer" - cp.IssueDateTime = "sometime" - cp.FaceValue = 1000 - cp.MaturityDateTime = "somelatertime" - cp.Owner = "someowner" - cp.state = TRADING - - bytes, err := cp.Serialize() - assert.Nil(t, err, "should not error on serialize") - assert.Equal(t, `{"paperNumber":"somepaper","issuer":"someissuer","issueDateTime":"sometime","faceValue":1000,"maturityDateTime":"somelatertime","owner":"someowner","currentState":2,"class":"org.papernet.commercialpaper","key":"someissuer:somepaper"}`, string(bytes), "should return JSON formatted value") -} - -func TestDeserialize(t *testing.T) { - var cp *CommercialPaper - var err error - - goodJSON := `{"paperNumber":"somepaper","issuer":"someissuer","issueDateTime":"sometime","faceValue":1000,"maturityDateTime":"somelatertime","owner":"someowner","currentState":2,"class":"org.papernet.commercialpaper","key":"someissuer:somepaper"}` - expectedCp := new(CommercialPaper) - expectedCp.PaperNumber = "somepaper" - expectedCp.Issuer = "someissuer" - expectedCp.IssueDateTime = "sometime" - expectedCp.FaceValue = 1000 - expectedCp.MaturityDateTime = "somelatertime" - expectedCp.Owner = "someowner" - expectedCp.state = TRADING - cp = new(CommercialPaper) - err = Deserialize([]byte(goodJSON), cp) - assert.Nil(t, err, "should not return error for deserialize") - assert.Equal(t, expectedCp, cp, "should create expected commercial paper") - - badJSON := `{"paperNumber":"somepaper","issuer":"someissuer","issueDateTime":"sometime","faceValue":"NaN","maturityDateTime":"somelatertime","owner":"someowner","currentState":2,"class":"org.papernet.commercialpaper","key":"someissuer:somepaper"}` - cp = new(CommercialPaper) - err = Deserialize([]byte(badJSON), cp) - assert.EqualError(t, err, "Error deserializing commercial paper. json: cannot unmarshal string into Go struct field jsonCommercialPaper.faceValue of type int", "should return error for bad data") -} diff --git a/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontext.go b/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontext.go deleted file mode 100644 index c346cf3b..00000000 --- a/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontext.go +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "github.com/hyperledger/fabric-contract-api-go/contractapi" -) - -// TransactionContextInterface an interface to -// describe the minimum required functions for -// a transaction context in the commercial -// paper -type TransactionContextInterface interface { - contractapi.TransactionContextInterface - GetPaperList() ListInterface -} - -// TransactionContext implementation of -// TransactionContextInterface for use with -// commercial paper contract -type TransactionContext struct { - contractapi.TransactionContext - paperList *list -} - -// GetPaperList return paper list -func (tc *TransactionContext) GetPaperList() ListInterface { - if tc.paperList == nil { - tc.paperList = newList(tc) - } - - return tc.paperList -} diff --git a/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontext_test.go b/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontext_test.go deleted file mode 100644 index 81317aac..00000000 --- a/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontext_test.go +++ /dev/null @@ -1,31 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "testing" - - ledgerapi "github.com/hyperledger/fabric-samples/commercial-paper/organization/digibank/contract-go/ledger-api" - "github.com/stretchr/testify/assert" -) - -func TestGetPaperList(t *testing.T) { - var tc *TransactionContext - var expectedPaperList *list - - tc = new(TransactionContext) - expectedPaperList = newList(tc) - actualList := tc.GetPaperList().(*list) - assert.Equal(t, expectedPaperList.stateList.(*ledgerapi.StateList).Name, actualList.stateList.(*ledgerapi.StateList).Name, "should configure paper list when one not already configured") - - tc = new(TransactionContext) - expectedPaperList = new(list) - expectedStateList := new(ledgerapi.StateList) - expectedStateList.Ctx = tc - expectedStateList.Name = "existing paper list" - expectedPaperList.stateList = expectedStateList - tc.paperList = expectedPaperList - assert.Equal(t, expectedPaperList, tc.GetPaperList(), "should return set paper list when already set") -} diff --git a/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontract.go b/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontract.go deleted file mode 100644 index 4e8cee20..00000000 --- a/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontract.go +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "fmt" - - "github.com/hyperledger/fabric-contract-api-go/contractapi" -) - -// Contract chaincode that defines -// the business logic for managing commercial -// paper -type Contract struct { - contractapi.Contract -} - -// Instantiate does nothing -func (c *Contract) Instantiate() { - fmt.Println("Instantiated") -} - -// Issue creates a new commercial paper and stores it in the world state -func (c *Contract) Issue(ctx TransactionContextInterface, issuer string, paperNumber string, issueDateTime string, maturityDateTime string, faceValue int) (*CommercialPaper, error) { - paper := CommercialPaper{PaperNumber: paperNumber, Issuer: issuer, IssueDateTime: issueDateTime, FaceValue: faceValue, MaturityDateTime: maturityDateTime, Owner: issuer} - paper.SetIssued() - - err := ctx.GetPaperList().AddPaper(&paper) - - if err != nil { - return nil, err - } - - return &paper, nil -} - -// Buy updates a commercial paper to be in trading status and sets the new owner -func (c *Contract) Buy(ctx TransactionContextInterface, issuer string, paperNumber string, currentOwner string, newOwner string, price int, purchaseDateTime string) (*CommercialPaper, error) { - paper, err := ctx.GetPaperList().GetPaper(issuer, paperNumber) - - if err != nil { - return nil, err - } - - if paper.Owner != currentOwner { - return nil, fmt.Errorf("Paper %s:%s is not owned by %s", issuer, paperNumber, currentOwner) - } - - if paper.IsIssued() { - paper.SetTrading() - } - - if !paper.IsTrading() { - return nil, fmt.Errorf("Paper %s:%s is not trading. Current state = %s", issuer, paperNumber, paper.GetState()) - } - - paper.Owner = newOwner - - err = ctx.GetPaperList().UpdatePaper(paper) - - if err != nil { - return nil, err - } - - return paper, nil -} - -// Redeem updates a commercial paper status to be redeemed -func (c *Contract) Redeem(ctx TransactionContextInterface, issuer string, paperNumber string, redeemingOwner string, redeenDateTime string) (*CommercialPaper, error) { - paper, err := ctx.GetPaperList().GetPaper(issuer, paperNumber) - - if err != nil { - return nil, err - } - - if paper.Owner != redeemingOwner { - return nil, fmt.Errorf("Paper %s:%s is not owned by %s", issuer, paperNumber, redeemingOwner) - } - - if paper.IsRedeemed() { - return nil, fmt.Errorf("Paper %s:%s is already redeemed", issuer, paperNumber) - } - - paper.Owner = paper.Issuer - paper.SetRedeemed() - - err = ctx.GetPaperList().UpdatePaper(paper) - - if err != nil { - return nil, err - } - - return paper, nil -} diff --git a/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontract_test.go b/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontract_test.go deleted file mode 100644 index 25c429b3..00000000 --- a/commercial-paper/organization/digibank/contract-go/commercial-paper/papercontract_test.go +++ /dev/null @@ -1,185 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "errors" - "testing" - - "github.com/hyperledger/fabric-contract-api-go/contractapi" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" -) - -// ######### -// HELPERS -// ######### -type MockPaperList struct { - mock.Mock -} - -func (mpl *MockPaperList) AddPaper(paper *CommercialPaper) error { - args := mpl.Called(paper) - - return args.Error(0) -} - -func (mpl *MockPaperList) GetPaper(issuer string, papernumber string) (*CommercialPaper, error) { - args := mpl.Called(issuer, papernumber) - - return args.Get(0).(*CommercialPaper), args.Error(1) -} - -func (mpl *MockPaperList) UpdatePaper(paper *CommercialPaper) error { - args := mpl.Called(paper) - - return args.Error(0) -} - -type MockTransactionContext struct { - contractapi.TransactionContext - paperList *MockPaperList -} - -func (mtc *MockTransactionContext) GetPaperList() ListInterface { - return mtc.paperList -} - -func resetPaper(paper *CommercialPaper) { - paper.Owner = "someowner" - paper.SetTrading() -} - -// ######### -// TESTS -// ######### - -func TestIssue(t *testing.T) { - var paper *CommercialPaper - var err error - - mpl := new(MockPaperList) - ctx := new(MockTransactionContext) - ctx.paperList = mpl - - contract := new(Contract) - - var sentPaper *CommercialPaper - - mpl.On("AddPaper", mock.MatchedBy(func(paper *CommercialPaper) bool { sentPaper = paper; return paper.Issuer == "someissuer" })).Return(nil) - mpl.On("AddPaper", mock.MatchedBy(func(paper *CommercialPaper) bool { sentPaper = paper; return paper.Issuer == "someotherissuer" })).Return(errors.New("AddPaper error")) - - expectedPaper := CommercialPaper{PaperNumber: "somepaper", Issuer: "someissuer", IssueDateTime: "someissuedate", FaceValue: 1000, MaturityDateTime: "somematuritydate", Owner: "someissuer", state: 1} - paper, err = contract.Issue(ctx, "someissuer", "somepaper", "someissuedate", "somematuritydate", 1000) - assert.Nil(t, err, "should not error when add paper does not error") - assert.Equal(t, sentPaper, paper, "should send the same paper as it returns to add paper") - assert.Equal(t, expectedPaper, *paper, "should correctly configure paper") - - paper, err = contract.Issue(ctx, "someotherissuer", "somepaper", "someissuedate", "somematuritydate", 1000) - assert.EqualError(t, err, "AddPaper error", "should return error when add paper fails") - assert.Nil(t, paper, "should not return paper when fails") -} - -func TestBuy(t *testing.T) { - var paper *CommercialPaper - var err error - - mpl := new(MockPaperList) - ctx := new(MockTransactionContext) - ctx.paperList = mpl - - contract := new(Contract) - - wsPaper := new(CommercialPaper) - resetPaper(wsPaper) - - var sentPaper *CommercialPaper - var emptyPaper *CommercialPaper - shouldError := false - - mpl.On("GetPaper", "someissuer", "somepaper").Return(wsPaper, nil) - mpl.On("GetPaper", "someotherissuer", "someotherpaper").Return(emptyPaper, errors.New("GetPaper error")) - mpl.On("UpdatePaper", mock.MatchedBy(func(paper *CommercialPaper) bool { return shouldError })).Return(errors.New("UpdatePaper error")) - mpl.On("UpdatePaper", mock.MatchedBy(func(paper *CommercialPaper) bool { sentPaper = paper; return !shouldError })).Return(nil) - - paper, err = contract.Buy(ctx, "someotherissuer", "someotherpaper", "someowner", "someotherowner", 100, "2019-12-10:10:00") - assert.EqualError(t, err, "GetPaper error", "should return error when GetPaper errors") - assert.Nil(t, paper, "should return nil for paper when GetPaper errors") - - paper, err = contract.Buy(ctx, "someissuer", "somepaper", "someotherowner", "someowner", 100, "2019-12-10:10:00") - assert.EqualError(t, err, "Paper someissuer:somepaper is not owned by someotherowner", "should error when sent owner not correct") - assert.Nil(t, paper, "should not return paper for bad owner error") - - resetPaper(wsPaper) - wsPaper.SetRedeemed() - paper, err = contract.Buy(ctx, "someissuer", "somepaper", "someowner", "someotherowner", 100, "2019-12-10:10:00") - assert.EqualError(t, err, "Paper someissuer:somepaper is not trading. Current state = REDEEMED") - assert.Nil(t, paper, "should not return paper for bad state error") - - resetPaper(wsPaper) - shouldError = true - paper, err = contract.Buy(ctx, "someissuer", "somepaper", "someowner", "someotherowner", 100, "2019-12-10:10:00") - assert.EqualError(t, err, "UpdatePaper error", "should error when update paper fails") - assert.Nil(t, paper, "should not return paper for bad state error") - shouldError = false - - resetPaper(wsPaper) - wsPaper.SetIssued() - paper, err = contract.Buy(ctx, "someissuer", "somepaper", "someowner", "someotherowner", 100, "2019-12-10:10:00") - assert.Nil(t, err, "should not error when good paper and owner") - assert.Equal(t, "someotherowner", paper.Owner, "should update the owner of the paper") - assert.True(t, paper.IsTrading(), "should mark issued paper as trading") - assert.Equal(t, sentPaper, paper, "should update same paper as it returns in the world state") -} - -func TestRedeem(t *testing.T) { - var paper *CommercialPaper - var err error - - mpl := new(MockPaperList) - ctx := new(MockTransactionContext) - ctx.paperList = mpl - - contract := new(Contract) - - var sentPaper *CommercialPaper - wsPaper := new(CommercialPaper) - resetPaper(wsPaper) - - var emptyPaper *CommercialPaper - shouldError := false - - mpl.On("GetPaper", "someissuer", "somepaper").Return(wsPaper, nil) - mpl.On("GetPaper", "someotherissuer", "someotherpaper").Return(emptyPaper, errors.New("GetPaper error")) - mpl.On("UpdatePaper", mock.MatchedBy(func(paper *CommercialPaper) bool { return shouldError })).Return(errors.New("UpdatePaper error")) - mpl.On("UpdatePaper", mock.MatchedBy(func(paper *CommercialPaper) bool { sentPaper = paper; return !shouldError })).Return(nil) - - paper, err = contract.Redeem(ctx, "someotherissuer", "someotherpaper", "someowner", "2021-12-10:10:00") - assert.EqualError(t, err, "GetPaper error", "should error when GetPaper errors") - assert.Nil(t, paper, "should not return paper when GetPaper errors") - - paper, err = contract.Redeem(ctx, "someissuer", "somepaper", "someotherowner", "2021-12-10:10:00") - assert.EqualError(t, err, "Paper someissuer:somepaper is not owned by someotherowner", "should error when paper owned by someone else") - assert.Nil(t, paper, "should not return paper when errors as owned by someone else") - - resetPaper(wsPaper) - wsPaper.SetRedeemed() - paper, err = contract.Redeem(ctx, "someissuer", "somepaper", "someowner", "2021-12-10:10:00") - assert.EqualError(t, err, "Paper someissuer:somepaper is already redeemed", "should error when paper already redeemed") - assert.Nil(t, paper, "should not return paper when errors as already redeemed") - - shouldError = true - resetPaper(wsPaper) - paper, err = contract.Redeem(ctx, "someissuer", "somepaper", "someowner", "2021-12-10:10:00") - assert.EqualError(t, err, "UpdatePaper error", "should error when update paper errors") - assert.Nil(t, paper, "should not return paper when UpdatePaper errors") - shouldError = false - - resetPaper(wsPaper) - paper, err = contract.Redeem(ctx, "someissuer", "somepaper", "someowner", "2021-12-10:10:00") - assert.Nil(t, err, "should not error on good redeem") - assert.True(t, paper.IsRedeemed(), "should return redeemed paper") - assert.Equal(t, sentPaper, paper, "should update same paper as it returns in the world state") -} diff --git a/commercial-paper/organization/digibank/contract-go/commercial-paper/paperlist.go b/commercial-paper/organization/digibank/contract-go/commercial-paper/paperlist.go deleted file mode 100644 index c3bdf810..00000000 --- a/commercial-paper/organization/digibank/contract-go/commercial-paper/paperlist.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ledgerapi "github.com/hyperledger/fabric-samples/commercial-paper/organization/digibank/contract-go/ledger-api" - -// ListInterface defines functionality needed -// to interact with the world state on behalf -// of a commercial paper -type ListInterface interface { - AddPaper(*CommercialPaper) error - GetPaper(string, string) (*CommercialPaper, error) - UpdatePaper(*CommercialPaper) error -} - -type list struct { - stateList ledgerapi.StateListInterface -} - -func (cpl *list) AddPaper(paper *CommercialPaper) error { - return cpl.stateList.AddState(paper) -} - -func (cpl *list) GetPaper(issuer string, paperNumber string) (*CommercialPaper, error) { - cp := new(CommercialPaper) - - err := cpl.stateList.GetState(CreateCommercialPaperKey(issuer, paperNumber), cp) - - if err != nil { - return nil, err - } - - return cp, nil -} - -func (cpl *list) UpdatePaper(paper *CommercialPaper) error { - return cpl.stateList.UpdateState(paper) -} - -// NewList create a new list from context -func newList(ctx TransactionContextInterface) *list { - stateList := new(ledgerapi.StateList) - stateList.Ctx = ctx - stateList.Name = "org.papernet.commercialpaperlist" - stateList.Deserialize = func(bytes []byte, state ledgerapi.StateInterface) error { - return Deserialize(bytes, state.(*CommercialPaper)) - } - - list := new(list) - list.stateList = stateList - - return list -} diff --git a/commercial-paper/organization/digibank/contract-go/commercial-paper/paperlist_test.go b/commercial-paper/organization/digibank/contract-go/commercial-paper/paperlist_test.go deleted file mode 100644 index 33a2c30b..00000000 --- a/commercial-paper/organization/digibank/contract-go/commercial-paper/paperlist_test.go +++ /dev/null @@ -1,103 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "errors" - "testing" - - ledgerapi "github.com/hyperledger/fabric-samples/commercial-paper/organization/digibank/contract-go/ledger-api" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" -) - -// ######### -// HELPERS -// ######### - -type MockStateList struct { - mock.Mock -} - -func (msl *MockStateList) AddState(state ledgerapi.StateInterface) error { - args := msl.Called(state) - - return args.Error(0) -} - -func (msl *MockStateList) GetState(key string, state ledgerapi.StateInterface) error { - args := msl.Called(key, state) - - state.(*CommercialPaper).PaperNumber = "somepaper" - - return args.Error(0) -} - -func (msl *MockStateList) UpdateState(state ledgerapi.StateInterface) error { - args := msl.Called(state) - - return args.Error(0) -} - -// ######### -// TESTS -// ######### - -func TestAddPaper(t *testing.T) { - paper := new(CommercialPaper) - - list := new(list) - msl := new(MockStateList) - msl.On("AddState", paper).Return(errors.New("Called add state correctly")) - list.stateList = msl - - err := list.AddPaper(paper) - assert.EqualError(t, err, "Called add state correctly", "should call state list add state with paper") -} - -func TestGetPaper(t *testing.T) { - var cp *CommercialPaper - var err error - - list := new(list) - msl := new(MockStateList) - msl.On("GetState", CreateCommercialPaperKey("someissuer", "somepaper"), mock.MatchedBy(func(state ledgerapi.StateInterface) bool { _, ok := state.(*CommercialPaper); return ok })).Return(nil) - msl.On("GetState", CreateCommercialPaperKey("someotherissuer", "someotherpaper"), mock.MatchedBy(func(state ledgerapi.StateInterface) bool { _, ok := state.(*CommercialPaper); return ok })).Return(errors.New("GetState error")) - list.stateList = msl - - cp, err = list.GetPaper("someissuer", "somepaper") - assert.Nil(t, err, "should not error when get state on state list does not error") - assert.Equal(t, cp.PaperNumber, "somepaper", "should use state list GetState to fill commercial paper") - - cp, err = list.GetPaper("someotherissuer", "someotherpaper") - assert.EqualError(t, err, "GetState error", "should return error when state list get state errors") - assert.Nil(t, cp, "should not return commercial paper on error") -} - -func TestUpdatePaper(t *testing.T) { - paper := new(CommercialPaper) - - list := new(list) - msl := new(MockStateList) - msl.On("UpdateState", paper).Return(errors.New("Called update state correctly")) - list.stateList = msl - - err := list.UpdatePaper(paper) - assert.EqualError(t, err, "Called update state correctly", "should call state list update state with paper") -} - -func TestNewStateList(t *testing.T) { - ctx := new(TransactionContext) - list := newList(ctx) - stateList, ok := list.stateList.(*ledgerapi.StateList) - - assert.True(t, ok, "should make statelist of type ledgerapi.StateList") - assert.Equal(t, ctx, stateList.Ctx, "should set the context to passed context") - assert.Equal(t, "org.papernet.commercialpaperlist", stateList.Name, "should set the name for the list") - - expectedErr := Deserialize([]byte("bad json"), new(CommercialPaper)) - err := stateList.Deserialize([]byte("bad json"), new(CommercialPaper)) - assert.EqualError(t, err, expectedErr.Error(), "should call Deserialize when stateList.Deserialize called") -} diff --git a/commercial-paper/organization/digibank/contract-go/go.mod b/commercial-paper/organization/digibank/contract-go/go.mod deleted file mode 100644 index 3652167b..00000000 --- a/commercial-paper/organization/digibank/contract-go/go.mod +++ /dev/null @@ -1,39 +0,0 @@ -module github.com/hyperledger/fabric-samples/commercial-paper/organization/digibank/contract-go - -go 1.17 - -require ( - github.com/hyperledger/fabric-contract-api-go v1.2.0 - github.com/stretchr/testify v1.8.0 -) - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect - github.com/go-openapi/spec v0.20.6 // indirect - github.com/go-openapi/swag v0.21.1 // 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/golang/protobuf v1.5.2 // indirect - github.com/hyperledger/fabric-chaincode-go v0.0.0-20220720122508-9207360bbddd // indirect - github.com/hyperledger/fabric-protos-go v0.0.0-20220613214546-bf864f01d75e // indirect - github.com/joho/godotenv v1.4.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.8.1 // indirect - github.com/stretchr/objx v0.4.0 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.0.0-20220708220712-1185a9018129 // indirect - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect - golang.org/x/text v0.3.7 // indirect - google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f // indirect - google.golang.org/grpc v1.48.0 // indirect - google.golang.org/protobuf v1.28.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/commercial-paper/organization/digibank/contract-go/go.sum b/commercial-paper/organization/digibank/contract-go/go.sum deleted file mode 100644 index 92a27e54..00000000 --- a/commercial-paper/organization/digibank/contract-go/go.sum +++ /dev/null @@ -1,486 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/gherkin-go/v19 v19.0.3/go.mod h1:jY/NP6jUtRSArQQJ5h1FXOUgk5fZK24qtE7vKi776Vw= -github.com/cucumber/godog v0.12.5/go.mod h1:u6SD7IXC49dLpPN35kal0oYEjsXZWee4pW6Tm9t5pIc= -github.com/cucumber/messages-go/v16 v16.0.0/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g= -github.com/cucumber/messages-go/v16 v16.0.1/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/spec v0.20.6 h1:ich1RQ3WDbfoeTqTAb+5EIxNmpKVJZWBNah9RAT0jIQ= -github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -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-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.10.1 h1:ppDLoXv2feQ5nus4IcgtyMdHQkKng2lhJCIm33cblM0= -github.com/gobuffalo/envy v1.10.1/go.mod h1:AWx4++KnNOW3JOeEvhSaq+mvgAvnMYOY1XSIin4Mago= -github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0= -github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= -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/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -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= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-memdb v1.3.0/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g= -github.com/hashicorp/go-memdb v1.3.3/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -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-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -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= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20220720122508-9207360bbddd h1:AIa0b7UPrt8e1YN4/68vhNnPxy/Mrgq9d2bYJ6O/KTE= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20220720122508-9207360bbddd/go.mod h1:OxME3M0bbgoWYHpXIVMzpbXgFqrTZnFmlH0Cpml54m0= -github.com/hyperledger/fabric-contract-api-go v1.2.0 h1:BmArPRmTjiC2brHk2FNlDoJ8bOI0ExKZhj2YqWAiv5o= -github.com/hyperledger/fabric-contract-api-go v1.2.0/go.mod h1:GU2NV95E5LNkFTCL3xcPgXzi8QNLXBZhx7DGnKskuqw= -github.com/hyperledger/fabric-protos-go v0.0.0-20220613214546-bf864f01d75e h1:Ae2p0e+v5ekrl4KgkbCStBTSoV67Cg9fPkEWrv0f3nk= -github.com/hyperledger/fabric-protos-go v0.0.0-20220613214546-bf864f01d75e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= -github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -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/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -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/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -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/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -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/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -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= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -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.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -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.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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -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= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0= -golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -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/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20220718134204-073382fd740c/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f h1:P8EiVSxZwC6xH2niv2N66aqwMtYFg+D54gbjpcqKJtM= -google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -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.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -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= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/commercial-paper/organization/digibank/contract-go/ledger-api/state.go b/commercial-paper/organization/digibank/contract-go/ledger-api/state.go deleted file mode 100644 index 6d8c3f86..00000000 --- a/commercial-paper/organization/digibank/contract-go/ledger-api/state.go +++ /dev/null @@ -1,27 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package ledgerapi - -import ( - "strings" -) - -// SplitKey splits a key on colon -func SplitKey(key string) []string { - return strings.Split(key, ":") -} - -// MakeKey joins key parts using colon -func MakeKey(keyParts ...string) string { - return strings.Join(keyParts, ":") -} - -// StateInterface interface states must implement -// for use in a list -type StateInterface interface { - // GetSplitKey return components that combine to form the key - GetSplitKey() []string - Serialize() ([]byte, error) -} diff --git a/commercial-paper/organization/digibank/contract-go/ledger-api/statelist.go b/commercial-paper/organization/digibank/contract-go/ledger-api/statelist.go deleted file mode 100644 index 492efb34..00000000 --- a/commercial-paper/organization/digibank/contract-go/ledger-api/statelist.go +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package ledgerapi - -import ( - "fmt" - - "github.com/hyperledger/fabric-contract-api-go/contractapi" -) - -// StateListInterface functions that a state list -// should have -type StateListInterface interface { - AddState(StateInterface) error - GetState(string, StateInterface) error - UpdateState(StateInterface) error -} - -// StateList useful for managing putting data in and out -// of the ledger. Implementation of StateListInterface -type StateList struct { - Ctx contractapi.TransactionContextInterface - Name string - Deserialize func([]byte, StateInterface) error -} - -// AddState puts state into world state -func (sl *StateList) AddState(state StateInterface) error { - key, _ := sl.Ctx.GetStub().CreateCompositeKey(sl.Name, state.GetSplitKey()) - data, err := state.Serialize() - - if err != nil { - return err - } - - return sl.Ctx.GetStub().PutState(key, data) -} - -// GetState returns state from world state. Unmarshalls the JSON -// into passed state. Key is the split key value used in Add/Update -// joined using a colon -func (sl *StateList) GetState(key string, state StateInterface) error { - ledgerKey, _ := sl.Ctx.GetStub().CreateCompositeKey(sl.Name, SplitKey(key)) - data, err := sl.Ctx.GetStub().GetState(ledgerKey) - - if err != nil { - return err - } else if data == nil { - return fmt.Errorf("No state found for %s", key) - } - - return sl.Deserialize(data, state) -} - -// UpdateState puts state into world state. Same as AddState but -// separate as semantically different -func (sl *StateList) UpdateState(state StateInterface) error { - return sl.AddState(state) -} diff --git a/commercial-paper/organization/digibank/contract-go/main.go b/commercial-paper/organization/digibank/contract-go/main.go deleted file mode 100644 index e6e079ed..00000000 --- a/commercial-paper/organization/digibank/contract-go/main.go +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package main - -import ( - "fmt" - - "github.com/hyperledger/fabric-contract-api-go/contractapi" - commercialpaper "github.com/hyperledger/fabric-samples/commercial-paper/organization/digibank/contract-go/commercial-paper" -) - -func main() { - - contract := new(commercialpaper.Contract) - contract.TransactionContextHandler = new(commercialpaper.TransactionContext) - contract.Name = "org.papernet.commercialpaper" - contract.Info.Version = "0.0.1" - - chaincode, err := contractapi.NewChaincode(contract) - - if err != nil { - panic(fmt.Sprintf("Error creating chaincode. %s", err.Error())) - } - - chaincode.Info.Title = "CommercialPaperChaincode" - chaincode.Info.Version = "0.0.1" - - err = chaincode.Start() - - if err != nil { - panic(fmt.Sprintf("Error starting chaincode. %s", err.Error())) - } -} diff --git a/commercial-paper/organization/digibank/contract-java/.gitignore b/commercial-paper/organization/digibank/contract-java/.gitignore deleted file mode 100644 index ae1478ca..00000000 --- a/commercial-paper/organization/digibank/contract-java/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -/.classpath -/.gradle/ -/.project -/.settings/ -/bin/ -/build/ diff --git a/commercial-paper/organization/digibank/contract-java/build.gradle b/commercial-paper/organization/digibank/contract-java/build.gradle deleted file mode 100644 index 65741879..00000000 --- a/commercial-paper/organization/digibank/contract-java/build.gradle +++ /dev/null @@ -1,37 +0,0 @@ -plugins { - id 'java-library-distribution' -} - -version '0.0.1' - -sourceCompatibility = 1.8 - -repositories { - mavenCentral() - maven { - url 'https://jitpack.io' - } - maven { - url "https://hyperledger.jfrog.io/hyperledger/fabric-maven" - } - -} - -dependencies { - compileOnly group: 'org.hyperledger.fabric-chaincode-java', name: 'fabric-chaincode-shim', version: '2.+' - compile group: 'org.json', name: 'json', version: '20180813' - testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2' - testImplementation 'org.assertj:assertj-core:3.11.1' - testImplementation 'org.mockito:mockito-core:2.+' -} - -test { - useJUnitPlatform() - testLogging { - events "passed", "skipped", "failed" - } -} - -tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters" -} diff --git a/commercial-paper/organization/digibank/contract-java/gradle/wrapper/gradle-wrapper.jar b/commercial-paper/organization/digibank/contract-java/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 5c2d1cf016b3885f6930543d57b744ea8c220a1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55616 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 \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/commercial-paper/organization/digibank/contract-java/gradlew.bat b/commercial-paper/organization/digibank/contract-java/gradlew.bat deleted file mode 100644 index 24467a14..00000000 --- a/commercial-paper/organization/digibank/contract-java/gradlew.bat +++ /dev/null @@ -1,100 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/commercial-paper/organization/digibank/contract-java/settings.gradle b/commercial-paper/organization/digibank/contract-java/settings.gradle deleted file mode 100644 index 0c5f0723..00000000 --- a/commercial-paper/organization/digibank/contract-java/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -rootProject.name = 'papercontract' - diff --git a/commercial-paper/organization/digibank/contract-java/shadow-build.gradle b/commercial-paper/organization/digibank/contract-java/shadow-build.gradle deleted file mode 100644 index 160bf421..00000000 --- a/commercial-paper/organization/digibank/contract-java/shadow-build.gradle +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ -plugins { - id 'com.github.johnrengelman.shadow' version '5.1.0' - id 'java' -} - - -version '0.0.1' - -sourceCompatibility = 1.8 - -repositories { - mavenCentral() - maven { - url 'https://jitpack.io' - } -} - -dependencies { - implementation group: 'org.hyperledger.fabric-chaincode-java', name: 'fabric-chaincode-shim', version: '2.+' - implementation group: 'org.json', name: 'json', version: '20180813' - testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2' - testImplementation 'org.assertj:assertj-core:3.11.1' - testImplementation 'org.mockito:mockito-core:2.+' -} - -test { - useJUnitPlatform() - testLogging { - events "passed", "skipped", "failed" - } -} - -shadowJar { - baseName = 'chaincode' - version = null - classifier = null - - manifest { - attributes 'Main-Class': 'org.hyperledger.fabric.contract.ContractRouter' - } -} - - -tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters" -} diff --git a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaper.java b/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaper.java deleted file mode 100644 index 13d16b66..00000000 --- a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaper.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.example; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.example.ledgerapi.State; -import org.hyperledger.fabric.contract.annotation.DataType; -import org.hyperledger.fabric.contract.annotation.Property; -import org.json.JSONObject; -import org.json.JSONPropertyIgnore; - -@DataType() -public class CommercialPaper extends State { - - // Enumerate commercial paper state values - public final static String ISSUED = "ISSUED"; - public final static String TRADING = "TRADING"; - public final static String REDEEMED = "REDEEMED"; - - @Property() - private String state=""; - - public String getState() { - return state; - } - - public CommercialPaper setState(String state) { - this.state = state; - return this; - } - - @JSONPropertyIgnore() - public boolean isIssued() { - return this.state.equals(CommercialPaper.ISSUED); - } - - @JSONPropertyIgnore() - public boolean isTrading() { - return this.state.equals(CommercialPaper.TRADING); - } - - @JSONPropertyIgnore() - public boolean isRedeemed() { - return this.state.equals(CommercialPaper.REDEEMED); - } - - public CommercialPaper setIssued() { - this.state = CommercialPaper.ISSUED; - return this; - } - - public CommercialPaper setTrading() { - this.state = CommercialPaper.TRADING; - return this; - } - - public CommercialPaper setRedeemed() { - this.state = CommercialPaper.REDEEMED; - return this; - } - - @Property() - private String paperNumber; - - @Property() - private String issuer; - - @Property() - private String issueDateTime; - - @Property() - private int faceValue; - - @Property() - private String maturityDateTime; - - @Property() - private String owner; - - public String getOwner() { - return owner; - } - - public CommercialPaper setOwner(String owner) { - this.owner = owner; - return this; - } - - public CommercialPaper() { - super(); - } - - public CommercialPaper setKey() { - this.key = State.makeKey(new String[] { this.paperNumber }); - return this; - } - - public String getPaperNumber() { - return paperNumber; - } - - public CommercialPaper setPaperNumber(String paperNumber) { - this.paperNumber = paperNumber; - return this; - } - - public String getIssuer() { - return issuer; - } - - public CommercialPaper setIssuer(String issuer) { - this.issuer = issuer; - return this; - } - - public String getIssueDateTime() { - return issueDateTime; - } - - public CommercialPaper setIssueDateTime(String issueDateTime) { - this.issueDateTime = issueDateTime; - return this; - } - - public int getFaceValue() { - return faceValue; - } - - public CommercialPaper setFaceValue(int faceValue) { - this.faceValue = faceValue; - return this; - } - - public String getMaturityDateTime() { - return maturityDateTime; - } - - public CommercialPaper setMaturityDateTime(String maturityDateTime) { - this.maturityDateTime = maturityDateTime; - return this; - } - - @Override - public String toString() { - return "Paper::" + this.key + " " + this.getPaperNumber() + " " + getIssuer() + " " + getFaceValue(); - } - - /** - * Deserialize a state data to commercial paper - * - * @param {Buffer} data to form back into the object - */ - public static CommercialPaper deserialize(byte[] data) { - JSONObject json = new JSONObject(new String(data, UTF_8)); - - String issuer = json.getString("issuer"); - String paperNumber = json.getString("paperNumber"); - String issueDateTime = json.getString("issueDateTime"); - String maturityDateTime = json.getString("maturityDateTime"); - String owner = json.getString("owner"); - int faceValue = json.getInt("faceValue"); - String state = json.getString("state"); - return createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, faceValue,owner,state); - } - - public static byte[] serialize(CommercialPaper paper) { - return State.serialize(paper); - } - - /** - * Factory method to create a commercial paper object - */ - public static CommercialPaper createInstance(String issuer, String paperNumber, String issueDateTime, - String maturityDateTime, int faceValue, String owner, String state) { - return new CommercialPaper().setIssuer(issuer).setPaperNumber(paperNumber).setMaturityDateTime(maturityDateTime) - .setFaceValue(faceValue).setKey().setIssueDateTime(issueDateTime).setOwner(owner).setState(state); - } - - -} diff --git a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContext.java b/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContext.java deleted file mode 100644 index 7a946f2f..00000000 --- a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContext.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.example; - -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.shim.ChaincodeStub; - -class CommercialPaperContext extends Context { - - public CommercialPaperContext(ChaincodeStub stub) { - super(stub); - this.paperList = new PaperList(this); - } - - public PaperList paperList; - -} \ No newline at end of file diff --git a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContract.java b/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContract.java deleted file mode 100644 index a46a7038..00000000 --- a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContract.java +++ /dev/null @@ -1,170 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ -package org.example; - -import java.util.logging.Logger; - -import org.example.ledgerapi.State; -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.contract.ContractInterface; -import org.hyperledger.fabric.contract.annotation.Contact; -import org.hyperledger.fabric.contract.annotation.Contract; -import org.hyperledger.fabric.contract.annotation.Default; -import org.hyperledger.fabric.contract.annotation.Info; -import org.hyperledger.fabric.contract.annotation.License; -import org.hyperledger.fabric.contract.annotation.Transaction; -import org.hyperledger.fabric.shim.ChaincodeStub; - -/** - * A custom context provides easy access to list of all commercial papers - */ - -/** - * Define commercial paper smart contract by extending Fabric Contract class - * - */ -@Contract(name = "org.papernet.commercialpaper", info = @Info(title = "MyAsset contract", description = "", version = "0.0.1", license = @License(name = "SPDX-License-Identifier: ", url = ""), contact = @Contact(email = "java-contract@example.com", name = "java-contract", url = "http://java-contract.me"))) -@Default -public class CommercialPaperContract implements ContractInterface { - - // use the classname for the logger, this way you can refactor - private final static Logger LOG = Logger.getLogger(CommercialPaperContract.class.getName()); - - @Override - public Context createContext(ChaincodeStub stub) { - return new CommercialPaperContext(stub); - } - - public CommercialPaperContract() { - - } - - /** - * Define a custom context for commercial paper - */ - - /** - * Instantiate to perform any setup of the ledger that might be required. - * - * @param {Context} ctx the transaction context - */ - @Transaction - public void instantiate(CommercialPaperContext ctx) { - // No implementation required with this example - // It could be where data migration is performed, if necessary - LOG.info("No data migration to perform"); - } - - /** - * Issue commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} issueDateTime paper issue date - * @param {String} maturityDateTime paper maturity date - * @param {Integer} faceValue face value of paper - */ - @Transaction - public CommercialPaper issue(CommercialPaperContext ctx, String issuer, String paperNumber, String issueDateTime, - String maturityDateTime, int faceValue) { - - System.out.println(ctx); - - // create an instance of the paper - CommercialPaper paper = CommercialPaper.createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, - faceValue,issuer,""); - - // Smart contract, rather than paper, moves paper into ISSUED state - paper.setIssued(); - - // Newly issued paper is owned by the issuer - paper.setOwner(issuer); - - System.out.println(paper); - // Add the paper to the list of all similar commercial papers in the ledger - // world state - ctx.paperList.addPaper(paper); - - // Must return a serialized paper to caller of smart contract - return paper; - } - - /** - * Buy commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} currentOwner current owner of paper - * @param {String} newOwner new owner of paper - * @param {Integer} price price paid for this paper - * @param {String} purchaseDateTime time paper was purchased (i.e. traded) - */ - @Transaction - public CommercialPaper buy(CommercialPaperContext ctx, String issuer, String paperNumber, String currentOwner, - String newOwner, int price, String purchaseDateTime) { - - // Retrieve the current paper using key fields provided - String paperKey = State.makeKey(new String[] { issuer, paperNumber }); - CommercialPaper paper = ctx.paperList.getPaper(paperKey); - - // Validate current owner - if (!paper.getOwner().equals(currentOwner)) { - throw new RuntimeException("Paper " + issuer + paperNumber + " is not owned by " + currentOwner); - } - - // First buy moves state from ISSUED to TRADING - if (paper.isIssued()) { - paper.setTrading(); - } - - // Check paper is not already REDEEMED - if (paper.isTrading()) { - paper.setOwner(newOwner); - } else { - throw new RuntimeException( - "Paper " + issuer + paperNumber + " is not trading. Current state = " + paper.getState()); - } - - // Update the paper - ctx.paperList.updatePaper(paper); - return paper; - } - - /** - * Redeem commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} redeemingOwner redeeming owner of paper - * @param {String} redeemDateTime time paper was redeemed - */ - @Transaction - public CommercialPaper redeem(CommercialPaperContext ctx, String issuer, String paperNumber, String redeemingOwner, - String redeemDateTime) { - - String paperKey = CommercialPaper.makeKey(new String[] { issuer, paperNumber }); - - CommercialPaper paper = ctx.paperList.getPaper(paperKey); - - // Check paper is not REDEEMED - if (paper.isRedeemed()) { - throw new RuntimeException("Paper " + issuer + paperNumber + " already redeemed"); - } - - // Verify that the redeemer owns the commercial paper before redeeming it - if (paper.getOwner().equals(redeemingOwner)) { - paper.setOwner(paper.getIssuer()); - paper.setRedeemed(); - } else { - throw new RuntimeException("Redeeming owner does not own paper" + issuer + paperNumber); - } - - ctx.paperList.updatePaper(paper); - return paper; - } - -} diff --git a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/PaperList.java b/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/PaperList.java deleted file mode 100644 index 0ecd24cd..00000000 --- a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/PaperList.java +++ /dev/null @@ -1,31 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package org.example; - -import org.example.ledgerapi.StateList; -import org.hyperledger.fabric.contract.Context; - -public class PaperList { - - private StateList stateList; - - public PaperList(Context ctx) { - this.stateList = StateList.getStateList(ctx, PaperList.class.getSimpleName(), CommercialPaper::deserialize); - } - - public PaperList addPaper(CommercialPaper paper) { - stateList.addState(paper); - return this; - } - - public CommercialPaper getPaper(String paperKey) { - return (CommercialPaper) this.stateList.getState(paperKey); - } - - public PaperList updatePaper(CommercialPaper paper) { - this.stateList.updateState(paper); - return this; - } -} diff --git a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/State.java b/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/State.java deleted file mode 100644 index 46d35c38..00000000 --- a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/State.java +++ /dev/null @@ -1,60 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ -package org.example.ledgerapi; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.json.JSONObject; - -/** - * State class. States have a class, unique key, and a lifecycle current state - * the current state is determined by the specific subclass - */ -public class State { - - protected String key; - - /** - * @param {String|Object} class An identifiable class of the instance - * @param {keyParts[]} elements to pull together to make a key for the objects - */ - public State() { - - } - - String getKey() { - return this.key; - } - - public String[] getSplitKey() { - return State.splitKey(this.key); - } - - /** - * Convert object to buffer containing JSON data serialization Typically used - * before putState()ledger API - * - * @param {Object} JSON object to serialize - * @return {buffer} buffer with the data to store - */ - public static byte[] serialize(Object object) { - String jsonStr = new JSONObject(object).toString(); - return jsonStr.getBytes(UTF_8); - } - - /** - * Join the keyParts to make a unififed string - * - * @param (String[]) keyParts - */ - public static String makeKey(String[] keyParts) { - return String.join(":", keyParts); - } - - public static String[] splitKey(String key) { - System.out.println("splitting key " + key + " " + java.util.Arrays.asList(key.split(":"))); - return key.split(":"); - } - -} diff --git a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/StateDeserializer.java b/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/StateDeserializer.java deleted file mode 100644 index 891788ea..00000000 --- a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/StateDeserializer.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.example.ledgerapi; - -@FunctionalInterface -public interface StateDeserializer { - State deserialize(byte[] buffer); -} diff --git a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/StateList.java b/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/StateList.java deleted file mode 100644 index d6725860..00000000 --- a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/StateList.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.example.ledgerapi; - -import org.example.ledgerapi.impl.StateListImpl; -import org.hyperledger.fabric.contract.Context; - -public interface StateList { - - /* - * SPDX-License-Identifier: Apache-2.0 - */ - - /** - * StateList provides a named virtual container for a set of ledger states. Each - * state has a unique key which associates it with the container, rather than - * the container containing a link to the state. This minimizes collisions for - * parallel transactions on different states. - */ - - /** - * Store Fabric context for subsequent API access, and name of list - */ - static StateList getStateList(Context ctx, String listName, StateDeserializer deserializer) { - return new StateListImpl(ctx, listName, deserializer); - } - - /** - * Add a state to the list. Creates a new state in worldstate with appropriate - * composite key. Note that state defines its own key. State object is - * serialized before writing. - */ - public StateList addState(State state); - - /** - * Get a state from the list using supplied keys. Form composite keys to - * retrieve state from world state. State data is deserialized into JSON object - * before being returned. - */ - public State getState(String key); - - /** - * Update a state in the list. Puts the new state in world state with - * appropriate composite key. Note that state defines its own key. A state is - * serialized before writing. Logic is very similar to addState() but kept - * separate becuase it is semantically distinct. - */ - public StateList updateState(State state); - -} diff --git a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/impl/StateListImpl.java b/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/impl/StateListImpl.java deleted file mode 100644 index 78a42933..00000000 --- a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/impl/StateListImpl.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.example.ledgerapi.impl; - -import java.util.Arrays; - -import org.example.ledgerapi.State; -import org.example.ledgerapi.StateDeserializer; -import org.example.ledgerapi.StateList; -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.shim.ChaincodeStub; -import org.hyperledger.fabric.shim.ledger.CompositeKey; - -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * StateList provides a named virtual container for a set of ledger states. Each - * state has a unique key which associates it with the container, rather than - * the container containing a link to the state. This minimizes collisions for - * parallel transactions on different states. - */ -public class StateListImpl implements StateList { - - private Context ctx; - private String name; - private Object supportedClasses; - private StateDeserializer deserializer; - - /** - * Store Fabric context for subsequent API access, and name of list - * - * @param deserializer - */ - public StateListImpl(Context ctx, String listName, StateDeserializer deserializer) { - this.ctx = ctx; - this.name = listName; - this.deserializer = deserializer; - - } - - /** - * Add a state to the list. Creates a new state in worldstate with appropriate - * composite key. Note that state defines its own key. State object is - * serialized before writing. - */ - @Override - public StateList addState(State state) { - System.out.println("Adding state " + this.name); - ChaincodeStub stub = this.ctx.getStub(); - System.out.println("Stub=" + stub); - String[] splitKey = state.getSplitKey(); - System.out.println("Split key " + Arrays.asList(splitKey)); - - CompositeKey ledgerKey = stub.createCompositeKey(this.name, splitKey); - System.out.println("ledgerkey is "); - System.out.println(ledgerKey); - - byte[] data = State.serialize(state); - System.out.println("ctx" + this.ctx); - System.out.println("stub" + this.ctx.getStub()); - this.ctx.getStub().putState(ledgerKey.toString(), data); - - return this; - } - - /** - * Get a state from the list using supplied keys. Form composite keys to - * retrieve state from world state. State data is deserialized into JSON object - * before being returned. - */ - @Override - public State getState(String key) { - - CompositeKey ledgerKey = this.ctx.getStub().createCompositeKey(this.name, State.splitKey(key)); - - byte[] data = this.ctx.getStub().getState(ledgerKey.toString()); - if (data != null) { - State state = this.deserializer.deserialize(data); - return state; - } else { - return null; - } - } - - /** - * Update a state in the list. Puts the new state in world state with - * appropriate composite key. Note that state defines its own key. A state is - * serialized before writing. Logic is very similar to addState() but kept - * separate becuase it is semantically distinct. - */ - @Override - public StateList updateState(State state) { - CompositeKey ledgerKey = this.ctx.getStub().createCompositeKey(this.name, state.getSplitKey()); - byte[] data = State.serialize(state); - this.ctx.getStub().putState(ledgerKey.toString(), data); - - return this; - } - -} diff --git a/commercial-paper/organization/digibank/contract/.editorconfig b/commercial-paper/organization/digibank/contract/.editorconfig deleted file mode 100755 index 75a13be2..00000000 --- a/commercial-paper/organization/digibank/contract/.editorconfig +++ /dev/null @@ -1,16 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -root = true - -[*] -indent_style = space -indent_size = 4 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.md] -trim_trailing_whitespace = false diff --git a/commercial-paper/organization/digibank/contract/.eslintignore b/commercial-paper/organization/digibank/contract/.eslintignore deleted file mode 100644 index 15958470..00000000 --- a/commercial-paper/organization/digibank/contract/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -coverage diff --git a/commercial-paper/organization/digibank/contract/.eslintrc.js b/commercial-paper/organization/digibank/contract/.eslintrc.js deleted file mode 100644 index 6772c660..00000000 --- a/commercial-paper/organization/digibank/contract/.eslintrc.js +++ /dev/null @@ -1,37 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -module.exports = { - env: { - node: true, - mocha: true - }, - parserOptions: { - ecmaVersion: 8, - sourceType: 'script' - }, - extends: "eslint:recommended", - rules: { - indent: ['error', 4], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], - 'no-unused-vars': ['error', { args: 'none' }], - 'no-console': 'off', - curly: 'error', - eqeqeq: 'error', - 'no-throw-literal': 'error', - strict: 'error', - 'no-var': 'error', - 'dot-notation': 'error', - 'no-tabs': 'error', - 'no-trailing-spaces': 'error', - 'no-use-before-define': 'error', - 'no-useless-call': 'error', - 'no-with': 'error', - 'operator-linebreak': 'error', - yoda: 'error', - 'quote-props': ['error', 'as-needed'] - } -}; diff --git a/commercial-paper/organization/digibank/contract/.npmignore b/commercial-paper/organization/digibank/contract/.npmignore deleted file mode 100644 index a00ca941..00000000 --- a/commercial-paper/organization/digibank/contract/.npmignore +++ /dev/null @@ -1,77 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# next.js build output -.next - -# nuxt.js build output -.nuxt - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless diff --git a/commercial-paper/organization/digibank/contract/index.js b/commercial-paper/organization/digibank/contract/index.js deleted file mode 100644 index e0ea2c7e..00000000 --- a/commercial-paper/organization/digibank/contract/index.js +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; - -const cpcontract = require('./lib/papercontract.js'); -module.exports.contracts = [cpcontract]; diff --git a/commercial-paper/organization/digibank/contract/ledger-api/state.js b/commercial-paper/organization/digibank/contract/ledger-api/state.js deleted file mode 100644 index f63e792e..00000000 --- a/commercial-paper/organization/digibank/contract/ledger-api/state.js +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; - -/** - * State class. States have a class, unique key, and a lifecycle current state - * the current state is determined by the specific subclass - */ -class State { - - /** - * @param {String|Object} class An indentifiable class of the instance - * @param {keyParts[]} elements to pull together to make a key for the objects - */ - constructor(stateClass, keyParts) { - this.class = stateClass; - this.key = State.makeKey(keyParts); - this.currentState = null; - } - - getClass() { - return this.class; - } - - getKey() { - return this.key; - } - - getSplitKey(){ - return State.splitKey(this.key); - } - - getCurrentState(){ - return this.currentState; - } - - // not used -/* serialize() { - - return State.serialize(this); - } */ - - /** - * Convert object to buffer containing JSON data serialization - * Typically used before putState()ledger API - * @param {Object} JSON object to serialize - * @return {buffer} buffer with the data to store - */ - static serialize(object) { - // don't write the key:value passed in - we already have a real composite key, issuer and paper Number. - delete object.key; - return Buffer.from(JSON.stringify(object)); - } - - /** - * Deserialize object into one of a set of supported JSON classes - * i.e. Covert serialized data to JSON object - * Typically used after getState() ledger API - * @param {data} data to deserialize into JSON object - * @param (supportedClasses) the set of classes data can be serialized to - * @return {json} json with the data to store - */ - static deserialize(data, supportedClasses) { - let json = JSON.parse(data.toString()); - let objClass = supportedClasses[json.class]; - if (!objClass) { - throw new Error(`Unknown class of ${json.class}`); - } - let object = new (objClass)(json); - - return object; - } - - /** - * Deserialize object into specific object class - * Typically used after getState() ledger API - * @param {data} data to deserialize into JSON object - * @return {json} json with the data to store - */ - static deserializeClass(data, objClass) { - let json = JSON.parse(data.toString()); - let object = new (objClass)(json); - return object; - } - - /** - * Join the keyParts to make a unififed string - * @param (String[]) keyParts - */ - static makeKey(keyParts) { - // return keyParts.map(part => JSON.stringify(part)).join(':'); - return keyParts.map(part => part).join(':'); - } - - static splitKey(key){ - return key.split(':'); - } - -} - -module.exports = State; diff --git a/commercial-paper/organization/digibank/contract/ledger-api/statelist.js b/commercial-paper/organization/digibank/contract/ledger-api/statelist.js deleted file mode 100644 index 15ec8370..00000000 --- a/commercial-paper/organization/digibank/contract/ledger-api/statelist.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; -const State = require('./state.js'); - -/** - * StateList provides a named virtual container for a set of ledger states. - * Each state has a unique key which associates it with the container, rather - * than the container containing a link to the state. This minimizes collisions - * for parallel transactions on different states. - */ -class StateList { - - /** - * Store Fabric context for subsequent API access, and name of list - */ - constructor(ctx, listName) { - this.ctx = ctx; - this.name = listName; - this.supportedClasses = {}; - - } - - /** - * Add a state to the list. Creates a new state in worldstate with - * appropriate composite key. Note that state defines its own key. - * State object is serialized before writing. - */ - async addState(state) { - let key = this.ctx.stub.createCompositeKey(this.name, state.getSplitKey()); - let data = State.serialize(state); - await this.ctx.stub.putState(key, data); - } - - /** - * Get a state from the list using supplied keys. Form composite - * keys to retrieve state from world state. State data is deserialized - * into JSON object before being returned. - */ - async getState(key) { - let ledgerKey = this.ctx.stub.createCompositeKey(this.name, State.splitKey(key)); - let data = await this.ctx.stub.getState(ledgerKey); - if (data && data.toString('utf8')) { - let state = State.deserialize(data, this.supportedClasses); - return state; - } else { - return null; - } - } - - /** - * Update a state in the list. Puts the new state in world state with - * appropriate composite key. Note that state defines its own key. - * A state is serialized before writing. Logic is very similar to - * addState() but kept separate becuase it is semantically distinct. - */ - async updateState(state) { - let key = this.ctx.stub.createCompositeKey(this.name, state.getSplitKey()); - let data = State.serialize(state); - await this.ctx.stub.putState(key, data); - } - - /** Stores the class for future deserialization */ - use(stateClass) { - this.supportedClasses[stateClass.getClass()] = stateClass; - } - -} - -module.exports = StateList; diff --git a/commercial-paper/organization/digibank/contract/lib/paper.js b/commercial-paper/organization/digibank/contract/lib/paper.js deleted file mode 100644 index 0629ba71..00000000 --- a/commercial-paper/organization/digibank/contract/lib/paper.js +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; - -// Utility class for ledger state -const State = require('./../ledger-api/state.js'); - -// Enumerate commercial paper state values -const cpState = { - ISSUED: 1, - PENDING: 2, - TRADING: 3, - REDEEMED: 4 -}; - -/** - * CommercialPaper class extends State class - * Class will be used by application and smart contract to define a paper - */ -class CommercialPaper extends State { - - constructor(obj) { - super(CommercialPaper.getClass(), [obj.issuer, obj.paperNumber]); - Object.assign(this, obj); - } - - /** - * Basic getters and setters - */ - getIssuer() { - return this.issuer; - } - - setIssuer(newIssuer) { - this.issuer = newIssuer; - } - - getOwner() { - return this.owner; - } - - setOwnerMSP(mspid) { - this.mspid = mspid; - } - - getOwnerMSP() { - return this.mspid; - } - - setOwner(newOwner) { - this.owner = newOwner; - } - - /** - * Useful methods to encapsulate commercial paper states - */ - setIssued() { - this.currentState = cpState.ISSUED; - } - - setTrading() { - this.currentState = cpState.TRADING; - } - - setRedeemed() { - this.currentState = cpState.REDEEMED; - } - - setPending() { - this.currentState = cpState.PENDING; - } - - isIssued() { - return this.currentState === cpState.ISSUED; - } - - isTrading() { - return this.currentState === cpState.TRADING; - } - - isRedeemed() { - return this.currentState === cpState.REDEEMED; - } - - isPending() { - return this.currentState === cpState.PENDING; - } - - static fromBuffer(buffer) { - return CommercialPaper.deserialize(buffer); - } - - toBuffer() { - return Buffer.from(JSON.stringify(this)); - } - - /** - * Deserialize a state data to commercial paper - * @param {Buffer} data to form back into the object - */ - static deserialize(data) { - return State.deserializeClass(data, CommercialPaper); - } - - /** - * Factory method to create a commercial paper object - */ - static createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, faceValue) { - return new CommercialPaper({ issuer, paperNumber, issueDateTime, maturityDateTime, faceValue }); - } - - static getClass() { - return 'org.papernet.commercialpaper'; - } -} - -module.exports = CommercialPaper; diff --git a/commercial-paper/organization/digibank/contract/lib/papercontract.js b/commercial-paper/organization/digibank/contract/lib/papercontract.js deleted file mode 100644 index c3d2cdb4..00000000 --- a/commercial-paper/organization/digibank/contract/lib/papercontract.js +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; - -// Fabric smart contract classes -const { Contract, Context } = require('fabric-contract-api'); - -// PaperNet specifc classes -const CommercialPaper = require('./paper.js'); -const PaperList = require('./paperlist.js'); -const QueryUtils = require('./queries.js'); - -/** - * A custom context provides easy access to list of all commercial papers - */ -class CommercialPaperContext extends Context { - - constructor() { - super(); - // All papers are held in a list of papers - this.paperList = new PaperList(this); - } - -} - -/** - * Define commercial paper smart contract by extending Fabric Contract class - * - */ -class CommercialPaperContract extends Contract { - - constructor() { - // Unique namespace when multiple contracts per chaincode file - super('org.papernet.commercialpaper'); - } - - /** - * Define a custom context for commercial paper - */ - createContext() { - return new CommercialPaperContext(); - } - - /** - * Instantiate to perform any setup of the ledger that might be required. - * @param {Context} ctx the transaction context - */ - async instantiate(ctx) { - // No implementation required with this example - // It could be where data migration is performed, if necessary - console.log('Instantiate the contract'); - } - - /** - * Issue commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} issueDateTime paper issue date - * @param {String} maturityDateTime paper maturity date - * @param {Integer} faceValue face value of paper - */ - async issue(ctx, issuer, paperNumber, issueDateTime, maturityDateTime, faceValue) { - - // create an instance of the paper - let paper = CommercialPaper.createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, parseInt(faceValue)); - - // Smart contract, rather than paper, moves paper into ISSUED state - paper.setIssued(); - - // save the owner's MSP - let mspid = ctx.clientIdentity.getMSPID(); - paper.setOwnerMSP(mspid); - - // Newly issued paper is owned by the issuer to begin with (recorded for reporting purposes) - paper.setOwner(issuer); - - // Add the paper to the list of all similar commercial papers in the ledger world state - await ctx.paperList.addPaper(paper); - - // Must return a serialized paper to caller of smart contract - return paper; - } - - /** - * Buy commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} currentOwner current owner of paper - * @param {String} newOwner new owner of paper - * @param {Integer} price price paid for this paper // transaction input - not written to asset - * @param {String} purchaseDateTime time paper was purchased (i.e. traded) // transaction input - not written to asset - */ - async buy(ctx, issuer, paperNumber, currentOwner, newOwner, price, purchaseDateTime) { - - // Retrieve the current paper using key fields provided - let paperKey = CommercialPaper.makeKey([issuer, paperNumber]); - let paper = await ctx.paperList.getPaper(paperKey); - - // Validate current owner - if (paper.getOwner() !== currentOwner) { - throw new Error('\nPaper ' + issuer + paperNumber + ' is not owned by ' + currentOwner); - } - - // First buy moves state from ISSUED to TRADING (when running ) - if (paper.isIssued()) { - paper.setTrading(); - } - - // Check paper is not already REDEEMED - if (paper.isTrading()) { - paper.setOwner(newOwner); - // save the owner's MSP - let mspid = ctx.clientIdentity.getMSPID(); - paper.setOwnerMSP(mspid); - } else { - throw new Error('\nPaper ' + issuer + paperNumber + ' is not trading. Current state = ' + paper.getCurrentState()); - } - - // Update the paper - await ctx.paperList.updatePaper(paper); - return paper; - } - - /** - * Buy request: (2-phase confirmation: Commercial paper is 'PENDING' subject to completion of transfer by owning org) - * Alternative to 'buy' transaction - * Note: 'buy_request' puts paper in 'PENDING' state - subject to transfer confirmation [below]. - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} currentOwner current owner of paper - * @param {String} newOwner new owner of paper // transaction input - not written to asset per se - but written to block - * @param {Integer} price price paid for this paper // transaction input - not written to asset per se - but written to block - * @param {String} purchaseDateTime time paper was requested // transaction input - ditto. - */ - async buy_request(ctx, issuer, paperNumber, currentOwner, newOwner, price, purchaseDateTime) { - - - // Retrieve the current paper using key fields provided - let paperKey = CommercialPaper.makeKey([issuer, paperNumber]); - let paper = await ctx.paperList.getPaper(paperKey); - - // Validate current owner - this is really information for the user trying the sample, rather than any 'authorisation' check per se FYI - if (paper.getOwner() !== currentOwner) { - throw new Error('\nPaper ' + issuer + paperNumber + ' is not owned by ' + currentOwner + ' provided as a paraneter'); - } - // paper set to 'PENDING' - can only be transferred (confirmed) by identity from owning org (MSP check). - paper.setPending(); - - // Update the paper - await ctx.paperList.updatePaper(paper); - return paper; - } - - /** - * transfer commercial paper: only the owning org has authority to execute. It is the complement to the 'buy_request' transaction. '[]' is optional below. - * eg. issue -> buy_request -> transfer -> [buy ...n | [buy_request...n | transfer ...n] ] -> redeem - * this transaction 'pair' is an alternative to the straight issue -> buy -> [buy....n] -> redeem ...path - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} newOwner new owner of paper - * @param {String} newOwnerMSP MSP id of the transferee - * @param {String} confirmDateTime confirmed transfer date. - */ - async transfer(ctx, issuer, paperNumber, newOwner, newOwnerMSP, confirmDateTime) { - - // Retrieve the current paper using key fields provided - let paperKey = CommercialPaper.makeKey([issuer, paperNumber]); - let paper = await ctx.paperList.getPaper(paperKey); - - // Validate current owner's MSP in the paper === invoking transferor's MSP id - can only transfer if you are the owning org. - - if (paper.getOwnerMSP() !== ctx.clientIdentity.getMSPID()) { - throw new Error('\nPaper ' + issuer + paperNumber + ' is not owned by the current invoking Organisation, and not authorised to transfer'); - } - - // Paper needs to be 'pending' - which means you need to have run 'buy_pending' transaction first. - if ( ! paper.isPending()) { - throw new Error('\nPaper ' + issuer + paperNumber + ' is not currently in state: PENDING for transfer to occur: \n must run buy_request transaction first'); - } - // else all good - - paper.setOwner(newOwner); - // set the MSP of the transferee (so that, that org may also pass MSP check, if subsequently transferred/sold on) - paper.setOwnerMSP(newOwnerMSP); - paper.setTrading(); - paper.confirmDateTime = confirmDateTime; - - // Update the paper - await ctx.paperList.updatePaper(paper); - return paper; - } - - /** - * Redeem commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} redeemingOwner redeeming owner of paper - * @param {String} issuingOwnerMSP the MSP of the org that the paper will be redeemed with. - * @param {String} redeemDateTime time paper was redeemed - */ - async redeem(ctx, issuer, paperNumber, redeemingOwner, issuingOwnerMSP, redeemDateTime) { - - let paperKey = CommercialPaper.makeKey([issuer, paperNumber]); - - let paper = await ctx.paperList.getPaper(paperKey); - - // Check paper is not alread in a state of REDEEMED - if (paper.isRedeemed()) { - throw new Error('\nPaper ' + issuer + paperNumber + ' has already been redeemed'); - } - - // Validate current redeemer's MSP matches the invoking redeemer's MSP id - can only redeem if you are the owning org. - - if (paper.getOwnerMSP() !== ctx.clientIdentity.getMSPID()) { - throw new Error('\nPaper ' + issuer + paperNumber + ' cannot be redeemed by ' + ctx.clientIdentity.getMSPID() + ', as it is not the authorised owning Organisation'); - } - - // As this is just a sample, can show additional verification check: that the redeemer provided matches that on record, before redeeming it - if (paper.getOwner() === redeemingOwner) { - paper.setOwner(paper.getIssuer()); - paper.setOwnerMSP(issuingOwnerMSP); - paper.setRedeemed(); - paper.redeemDateTime = redeemDateTime; // record redemption date against the asset (the complement to 'issue date') - } else { - throw new Error('\nRedeeming owner: ' + redeemingOwner + ' organisation does not currently own paper: ' + issuer + paperNumber); - } - - await ctx.paperList.updatePaper(paper); - return paper; - } - - // Query transactions - - /** - * Query history of a commercial paper - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - */ - async queryHistory(ctx, issuer, paperNumber) { - - // Get a key to be used for History query - - let query = new QueryUtils(ctx, 'org.papernet.paper'); - let results = await query.getAssetHistory(issuer, paperNumber); // (cpKey); - return results; - - } - - /** - * queryOwner commercial paper: supply name of owning org, to find list of papers based on owner field - * @param {Context} ctx the transaction context - * @param {String} owner commercial paper owner - */ - async queryOwner(ctx, owner) { - - let query = new QueryUtils(ctx, 'org.papernet.paper'); - let owner_results = await query.queryKeyByOwner(owner); - - return owner_results; - } - - /** - * queryPartial commercial paper - provide a prefix eg. "DigiBank" will list all papers _issued_ by DigiBank etc etc - * @param {Context} ctx the transaction context - * @param {String} prefix asset class prefix (added to paperlist namespace) eg. org.papernet.paperMagnetoCorp asset listing: papers issued by MagnetoCorp. - */ - async queryPartial(ctx, prefix) { - - let query = new QueryUtils(ctx, 'org.papernet.paper'); - let partial_results = await query.queryKeyByPartial(prefix); - - return partial_results; - } - - /** - * queryAdHoc commercial paper - supply a custom mango query - * eg - as supplied as a param: - * ex1: ["{\"selector\":{\"faceValue\":{\"$lt\":8000000}}}"] - * ex2: ["{\"selector\":{\"faceValue\":{\"$gt\":4999999}}}"] - * - * @param {Context} ctx the transaction context - * @param {String} queryString querystring - */ - async queryAdhoc(ctx, queryString) { - - let query = new QueryUtils(ctx, 'org.papernet.paper'); - let querySelector = JSON.parse(queryString); - let adhoc_results = await query.queryByAdhoc(querySelector); - - return adhoc_results; - } - - - /** - * queryNamed - supply named query - 'case' statement chooses selector to build (pre-canned for demo purposes) - * @param {Context} ctx the transaction context - * @param {String} queryname the 'named' query (built here) - or - the adHoc query string, provided as a parameter - */ - async queryNamed(ctx, queryname) { - let querySelector = {}; - switch (queryname) { - case "redeemed": - querySelector = { "selector": { "currentState": 4 } }; // 4 = redeemd state - break; - case "trading": - querySelector = { "selector": { "currentState": 3 } }; // 3 = trading state - break; - case "value": - // may change to provide as a param - fixed value for now in this sample - querySelector = { "selector": { "faceValue": { "$gt": 4000000 } } }; // to test, issue CommPapers with faceValue <= or => this figure. - break; - default: // else, unknown named query - throw new Error('invalid named query supplied: ' + queryname + '- please try again '); - } - - let query = new QueryUtils(ctx, 'org.papernet.paper'); - let adhoc_results = await query.queryByAdhoc(querySelector); - - return adhoc_results; - } - -} - -module.exports = CommercialPaperContract; diff --git a/commercial-paper/organization/digibank/contract/lib/paperlist.js b/commercial-paper/organization/digibank/contract/lib/paperlist.js deleted file mode 100644 index 73528b61..00000000 --- a/commercial-paper/organization/digibank/contract/lib/paperlist.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; - -// Utility class for collections of ledger states -- a state list -const StateList = require('./../ledger-api/statelist.js'); - -const CommercialPaper = require('./paper.js'); - -class PaperList extends StateList { - - constructor(ctx) { - super(ctx, 'org.papernet.paper'); - this.use(CommercialPaper); - } - - async addPaper(paper) { - return this.addState(paper); - } - - async getPaper(paperKey) { - return this.getState(paperKey); - } - - async updatePaper(paper) { - return this.updateState(paper); - } -} - - -module.exports = PaperList; diff --git a/commercial-paper/organization/digibank/contract/lib/queries.js b/commercial-paper/organization/digibank/contract/lib/queries.js deleted file mode 100644 index f0a73a51..00000000 --- a/commercial-paper/organization/digibank/contract/lib/queries.js +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; - -const State = require('../ledger-api/state.js'); -//const CommercialPaper = require('./paper.js'); -/** - * Query Class for query functions such as history etc - * - */ -class QueryUtils { - - constructor(ctx, listName) { - this.ctx = ctx; - this.name = listName; - //this.supportedTypes = {}; - } - - // ========================================================================================= - // getAssetHistory takes the composite key as arg, gets returns results as JSON to 'main contract' - // ========================================================================================= - /** - * Get Asset History for a commercial paper - * @param {String} issuer the CP issuer - * @param {String} paperNumber commercial paper number - */ - async getAssetHistory(issuer, paperNumber) { - - let ledgerKey = await this.ctx.stub.createCompositeKey(this.name, [issuer, paperNumber]); - const resultsIterator = await this.ctx.stub.getHistoryForKey(ledgerKey); - let results = await this.getAllResults(resultsIterator, true); - - return results; - } - - // =========================================================================================== - // queryKeyByPartial performs a partial query based on the namespace and asset key prefix provided - - // Read-only function results are not typically submitted to ordering. If the read-only - // results are submitted to ordering, or if the query is used in an update transaction - // and submitted to ordering, then the committing peers will re-execute to guarantee that - // result sets are stable between endorsement time and commit time. The transaction is - // invalidated by the committing peers if the result set has changed between endorsement - // time and commit time. - // - // =========================================================================================== - /** - * queryOwner commercial paper - * @param {String} assetspace the asset space (eg MagnetoCorp's assets) - */ - async queryKeyByPartial(assetspace) { - - if (arguments.length < 1) { - throw new Error('Incorrect number of arguments. Expecting 1'); - } - // ie namespace + prefix to assets etc eg - // "Key":"org.papernet.paperMagnetoCorp0001" (0002, etc) - // "Partial":'org.papernet.paperlistMagnetoCorp"' (using partial key, find keys "0001", "0002" etc) - const resultsIterator = await this.ctx.stub.getStateByPartialCompositeKey(this.name, [assetspace]); - let method = this.getAllResults; - let results = await method(resultsIterator, false); - - return results; - } - - - // ===== Example: Parameterized rich query ================================================= - // queryKeyByOwner queries for assets based on a passed in owner. - // This is an example of a parameterized query accepting a single query parameter (owner). - // Only available on state databases that support rich query (e.g. CouchDB) - // ========================================================================================= - /** - * queryKeyByOwner commercial paper - * @param {String} owner commercial paper owner - */ - async queryKeyByOwner(owner) { - // - let self = this; - if (arguments.length < 1) { - throw new Error('Incorrect number of arguments. Expecting owner name.'); - } - let queryString = {}; - queryString.selector = {}; - // queryString.selector.docType = 'indexOwnerDoc'; - queryString.selector.owner = owner; - // set to (eg) '{selector:{owner:MagnetoCorp}}' - let method = self.getQueryResultForQueryString; - let queryResults = await method(this.ctx, self, JSON.stringify(queryString)); - return queryResults; - } - - // ===== Example: Ad hoc rich query ======================================================== - // queryAdhoc uses a query string to perform a query for marbles.. - // Query string matching state database syntax is passed in and executed as is. - // Supports ad hoc queries that can be defined at runtime by the client. - // If this is not desired, follow the queryKeyByOwner example for parameterized queries. - // Only available on state databases that support rich query (e.g. CouchDB) - // example passed using VS Code ext: ["{\"selector\": {\"owner\": \"MagnetoCorp\"}}"] - // ========================================================================================= - /** - * query By AdHoc string (commercial paper) - * @param {String} queryString actual MangoDB query string (escaped) - */ - async queryByAdhoc(queryString) { - - if (arguments.length < 1) { - throw new Error('Incorrect number of arguments. Expecting ad-hoc string, which gets stringified for mango query'); - } - let self = this; - - if (!queryString) { - throw new Error('queryString must not be empty'); - } - let method = self.getQueryResultForQueryString; - let queryResults = await method(this.ctx, self, JSON.stringify(queryString)); - return queryResults; - } - - // WORKER functions are below this line: these are called by the above functions, where iterator is passed in - - // ========================================================================================= - // getQueryResultForQueryString woerk function executes the passed-in query string. - // Result set is built and returned as a byte array containing the JSON results. - // ========================================================================================= - /** - * Function getQueryResultForQueryString - * @param {Context} ctx the transaction context - * @param {any} self within scope passed in - * @param {String} the query string created prior to calling this fn - */ - async getQueryResultForQueryString(ctx, self, queryString) { - - // console.log('- getQueryResultForQueryString queryString:\n' + queryString); - - const resultsIterator = await ctx.stub.getQueryResult(queryString); - let results = await self.getAllResults(resultsIterator, false); - - return results; - - } - - /** - * Function getAllResults - * @param {resultsIterator} iterator within scope passed in - * @param {Boolean} isHistory query string created prior to calling this fn - */ - async getAllResults(iterator, isHistory) { - let allResults = []; - let res = { done: false, value: null }; - - while (true) { - res = await iterator.next(); - let jsonRes = {}; - if (res.value && res.value.value.toString()) { - if (isHistory && isHistory === true) { - //jsonRes.TxId = res.value.tx_id; - jsonRes.TxId = res.value.txId; - jsonRes.Timestamp = res.value.timestamp; - jsonRes.Timestamp = new Date((res.value.timestamp.seconds.low * 1000)); - let ms = res.value.timestamp.nanos / 1000000; - jsonRes.Timestamp.setMilliseconds(ms); - if (res.value.is_delete) { - jsonRes.IsDelete = res.value.is_delete.toString(); - } else { - try { - jsonRes.Value = JSON.parse(res.value.value.toString('utf8')); - // report the commercial paper states during the asset lifecycle, just for asset history reporting - switch (jsonRes.Value.currentState) { - case 1: - jsonRes.Value.currentState = 'ISSUED'; - break; - case 2: - jsonRes.Value.currentState = 'PENDING'; - break; - case 3: - jsonRes.Value.currentState = 'TRADING'; - break; - case 4: - jsonRes.Value.currentState = 'REDEEMED'; - break; - default: // else, unknown named query - jsonRes.Value.currentState = 'UNKNOWN'; - } - - } catch (err) { - console.log(err); - jsonRes.Value = res.value.value.toString('utf8'); - } - } - } else { // non history query .. - jsonRes.Key = res.value.key; - try { - jsonRes.Record = JSON.parse(res.value.value.toString('utf8')); - } catch (err) { - console.log(err); - jsonRes.Record = res.value.value.toString('utf8'); - } - } - allResults.push(jsonRes); - } - // check to see if we have reached the end - if (res.done) { - // explicitly close the iterator - console.log('iterator is done'); - await iterator.close(); - return allResults; - } - - } // while true - } - -} -module.exports = QueryUtils; diff --git a/commercial-paper/organization/digibank/contract/package.json b/commercial-paper/organization/digibank/contract/package.json deleted file mode 100644 index 2c4a6449..00000000 --- a/commercial-paper/organization/digibank/contract/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "papernet-js", - "version": "0.0.1", - "description": "Papernet Contract", - "main": "index.js", - "engines": { - "node": ">=8", - "npm": ">=5" - }, - "scripts": { - "lint": "eslint .", - "pretest": "npm run lint", - "test": "nyc mocha test --recursive", - "start": "fabric-chaincode-node start", - "mocha": "mocha test --recursive" - }, - "engineStrict": true, - "author": "hyperledger", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "^2.0.0", - "fabric-shim": "^2.0.0" - }, - "devDependencies": { - "chai": "^4.1.2", - "chai-as-promised": "^7.1.1", - "eslint": "^4.19.1", - "mocha": "^5.2.0", - "nyc": "^12.0.2", - "sinon": "^6.0.0", - "sinon-chai": "^3.2.0" - }, - "nyc": { - "exclude": [ - "coverage/**", - "test/**" - ], - "reporter": [ - "text-summary", - "html" - ], - "all": true, - "check-coverage": true, - "statements": 100, - "branches": 100, - "functions": 100, - "lines": 100 - } -} diff --git a/commercial-paper/organization/digibank/contract/test/contract.js b/commercial-paper/organization/digibank/contract/test/contract.js deleted file mode 100644 index 63576eed..00000000 --- a/commercial-paper/organization/digibank/contract/test/contract.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ -'use strict'; - -const Chaincode = require('../lib/chaincode'); -const { Stub } = require('fabric-shim'); - -require('chai').should(); -const sinon = require('sinon'); - -describe('Chaincode', () => { - - describe('#Init', () => { - - it('should work', async () => { - const cc = new Chaincode(); - const stub = sinon.createStubInstance(Stub); - stub.getFunctionAndParameters.returns({ fcn: 'initFunc', params: [] }); - const res = await cc.Init(stub); - res.status.should.equal(Stub.RESPONSE_CODE.OK); - }); - - }); - - describe('#Invoke', async () => { - - it('should work', async () => { - const cc = new Chaincode(); - const stub = sinon.createStubInstance(Stub); - stub.getFunctionAndParameters.returns({ fcn: 'initFunc', params: [] }); - let res = await cc.Init(stub); - res.status.should.equal(Stub.RESPONSE_CODE.OK); - stub.getFunctionAndParameters.returns({ fcn: 'invokeFunc', params: [] }); - res = await cc.Invoke(stub); - res.status.should.equal(Stub.RESPONSE_CODE.OK); - }); - - }); - -}); diff --git a/commercial-paper/organization/digibank/digibank.sh b/commercial-paper/organization/digibank/digibank.sh deleted file mode 100755 index 1b977b12..00000000 --- a/commercial-paper/organization/digibank/digibank.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: Apache-2.0 -# -TMPFILE=`mktemp` -shopt -s extglob - -function _exit(){ - printf "Exiting:%s\n" "$1" - exit -1 -} - -: ${CHANNEL_NAME:="mychannel"} -: ${DELAY:="3"} -: ${MAX_RETRY:="5"} -: ${VERBOSE:="false"} - -# Where am I? -DIR=${PWD} - -# Locate the test network -cd "${DIR}/../../../test-network" -env | sort > $TMPFILE - -OVERRIDE_ORG="1" -. ./scripts/envVar.sh - -parsePeerConnectionParameters 1 2 - -# set the fabric config path -export FABRIC_CFG_PATH="${DIR}/../../../config" -export PATH="${DIR}/../../../bin:${PWD}:$PATH" - -env | sort | comm -1 -3 $TMPFILE - | sed -E 's/(.*)=(.*)/export \1="\2"/' - -rm $TMPFILE - -cd "${DIR}" diff --git a/commercial-paper/organization/digibank/gateway/.gitkeep b/commercial-paper/organization/digibank/gateway/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/commercial-paper/organization/magnetocorp/.gitignore b/commercial-paper/organization/magnetocorp/.gitignore deleted file mode 100644 index 7d139014..00000000 --- a/commercial-paper/organization/magnetocorp/.gitignore +++ /dev/null @@ -1 +0,0 @@ -identity \ No newline at end of file diff --git a/commercial-paper/organization/magnetocorp/application-java/.gitignore b/commercial-paper/organization/magnetocorp/application-java/.gitignore deleted file mode 100644 index 2f7896d1..00000000 --- a/commercial-paper/organization/magnetocorp/application-java/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target/ diff --git a/commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.core.resources.prefs b/commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 7a531392..00000000 --- a/commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,3 +0,0 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 -encoding/src=UTF-8 diff --git a/commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.m2e.core.prefs b/commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f1..00000000 --- a/commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/commercial-paper/organization/magnetocorp/application-java/pom.xml b/commercial-paper/organization/magnetocorp/application-java/pom.xml deleted file mode 100644 index 71cd8e10..00000000 --- a/commercial-paper/organization/magnetocorp/application-java/pom.xml +++ /dev/null @@ -1,96 +0,0 @@ - - 4.0.0 - commercial-paper - commercial-paper - 0.0.1-SNAPSHOT - - - - - 1.8 - UTF-8 - UTF-8 - - - 2.1.0 - - 2.1.0 - - - - - src - - - maven-compiler-plugin - 3.8.0 - - 1.8 - 1.8 - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.0 - - - - package - - shade - - - - - false - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - - - - - - jitpack.io - https://jitpack.io - - - - - - org.hyperledger.fabric - fabric-gateway-java - ${fabric-gateway-java.version} - - - - - org.hyperledger.fabric-chaincode-java - fabric-chaincode-shim - ${fabric-chaincode-java.version} - compile - - - - - org.json - json - 20180813 - - - - diff --git a/commercial-paper/organization/magnetocorp/application-java/src/org/magnetocorp/AddToWallet.java b/commercial-paper/organization/magnetocorp/application-java/src/org/magnetocorp/AddToWallet.java deleted file mode 100644 index 36d0c1f4..00000000 --- a/commercial-paper/organization/magnetocorp/application-java/src/org/magnetocorp/AddToWallet.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package org.magnetocorp; - -import java.io.IOException; -import java.io.Reader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.InvalidKeyException; -import java.security.PrivateKey; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import org.hyperledger.fabric.gateway.Identities; -import org.hyperledger.fabric.gateway.Wallet; -import org.hyperledger.fabric.gateway.Wallets; -import org.hyperledger.fabric.gateway.Identity; - -public class AddToWallet { - - private static X509Certificate readX509Certificate(final Path certificatePath) throws IOException, CertificateException { - try (Reader certificateReader = Files.newBufferedReader(certificatePath, StandardCharsets.UTF_8)) { - return Identities.readX509Certificate(certificateReader); - } - } - - private static PrivateKey getPrivateKey(final Path privateKeyPath) throws IOException, InvalidKeyException { - try (Reader privateKeyReader = Files.newBufferedReader(privateKeyPath, StandardCharsets.UTF_8)) { - return Identities.readPrivateKey(privateKeyReader); - } - } - - public static void main(String[] args) { - try { - // A wallet stores a collection of identities - Path walletPath = Paths.get(".", "wallet"); - Wallet wallet = Wallets.newFileSystemWallet(walletPath); - - Path credentialPath = Paths.get("..", "..", "..",".." ,"test-network", "organizations", - "peerOrganizations", "org2.example.com", "users", "User1@org2.example.com", "msp"); - System.out.println("credentialPath: " + credentialPath.toString()); - Path certificatePath = credentialPath.resolve(Paths.get("signcerts", - "User1@org2.example.com-cert.pem")); - System.out.println("certificatePem: " + certificatePath.toString()); - Path privateKeyPath = credentialPath.resolve(Paths.get("keystore", - "priv_sk")); - - X509Certificate certificate = readX509Certificate(certificatePath); - PrivateKey privateKey = getPrivateKey(privateKeyPath); - - Identity identity = Identities.newX509Identity("Org2MSP", certificate, privateKey); - - - String identityLabel = "User1@org2.example.com"; - wallet.put(identityLabel, identity); - - System.out.println("Write wallet info into " + walletPath.toString() + " successfully."); - - } catch (IOException | CertificateException | InvalidKeyException e) { - System.err.println("Error adding to wallet"); - e.printStackTrace(); - } - } - -} \ No newline at end of file diff --git a/commercial-paper/organization/magnetocorp/application-java/src/org/magnetocorp/Issue.java b/commercial-paper/organization/magnetocorp/application-java/src/org/magnetocorp/Issue.java deleted file mode 100644 index cdc268ed..00000000 --- a/commercial-paper/organization/magnetocorp/application-java/src/org/magnetocorp/Issue.java +++ /dev/null @@ -1,75 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package org.magnetocorp; - -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Map; -import java.util.concurrent.TimeoutException; - -import org.hyperledger.fabric.gateway.Contract; -import org.hyperledger.fabric.gateway.Gateway; -import org.hyperledger.fabric.gateway.GatewayException; -import org.hyperledger.fabric.gateway.Network; -import org.hyperledger.fabric.gateway.Wallet; -import org.hyperledger.fabric.gateway.Wallets; -import org.papernet.CommercialPaper; - -public class Issue { - - private static final String ENVKEY="CONTRACT_NAME"; - - public static void main(String[] args) { - - String contractName="papercontract"; - // get the name of the contract, in case it is overridden - Map envvar = System.getenv(); - if (envvar.containsKey(ENVKEY)){ - contractName=envvar.get(ENVKEY); - } - - Gateway.Builder builder = Gateway.createBuilder(); - - try { - // A wallet stores a collection of identities - Path walletPath = Paths.get(".", "wallet"); - Wallet wallet = Wallets.newFileSystemWallet(walletPath); - System.out.println("Read wallet info from: " + walletPath.toString()); - - String userName = "User1@org2.example.com"; - - Path connectionProfile = Paths.get("..", "gateway", "connection-org2.yaml"); - - // Set connection options on the gateway builder - builder.identity(wallet, userName).networkConfig(connectionProfile).discovery(false); - - // Connect to gateway using application specified parameters - try(Gateway gateway = builder.connect()) { - - // Access PaperNet network - System.out.println("Use network channel: mychannel."); - Network network = gateway.getNetwork("mychannel"); - - // Get addressability to commercial paper contract - System.out.println("Use org.papernet.commercialpaper smart contract."); - Contract contract = network.getContract(contractName, "org.papernet.commercialpaper"); - - // Issue commercial paper - System.out.println("Submit commercial paper issue transaction."); - byte[] response = contract.submitTransaction("issue", "MagnetoCorp", "00001", "2020-05-31", "2020-11-30", "5000000"); - - // Process response - System.out.println("Process issue transaction response."); - CommercialPaper paper = CommercialPaper.deserialize(response); - System.out.println(paper); - } - } catch (GatewayException | IOException | TimeoutException | InterruptedException e) { - e.printStackTrace(); - System.exit(-1); - } - } - -} \ No newline at end of file diff --git a/commercial-paper/organization/magnetocorp/application-java/src/org/papernet/CommercialPaper.java b/commercial-paper/organization/magnetocorp/application-java/src/org/papernet/CommercialPaper.java deleted file mode 100644 index e1397e46..00000000 --- a/commercial-paper/organization/magnetocorp/application-java/src/org/papernet/CommercialPaper.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.papernet; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.hyperledger.fabric.contract.annotation.DataType; -import org.hyperledger.fabric.contract.annotation.Property; -import org.json.JSONObject; -import org.json.JSONPropertyIgnore; -import org.papernet.ledgerapi.State; - -@DataType() -public class CommercialPaper extends State { - - // Enumerate commercial paper state values - public final static String ISSUED = "ISSUED"; - public final static String TRADING = "TRADING"; - public final static String REDEEMED = "REDEEMED"; - public final static String[] STATES = new String[] {ISSUED, TRADING, REDEEMED}; - - @Property() - private String state=""; - - public String getState() { - return state; - } - - public CommercialPaper setState(String state) { - this.state = state; - return this; - } - - @JSONPropertyIgnore() - public boolean isIssued() { - return this.state.equals(CommercialPaper.ISSUED); - } - - @JSONPropertyIgnore() - public boolean isTrading() { - return this.state.equals(CommercialPaper.TRADING); - } - - @JSONPropertyIgnore() - public boolean isRedeemed() { - return this.state.equals(CommercialPaper.REDEEMED); - } - - public CommercialPaper setIssued() { - this.state = CommercialPaper.ISSUED; - return this; - } - - public CommercialPaper setTrading() { - this.state = CommercialPaper.TRADING; - return this; - } - - public CommercialPaper setRedeemed() { - this.state = CommercialPaper.REDEEMED; - return this; - } - - @Property() - private String paperNumber; - - @Property() - private String issuer; - - @Property() - private String issueDateTime; - - @Property() - private int faceValue; - - @Property() - private String maturityDateTime; - - @Property() - private String owner; - - public String getOwner() { - return owner; - } - - public CommercialPaper setOwner(String owner) { - this.owner = owner; - return this; - } - - public CommercialPaper() { - super(); - } - - public CommercialPaper setKey() { - this.key = State.makeKey(new String[] { this.paperNumber }); - return this; - } - - public String getPaperNumber() { - return paperNumber; - } - - public CommercialPaper setPaperNumber(String paperNumber) { - this.paperNumber = paperNumber; - return this; - } - - public String getIssuer() { - return issuer; - } - - public CommercialPaper setIssuer(String issuer) { - this.issuer = issuer; - return this; - } - - public String getIssueDateTime() { - return issueDateTime; - } - - public CommercialPaper setIssueDateTime(String issueDateTime) { - this.issueDateTime = issueDateTime; - return this; - } - - public int getFaceValue() { - return faceValue; - } - - public CommercialPaper setFaceValue(int faceValue) { - this.faceValue = faceValue; - return this; - } - - public String getMaturityDateTime() { - return maturityDateTime; - } - - public CommercialPaper setMaturityDateTime(String maturityDateTime) { - this.maturityDateTime = maturityDateTime; - return this; - } - - @Override - public String toString() { - return "Paper::" + this.key + " " + this.getPaperNumber() + " " + getIssuer() + " " + getFaceValue(); - } - - /** - * Deserialize a state data to commercial paper - * - * @param {Buffer} data to form back into the object - */ - public static CommercialPaper deserialize(byte[] data) { - JSONObject json = new JSONObject(new String(data, UTF_8)); - - String issuer = json.getString("issuer"); - String paperNumber = json.getString("paperNumber"); - String issueDateTime = json.getString("issueDateTime"); - String maturityDateTime = json.getString("maturityDateTime"); - String owner = json.getString("owner"); - int faceValue = json.getInt("faceValue"); - int currentState = json.getInt("currentState"); - String state = STATES[currentState-1]; - return createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, faceValue, owner, state); - } - - public static byte[] serialize(CommercialPaper paper) { - return State.serialize(paper); - } - - /** - * Factory method to create a commercial paper object - */ - public static CommercialPaper createInstance(String issuer, String paperNumber, String issueDateTime, - String maturityDateTime, int faceValue, String owner, String state) { - return new CommercialPaper().setIssuer(issuer).setPaperNumber(paperNumber).setMaturityDateTime(maturityDateTime) - .setFaceValue(faceValue).setKey().setIssueDateTime(issueDateTime).setOwner(issuer).setState(state); - } - - -} diff --git a/commercial-paper/organization/magnetocorp/application-java/src/org/papernet/ledgerapi/State.java b/commercial-paper/organization/magnetocorp/application-java/src/org/papernet/ledgerapi/State.java deleted file mode 100644 index a32abc02..00000000 --- a/commercial-paper/organization/magnetocorp/application-java/src/org/papernet/ledgerapi/State.java +++ /dev/null @@ -1,60 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ -package org.papernet.ledgerapi; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.json.JSONObject; - -/** - * State class. States have a class, unique key, and a lifecycle current state - * the current state is determined by the specific subclass - */ -public class State { - - protected String key; - - /** - * @param {String|Object} class An identifiable class of the instance - * @param {keyParts[]} elements to pull together to make a key for the objects - */ - public State() { - - } - - String getKey() { - return this.key; - } - - public String[] getSplitKey() { - return State.splitKey(this.key); - } - - /** - * Convert object to buffer containing JSON data serialization Typically used - * before putState()ledger API - * - * @param {Object} JSON object to serialize - * @return {buffer} buffer with the data to store - */ - public static byte[] serialize(Object object) { - String jsonStr = new JSONObject(object).toString(); - return jsonStr.getBytes(UTF_8); - } - - /** - * Join the keyParts to make a unififed string - * - * @param (String[]) keyParts - */ - public static String makeKey(String[] keyParts) { - return String.join(":", keyParts); - } - - public static String[] splitKey(String key) { - System.out.println("splitting key " + key + " " + java.util.Arrays.asList(key.split(":"))); - return key.split(":"); - } - -} diff --git a/commercial-paper/organization/magnetocorp/application/.eslintrc.js b/commercial-paper/organization/magnetocorp/application/.eslintrc.js deleted file mode 100644 index 22fbefc8..00000000 --- a/commercial-paper/organization/magnetocorp/application/.eslintrc.js +++ /dev/null @@ -1,37 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -module.exports = { - env: { - node: true, - mocha: true - }, - parserOptions: { - ecmaVersion: 8, - sourceType: 'script' - }, - extends: "eslint:recommended", - rules: { - indent: ['error', 4], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], - 'no-unused-vars': ['error', { args: 'none' }], - 'no-console': 'off', - curly: 'error', - eqeqeq: 'error', - 'no-throw-literal': 'error', - strict: 'error', - 'no-var': 'error', - 'dot-notation': 'error', - 'no-tabs': 'error', - 'no-trailing-spaces': 'error', - 'no-use-before-define': 'error', - 'no-useless-call': 'error', - 'no-with': 'error', - 'operator-linebreak': 'error', - yoda: 'error', - 'quote-props': ['error', 'as-needed'] - } -}; \ No newline at end of file diff --git a/commercial-paper/organization/magnetocorp/application/.gitignore b/commercial-paper/organization/magnetocorp/application/.gitignore deleted file mode 100644 index b512c09d..00000000 --- a/commercial-paper/organization/magnetocorp/application/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file diff --git a/commercial-paper/organization/magnetocorp/application/addToWallet.js b/commercial-paper/organization/magnetocorp/application/addToWallet.js deleted file mode 100644 index eb491238..00000000 --- a/commercial-paper/organization/magnetocorp/application/addToWallet.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -// Bring key classes into scope, most importantly Fabric SDK network class -const fs = require('fs'); -const { Wallets } = require('fabric-network'); -const path = require('path'); - -const fixtures = path.resolve(__dirname, '../../../../test-network'); - -async function main() { - - // Main try/catch block - try { - // A wallet stores a collection of identities - const wallet = await Wallets.newFileSystemWallet('../identity/user/isabella/wallet'); - - // Identity to credentials to be stored in the wallet - const credPath = path.join(fixtures, '/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com'); - const certificate = fs.readFileSync(path.join(credPath, '/msp/signcerts/User1@org2.example.com-cert.pem')).toString(); - const privateKey = fs.readFileSync(path.join(credPath, '/msp/keystore/priv_sk')).toString(); - - // Load credentials into wallet - const identityLabel = 'isabella'; - - const identity = { - credentials: { - certificate, - privateKey - }, - mspId: 'Org2MSP', - type: 'X.509' - } - - - await wallet.put(identityLabel,identity); - - } catch (error) { - console.log(`Error adding to wallet. ${error}`); - console.log(error.stack); - } -} - -main().then(() => { - console.log('done'); -}).catch((e) => { - console.log(e); - console.log(e.stack); - process.exit(-1); -}); diff --git a/commercial-paper/organization/magnetocorp/application/cpListener.js b/commercial-paper/organization/magnetocorp/application/cpListener.js deleted file mode 100644 index 1c62cbda..00000000 --- a/commercial-paper/organization/magnetocorp/application/cpListener.js +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -"use strict"; - -const yaml = require('js-yaml'); -const { Wallets, Gateway } = require('fabric-network'); -const path = require("path"); -const fs = require("fs"); - -let finished; -async function main() { - try { - // Set up the wallet - just use Org2's wallet (isabella) - const wallet = await Wallets.newFileSystemWallet('../identity/user/isabella/wallet'); - - // Create a new gateway for connecting to our peer node. - const gateway = new Gateway(); - - const userName = 'isabella'; - - // Load connection profile; will be used to locate a gateway - let connectionProfile = yaml.safeLoad(fs.readFileSync('../gateway/connection-org2.yaml', 'utf8')); - - // Set connection options; identity and wallet - let connectionOptions = { - identity: userName, - wallet: wallet, - discovery: { enabled:true, asLocalhost: true } - }; - - // connect to the gateway - await gateway.connect(connectionProfile, connectionOptions); - // get the channel and smart contract - const network = await gateway.getNetwork('mychannel'); - - // Listen for blocks being added, display relevant contents: in particular, the transaction inputs - finished = false; - - const listener = async (event) => { - if (event.blockData !== undefined) { - for (const i in event.blockData.data.data) { - if (event.blockData.data.data[i].payload.data.actions !== undefined) { - const inputArgs = event.blockData.data.data[i].payload.data.actions[0].payload.chaincode_proposal_payload.input.chaincode_spec.input.args; - // Print block details - console.log('----------'); - console.log('Block:', parseInt(event.blockData.header.number), 'transaction', i); - // Show ID and timestamp of the transaction - const tx_id = event.blockData.data.data[i].payload.header.channel_header.tx_id; - const txTime = new Date(event.blockData.data.data[i].payload.header.channel_header.timestamp).toUTCString(); - // Show ID, date and time of transaction - console.log('Transaction ID:', tx_id); - console.log('Timestamp:', txTime); - // Show transaction inputs (formatted, as may contain binary data) - let inputData = 'Inputs: '; - for (let j = 0; j < inputArgs.length; j++) { - const inputArgPrintable = inputArgs[j].toString().replace(/[^\x20-\x7E]+/g, ''); - inputData = inputData.concat(inputArgPrintable, ' '); - } - console.log(inputData); - // Show the proposed writes to the world state - let keyData = 'Keys updated: '; - for (const l in event.blockData.data.data[i].payload.data.actions[0].payload.action.proposal_response_payload.extension.results.ns_rwset[1].rwset.writes) { - // add a ' ' space between multiple keys in 'concat' - keyData = keyData.concat(event.blockData.data.data[i].payload.data.actions[0].payload.action.proposal_response_payload.extension.results.ns_rwset[1].rwset.writes[l].key, ' '); - } - console.log(keyData); - // Show which organizations endorsed - let endorsers = 'Endorsers: '; - for (const k in event.blockData.data.data[i].payload.data.actions[0].payload.action.endorsements) { - endorsers = endorsers.concat(event.blockData.data.data[i].payload.data.actions[0].payload.action.endorsements[k].endorser.mspid, ' '); - } - console.log(endorsers); - // Was the transaction valid or not? - // (Invalid transactions are still logged on the blockchain but don't affect the world state) - if ((event.blockData.metadata.metadata[2])[i] !== 0) { - console.log('INVALID TRANSACTION'); - } - } - } - } - }; - const options = { - type: 'full', - startBlock: 1 - }; - await network.addBlockListener(listener, options); - while (!finished) { - await new Promise(resolve => setTimeout(resolve, 5000)); - // Disconnect from the gateway after Promise is resolved. - // ... do other things - } - gateway.disconnect(); - } - catch (error) { - console.error('Error: ', error); - process.exit(1); - } -} -void main(); diff --git a/commercial-paper/organization/magnetocorp/application/enrollUser.js b/commercial-paper/organization/magnetocorp/application/enrollUser.js deleted file mode 100644 index bb673f08..00000000 --- a/commercial-paper/organization/magnetocorp/application/enrollUser.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const FabricCAServices = require('fabric-ca-client'); -const { Wallets } = require('fabric-network'); -const fs = require('fs'); -const yaml = require('js-yaml'); -const path = require('path'); - -async function main() { - try { - // load the network configuration - let connectionProfile = yaml.safeLoad(fs.readFileSync('../gateway/connection-org2.yaml', 'utf8')); - - // Create a new CA client for interacting with the CA. - const caInfo = connectionProfile.certificateAuthorities['ca.org2.example.com']; - const caTLSCACerts = caInfo.tlsCACerts.pem; - const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName); - - // Create a new file system based wallet for managing identities. - const walletPath = path.join(process.cwd(), '../identity/user/isabella/wallet'); - const wallet = await Wallets.newFileSystemWallet(walletPath); - console.log(`Wallet path: ${walletPath}`); - - // Check to see if we've already enrolled the admin user. - const userExists = await wallet.get('isabella'); - if (userExists) { - console.log('An identity for the client user "user1" already exists in the wallet'); - return; - } - - // Enroll the admin user, and import the new identity into the wallet. - const enrollment = await ca.enroll({ enrollmentID: 'user1', enrollmentSecret: 'user1pw' }); - const x509Identity = { - credentials: { - certificate: enrollment.certificate, - privateKey: enrollment.key.toBytes(), - }, - mspId: 'Org2MSP', - type: 'X.509', - }; - await wallet.put('isabella', x509Identity); - console.log('Successfully enrolled client user "isabella" and imported it into the wallet'); - - } catch (error) { - console.error(`Failed to enroll client user "isabella": ${error}`); - process.exit(1); - } -} - -main(); diff --git a/commercial-paper/organization/magnetocorp/application/issue.js b/commercial-paper/organization/magnetocorp/application/issue.js deleted file mode 100644 index 2d44fce3..00000000 --- a/commercial-paper/organization/magnetocorp/application/issue.js +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -/* - * This application has 6 basic steps: - * 1. Select an identity from a wallet - * 2. Connect to network gateway - * 3. Access PaperNet network - * 4. Construct request to issue commercial paper - * 5. Submit transaction - * 6. Process response - */ - -'use strict'; - -// Bring key classes into scope, most importantly Fabric SDK network class -const fs = require('fs'); -const yaml = require('js-yaml'); -const { Wallets, Gateway } = require('fabric-network'); -const CommercialPaper = require('../contract/lib/paper.js'); - -// Main program function -async function main() { - - // A wallet stores a collection of identities for use - const wallet = await Wallets.newFileSystemWallet('../identity/user/isabella/wallet'); - - // A gateway defines the peers used to access Fabric networks - const gateway = new Gateway(); - - // Main try/catch block - try { - - // Specify userName for network access - // const userName = 'isabella.issuer@magnetocorp.com'; - const userName = 'isabella'; - - // Load connection profile; will be used to locate a gateway - let connectionProfile = yaml.safeLoad(fs.readFileSync('../gateway/connection-org2.yaml', 'utf8')); - - // Set connection options; identity and wallet - let connectionOptions = { - identity: userName, - wallet: wallet, - discovery: { enabled:true, asLocalhost: true } - }; - - // Connect to gateway using application specified parameters - console.log('Connect to Fabric gateway.'); - - await gateway.connect(connectionProfile, connectionOptions); - - // Access PaperNet network - console.log('Use network channel: mychannel.'); - - const network = await gateway.getNetwork('mychannel'); - - // Get addressability to commercial paper contract - console.log('Use org.papernet.commercialpaper smart contract.'); - - const contract = await network.getContract('papercontract'); - - // issue commercial paper - console.log('Submit commercial paper issue transaction.'); - - const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000'); - - // process response - console.log('Process issue transaction response.'+issueResponse); - - let paper = CommercialPaper.fromBuffer(issueResponse); - - console.log(`${paper.issuer} commercial paper : ${paper.paperNumber} successfully issued for value ${paper.faceValue}`); - console.log('Transaction complete.'); - - } catch (error) { - - console.log(`Error processing transaction. ${error}`); - console.log(error.stack); - - } finally { - - // Disconnect from the gateway - console.log('Disconnect from Fabric gateway.'); - gateway.disconnect(); - - } -} -main().then(() => { - - console.log('Issue program complete.'); - -}).catch((e) => { - - console.log('Issue program exception.'); - console.log(e); - console.log(e.stack); - process.exit(-1); - -}); diff --git a/commercial-paper/organization/magnetocorp/application/package.json b/commercial-paper/organization/magnetocorp/application/package.json deleted file mode 100644 index f8fac560..00000000 --- a/commercial-paper/organization/magnetocorp/application/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "nodejs", - "version": "1.0.0", - "description": "", - "main": "issue.js", - "scripts": { - "test": "rm -rf _idwallet && node addToWallet.js && node issue.js" - }, - "keywords": [], - "author": "", - "license": "Apache-2.0", - "dependencies": { - "fabric-network": "^2.2.4", - "fabric-ca-client": "^2.2.4", - "js-yaml": "^3.12.0" - }, - "devDependencies": { - "eslint": "^5.6.0" - } -} diff --git a/commercial-paper/organization/magnetocorp/application/transfer.js b/commercial-paper/organization/magnetocorp/application/transfer.js deleted file mode 100644 index 908903ab..00000000 --- a/commercial-paper/organization/magnetocorp/application/transfer.js +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -/* - * This application has 6 basic steps: - * 1. Select an identity from a wallet - * 2. Connect to network gateway - * 3. Access PaperNet network - * 4. Construct request to transfer commercial paper - * 5. Submit transaction - * 6. Process response - */ - -'use strict'; - -// Bring key classes into scope, most importantly Fabric SDK network class -const fs = require('fs'); -const yaml = require('js-yaml'); -const { Wallets, Gateway } = require('fabric-network'); -const CommercialPaper = require('../contract/lib/paper.js'); - -// Main program function -async function main() { - - // A wallet stores a collection of identities for use - const wallet = await Wallets.newFileSystemWallet('../identity/user/isabella/wallet'); - - // A gateway defines the peers used to access Fabric networks - const gateway = new Gateway(); - - // Main try/catch block - try { - - // Specify userName for network access - // const userName = 'isabella.issuer@magnetocorp.com'; - const userName = 'isabella'; - - // Load connection profile; will be used to locate a gateway - let connectionProfile = yaml.safeLoad(fs.readFileSync('../gateway/connection-org2.yaml', 'utf8')); - - // Set connection options; identity and wallet - let connectionOptions = { - identity: userName, - wallet: wallet, - discovery: { enabled:true, asLocalhost: true } - }; - - // Connect to gateway using application specified parameters - console.log('Connect to Fabric gateway.'); - - await gateway.connect(connectionProfile, connectionOptions); - - // Access PaperNet network - console.log('Use network channel: mychannel.'); - - const network = await gateway.getNetwork('mychannel'); - - // Get addressability to commercial paper contract - console.log('Use org.papernet.commercialpaper smart contract.'); - - const contract = await network.getContract('papercontract'); - - // transfer commercial paper - console.log('Submit commercial paper transfer transaction.'); - - const transferResponse = await contract.submitTransaction('transfer', 'MagnetoCorp', '00001', 'DigiBank', 'Org1MSP', '2020-06-01'); - - // process response - console.log('Process transfer transaction response.'+ transferResponse); - - let paper = CommercialPaper.fromBuffer(transferResponse); - - console.log(`commercial paper issued by ${paper.issuer} : ${paper.paperNumber} was successfully transferred`); - console.log('Transaction complete.'); - - } catch (error) { - - console.log(`Error processing transaction. ${error}`); - console.log(error.stack); - - } finally { - - // Disconnect from the gateway - console.log('Disconnect from Fabric gateway.'); - gateway.disconnect(); - - } -} -main().then(() => { - - console.log('Transfer program complete.'); - -}).catch((e) => { - - console.log('Transfer program exception.'); - console.log(e); - console.log(e.stack); - process.exit(-1); - -}); diff --git a/commercial-paper/organization/magnetocorp/configuration/cli/docker-compose.yml b/commercial-paper/organization/magnetocorp/configuration/cli/docker-compose.yml deleted file mode 100644 index cdbc0511..00000000 --- a/commercial-paper/organization/magnetocorp/configuration/cli/docker-compose.yml +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright IBM Corp All Rights Reserved -# -# SPDX-License-Identifier: Apache-2.0 -# -version: '2' - -networks: - basic: - external: - name: fabric_test - -services: - cliMagnetoCorp: - container_name: cliMagnetoCorp - image: hyperledger/fabric-tools:2.0.0-beta - tty: true - environment: - - GOPATH=/opt/gopath - - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - - FABRIC_LOGGING_SPEC=info - - CORE_PEER_ID=cli - - CORE_PEER_ADDRESS=peer0.org2.example.com:9051 - - CORE_PEER_LOCALMSPID=Org2MSP - - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp - - CORE_CHAINCODE_KEEPALIVE=10 - - CORE_PEER_TLS_ENABLED=true - - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt - - ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem - working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer - command: /bin/bash - volumes: - - /var/run/docker.sock:/host/var/run/docker.sock - - ./../../../../organization/magnetocorp:/opt/gopath/src/github.com/ - - ./../../../../../test-network/organizations:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ - networks: - - test diff --git a/commercial-paper/organization/magnetocorp/configuration/cli/monitordocker.sh b/commercial-paper/organization/magnetocorp/configuration/cli/monitordocker.sh deleted file mode 100755 index 6f8ba0e4..00000000 --- a/commercial-paper/organization/magnetocorp/configuration/cli/monitordocker.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# This script uses the logspout and http stream tools to let you watch the docker containers -# in action. -# -# More information at https://github.com/gliderlabs/logspout/tree/master/httpstream - -if [ -z "$1" ]; then - DOCKER_NETWORK=fabric_test -else - DOCKER_NETWORK="$1" -fi - -if [ -z "$2" ]; then - PORT=8000 -else - PORT="$2" -fi - -echo Starting monitoring on all containers on the network ${DOCKER_NETWORK} - -docker kill logspout 2> /dev/null 1>&2 || true -docker rm logspout 2> /dev/null 1>&2 || true - -docker run -d --name="logspout" \ - --volume=/var/run/docker.sock:/var/run/docker.sock \ - --publish=127.0.0.1:${PORT}:80 \ - --network ${DOCKER_NETWORK} \ - gliderlabs/logspout -sleep 3 -curl http://127.0.0.1:${PORT}/logs diff --git a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paper.go b/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paper.go deleted file mode 100644 index 7eecdf45..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paper.go +++ /dev/null @@ -1,139 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "encoding/json" - "fmt" - - ledgerapi "github.com/hyperledger/fabric-samples/commercial-paper/organization/magnetocorp/contract-go/ledger-api" -) - -// State enum for commercial paper state property -type State uint - -const ( - // ISSUED state for when a paper has been issued - ISSUED State = iota + 1 - // TRADING state for when a paper is trading - TRADING - // REDEEMED state for when a paper has been redeemed - REDEEMED -) - -func (state State) String() string { - names := []string{"ISSUED", "TRADING", "REDEEMED"} - - if state < ISSUED || state > REDEEMED { - return "UNKNOWN" - } - - return names[state-1] -} - -// CreateCommercialPaperKey creates a key for commercial papers -func CreateCommercialPaperKey(issuer string, paperNumber string) string { - return ledgerapi.MakeKey(issuer, paperNumber) -} - -// Used for managing the fact status is private but want it in world state -type commercialPaperAlias CommercialPaper -type jsonCommercialPaper struct { - *commercialPaperAlias - State State `json:"currentState"` - Class string `json:"class"` - Key string `json:"key"` -} - -// CommercialPaper defines a commercial paper -type CommercialPaper struct { - PaperNumber string `json:"paperNumber"` - Issuer string `json:"issuer"` - IssueDateTime string `json:"issueDateTime"` - FaceValue int `json:"faceValue"` - MaturityDateTime string `json:"maturityDateTime"` - Owner string `json:"owner"` - state State `metadata:"currentState"` - class string `metadata:"class"` - key string `metadata:"key"` -} - -// UnmarshalJSON special handler for managing JSON marshalling -func (cp *CommercialPaper) UnmarshalJSON(data []byte) error { - jcp := jsonCommercialPaper{commercialPaperAlias: (*commercialPaperAlias)(cp)} - - err := json.Unmarshal(data, &jcp) - - if err != nil { - return err - } - - cp.state = jcp.State - - return nil -} - -// MarshalJSON special handler for managing JSON marshalling -func (cp CommercialPaper) MarshalJSON() ([]byte, error) { - jcp := jsonCommercialPaper{commercialPaperAlias: (*commercialPaperAlias)(&cp), State: cp.state, Class: "org.papernet.commercialpaper", Key: ledgerapi.MakeKey(cp.Issuer, cp.PaperNumber)} - - return json.Marshal(&jcp) -} - -// GetState returns the state -func (cp *CommercialPaper) GetState() State { - return cp.state -} - -// SetIssued returns the state to issued -func (cp *CommercialPaper) SetIssued() { - cp.state = ISSUED -} - -// SetTrading sets the state to trading -func (cp *CommercialPaper) SetTrading() { - cp.state = TRADING -} - -// SetRedeemed sets the state to redeemed -func (cp *CommercialPaper) SetRedeemed() { - cp.state = REDEEMED -} - -// IsIssued returns true if state is issued -func (cp *CommercialPaper) IsIssued() bool { - return cp.state == ISSUED -} - -// IsTrading returns true if state is trading -func (cp *CommercialPaper) IsTrading() bool { - return cp.state == TRADING -} - -// IsRedeemed returns true if state is redeemed -func (cp *CommercialPaper) IsRedeemed() bool { - return cp.state == REDEEMED -} - -// GetSplitKey returns values which should be used to form key -func (cp *CommercialPaper) GetSplitKey() []string { - return []string{cp.Issuer, cp.PaperNumber} -} - -// Serialize formats the commercial paper as JSON bytes -func (cp *CommercialPaper) Serialize() ([]byte, error) { - return json.Marshal(cp) -} - -// Deserialize formats the commercial paper from JSON bytes -func Deserialize(bytes []byte, cp *CommercialPaper) error { - err := json.Unmarshal(bytes, cp) - - if err != nil { - return fmt.Errorf("Error deserializing commercial paper. %s", err.Error()) - } - - return nil -} diff --git a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paper_test.go b/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paper_test.go deleted file mode 100644 index 07c888bf..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paper_test.go +++ /dev/null @@ -1,125 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "testing" - - ledgerapi "github.com/hyperledger/fabric-samples/commercial-paper/organization/magnetocorp/contract-go/ledger-api" - "github.com/stretchr/testify/assert" -) - -func TestString(t *testing.T) { - assert.Equal(t, "ISSUED", ISSUED.String(), "should return string for issued") - assert.Equal(t, "TRADING", TRADING.String(), "should return string for issued") - assert.Equal(t, "REDEEMED", REDEEMED.String(), "should return string for issued") - assert.Equal(t, "UNKNOWN", State(REDEEMED+1).String(), "should return unknown when not one of constants") -} - -func TestCreateCommercialPaperKey(t *testing.T) { - assert.Equal(t, ledgerapi.MakeKey("someissuer", "somepaper"), CreateCommercialPaperKey("someissuer", "somepaper"), "should return key comprised of passed values") -} - -func TestGetState(t *testing.T) { - cp := new(CommercialPaper) - cp.state = ISSUED - - assert.Equal(t, ISSUED, cp.GetState(), "should return set state") -} - -func TestSetIssued(t *testing.T) { - cp := new(CommercialPaper) - cp.SetIssued() - assert.Equal(t, ISSUED, cp.state, "should set state to trading") -} - -func TestSetTrading(t *testing.T) { - cp := new(CommercialPaper) - cp.SetTrading() - assert.Equal(t, TRADING, cp.state, "should set state to trading") -} - -func TestSetRedeemed(t *testing.T) { - cp := new(CommercialPaper) - cp.SetRedeemed() - assert.Equal(t, REDEEMED, cp.state, "should set state to trading") -} - -func TestIsIssued(t *testing.T) { - cp := new(CommercialPaper) - - cp.SetIssued() - assert.True(t, cp.IsIssued(), "should be true when status set to issued") - - cp.SetTrading() - assert.False(t, cp.IsIssued(), "should be false when status not set to issued") -} - -func TestIsTrading(t *testing.T) { - cp := new(CommercialPaper) - - cp.SetTrading() - assert.True(t, cp.IsTrading(), "should be true when status set to trading") - - cp.SetRedeemed() - assert.False(t, cp.IsTrading(), "should be false when status not set to trading") -} - -func TestIsRedeemed(t *testing.T) { - cp := new(CommercialPaper) - - cp.SetRedeemed() - assert.True(t, cp.IsRedeemed(), "should be true when status set to redeemed") - - cp.SetIssued() - assert.False(t, cp.IsRedeemed(), "should be false when status not set to redeemed") -} - -func TestGetSplitKey(t *testing.T) { - cp := new(CommercialPaper) - cp.PaperNumber = "somepaper" - cp.Issuer = "someissuer" - - assert.Equal(t, []string{"someissuer", "somepaper"}, cp.GetSplitKey(), "should return issuer and paper number as split key") -} - -func TestSerialize(t *testing.T) { - cp := new(CommercialPaper) - cp.PaperNumber = "somepaper" - cp.Issuer = "someissuer" - cp.IssueDateTime = "sometime" - cp.FaceValue = 1000 - cp.MaturityDateTime = "somelatertime" - cp.Owner = "someowner" - cp.state = TRADING - - bytes, err := cp.Serialize() - assert.Nil(t, err, "should not error on serialize") - assert.Equal(t, `{"paperNumber":"somepaper","issuer":"someissuer","issueDateTime":"sometime","faceValue":1000,"maturityDateTime":"somelatertime","owner":"someowner","currentState":2,"class":"org.papernet.commercialpaper","key":"someissuer:somepaper"}`, string(bytes), "should return JSON formatted value") -} - -func TestDeserialize(t *testing.T) { - var cp *CommercialPaper - var err error - - goodJSON := `{"paperNumber":"somepaper","issuer":"someissuer","issueDateTime":"sometime","faceValue":1000,"maturityDateTime":"somelatertime","owner":"someowner","currentState":2,"class":"org.papernet.commercialpaper","key":"someissuer:somepaper"}` - expectedCp := new(CommercialPaper) - expectedCp.PaperNumber = "somepaper" - expectedCp.Issuer = "someissuer" - expectedCp.IssueDateTime = "sometime" - expectedCp.FaceValue = 1000 - expectedCp.MaturityDateTime = "somelatertime" - expectedCp.Owner = "someowner" - expectedCp.state = TRADING - cp = new(CommercialPaper) - err = Deserialize([]byte(goodJSON), cp) - assert.Nil(t, err, "should not return error for deserialize") - assert.Equal(t, expectedCp, cp, "should create expected commercial paper") - - badJSON := `{"paperNumber":"somepaper","issuer":"someissuer","issueDateTime":"sometime","faceValue":"NaN","maturityDateTime":"somelatertime","owner":"someowner","currentState":2,"class":"org.papernet.commercialpaper","key":"someissuer:somepaper"}` - cp = new(CommercialPaper) - err = Deserialize([]byte(badJSON), cp) - assert.EqualError(t, err, "Error deserializing commercial paper. json: cannot unmarshal string into Go struct field jsonCommercialPaper.faceValue of type int", "should return error for bad data") -} diff --git a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontext.go b/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontext.go deleted file mode 100644 index c346cf3b..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontext.go +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "github.com/hyperledger/fabric-contract-api-go/contractapi" -) - -// TransactionContextInterface an interface to -// describe the minimum required functions for -// a transaction context in the commercial -// paper -type TransactionContextInterface interface { - contractapi.TransactionContextInterface - GetPaperList() ListInterface -} - -// TransactionContext implementation of -// TransactionContextInterface for use with -// commercial paper contract -type TransactionContext struct { - contractapi.TransactionContext - paperList *list -} - -// GetPaperList return paper list -func (tc *TransactionContext) GetPaperList() ListInterface { - if tc.paperList == nil { - tc.paperList = newList(tc) - } - - return tc.paperList -} diff --git a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontext_test.go b/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontext_test.go deleted file mode 100644 index 7ffc90fb..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontext_test.go +++ /dev/null @@ -1,31 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "testing" - - ledgerapi "github.com/hyperledger/fabric-samples/commercial-paper/organization/magnetocorp/contract-go/ledger-api" - "github.com/stretchr/testify/assert" -) - -func TestGetPaperList(t *testing.T) { - var tc *TransactionContext - var expectedPaperList *list - - tc = new(TransactionContext) - expectedPaperList = newList(tc) - actualList := tc.GetPaperList().(*list) - assert.Equal(t, expectedPaperList.stateList.(*ledgerapi.StateList).Name, actualList.stateList.(*ledgerapi.StateList).Name, "should configure paper list when one not already configured") - - tc = new(TransactionContext) - expectedPaperList = new(list) - expectedStateList := new(ledgerapi.StateList) - expectedStateList.Ctx = tc - expectedStateList.Name = "existing paper list" - expectedPaperList.stateList = expectedStateList - tc.paperList = expectedPaperList - assert.Equal(t, expectedPaperList, tc.GetPaperList(), "should return set paper list when already set") -} diff --git a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontract.go b/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontract.go deleted file mode 100644 index 4e8cee20..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontract.go +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "fmt" - - "github.com/hyperledger/fabric-contract-api-go/contractapi" -) - -// Contract chaincode that defines -// the business logic for managing commercial -// paper -type Contract struct { - contractapi.Contract -} - -// Instantiate does nothing -func (c *Contract) Instantiate() { - fmt.Println("Instantiated") -} - -// Issue creates a new commercial paper and stores it in the world state -func (c *Contract) Issue(ctx TransactionContextInterface, issuer string, paperNumber string, issueDateTime string, maturityDateTime string, faceValue int) (*CommercialPaper, error) { - paper := CommercialPaper{PaperNumber: paperNumber, Issuer: issuer, IssueDateTime: issueDateTime, FaceValue: faceValue, MaturityDateTime: maturityDateTime, Owner: issuer} - paper.SetIssued() - - err := ctx.GetPaperList().AddPaper(&paper) - - if err != nil { - return nil, err - } - - return &paper, nil -} - -// Buy updates a commercial paper to be in trading status and sets the new owner -func (c *Contract) Buy(ctx TransactionContextInterface, issuer string, paperNumber string, currentOwner string, newOwner string, price int, purchaseDateTime string) (*CommercialPaper, error) { - paper, err := ctx.GetPaperList().GetPaper(issuer, paperNumber) - - if err != nil { - return nil, err - } - - if paper.Owner != currentOwner { - return nil, fmt.Errorf("Paper %s:%s is not owned by %s", issuer, paperNumber, currentOwner) - } - - if paper.IsIssued() { - paper.SetTrading() - } - - if !paper.IsTrading() { - return nil, fmt.Errorf("Paper %s:%s is not trading. Current state = %s", issuer, paperNumber, paper.GetState()) - } - - paper.Owner = newOwner - - err = ctx.GetPaperList().UpdatePaper(paper) - - if err != nil { - return nil, err - } - - return paper, nil -} - -// Redeem updates a commercial paper status to be redeemed -func (c *Contract) Redeem(ctx TransactionContextInterface, issuer string, paperNumber string, redeemingOwner string, redeenDateTime string) (*CommercialPaper, error) { - paper, err := ctx.GetPaperList().GetPaper(issuer, paperNumber) - - if err != nil { - return nil, err - } - - if paper.Owner != redeemingOwner { - return nil, fmt.Errorf("Paper %s:%s is not owned by %s", issuer, paperNumber, redeemingOwner) - } - - if paper.IsRedeemed() { - return nil, fmt.Errorf("Paper %s:%s is already redeemed", issuer, paperNumber) - } - - paper.Owner = paper.Issuer - paper.SetRedeemed() - - err = ctx.GetPaperList().UpdatePaper(paper) - - if err != nil { - return nil, err - } - - return paper, nil -} diff --git a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontract_test.go b/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontract_test.go deleted file mode 100644 index 25c429b3..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontract_test.go +++ /dev/null @@ -1,185 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "errors" - "testing" - - "github.com/hyperledger/fabric-contract-api-go/contractapi" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" -) - -// ######### -// HELPERS -// ######### -type MockPaperList struct { - mock.Mock -} - -func (mpl *MockPaperList) AddPaper(paper *CommercialPaper) error { - args := mpl.Called(paper) - - return args.Error(0) -} - -func (mpl *MockPaperList) GetPaper(issuer string, papernumber string) (*CommercialPaper, error) { - args := mpl.Called(issuer, papernumber) - - return args.Get(0).(*CommercialPaper), args.Error(1) -} - -func (mpl *MockPaperList) UpdatePaper(paper *CommercialPaper) error { - args := mpl.Called(paper) - - return args.Error(0) -} - -type MockTransactionContext struct { - contractapi.TransactionContext - paperList *MockPaperList -} - -func (mtc *MockTransactionContext) GetPaperList() ListInterface { - return mtc.paperList -} - -func resetPaper(paper *CommercialPaper) { - paper.Owner = "someowner" - paper.SetTrading() -} - -// ######### -// TESTS -// ######### - -func TestIssue(t *testing.T) { - var paper *CommercialPaper - var err error - - mpl := new(MockPaperList) - ctx := new(MockTransactionContext) - ctx.paperList = mpl - - contract := new(Contract) - - var sentPaper *CommercialPaper - - mpl.On("AddPaper", mock.MatchedBy(func(paper *CommercialPaper) bool { sentPaper = paper; return paper.Issuer == "someissuer" })).Return(nil) - mpl.On("AddPaper", mock.MatchedBy(func(paper *CommercialPaper) bool { sentPaper = paper; return paper.Issuer == "someotherissuer" })).Return(errors.New("AddPaper error")) - - expectedPaper := CommercialPaper{PaperNumber: "somepaper", Issuer: "someissuer", IssueDateTime: "someissuedate", FaceValue: 1000, MaturityDateTime: "somematuritydate", Owner: "someissuer", state: 1} - paper, err = contract.Issue(ctx, "someissuer", "somepaper", "someissuedate", "somematuritydate", 1000) - assert.Nil(t, err, "should not error when add paper does not error") - assert.Equal(t, sentPaper, paper, "should send the same paper as it returns to add paper") - assert.Equal(t, expectedPaper, *paper, "should correctly configure paper") - - paper, err = contract.Issue(ctx, "someotherissuer", "somepaper", "someissuedate", "somematuritydate", 1000) - assert.EqualError(t, err, "AddPaper error", "should return error when add paper fails") - assert.Nil(t, paper, "should not return paper when fails") -} - -func TestBuy(t *testing.T) { - var paper *CommercialPaper - var err error - - mpl := new(MockPaperList) - ctx := new(MockTransactionContext) - ctx.paperList = mpl - - contract := new(Contract) - - wsPaper := new(CommercialPaper) - resetPaper(wsPaper) - - var sentPaper *CommercialPaper - var emptyPaper *CommercialPaper - shouldError := false - - mpl.On("GetPaper", "someissuer", "somepaper").Return(wsPaper, nil) - mpl.On("GetPaper", "someotherissuer", "someotherpaper").Return(emptyPaper, errors.New("GetPaper error")) - mpl.On("UpdatePaper", mock.MatchedBy(func(paper *CommercialPaper) bool { return shouldError })).Return(errors.New("UpdatePaper error")) - mpl.On("UpdatePaper", mock.MatchedBy(func(paper *CommercialPaper) bool { sentPaper = paper; return !shouldError })).Return(nil) - - paper, err = contract.Buy(ctx, "someotherissuer", "someotherpaper", "someowner", "someotherowner", 100, "2019-12-10:10:00") - assert.EqualError(t, err, "GetPaper error", "should return error when GetPaper errors") - assert.Nil(t, paper, "should return nil for paper when GetPaper errors") - - paper, err = contract.Buy(ctx, "someissuer", "somepaper", "someotherowner", "someowner", 100, "2019-12-10:10:00") - assert.EqualError(t, err, "Paper someissuer:somepaper is not owned by someotherowner", "should error when sent owner not correct") - assert.Nil(t, paper, "should not return paper for bad owner error") - - resetPaper(wsPaper) - wsPaper.SetRedeemed() - paper, err = contract.Buy(ctx, "someissuer", "somepaper", "someowner", "someotherowner", 100, "2019-12-10:10:00") - assert.EqualError(t, err, "Paper someissuer:somepaper is not trading. Current state = REDEEMED") - assert.Nil(t, paper, "should not return paper for bad state error") - - resetPaper(wsPaper) - shouldError = true - paper, err = contract.Buy(ctx, "someissuer", "somepaper", "someowner", "someotherowner", 100, "2019-12-10:10:00") - assert.EqualError(t, err, "UpdatePaper error", "should error when update paper fails") - assert.Nil(t, paper, "should not return paper for bad state error") - shouldError = false - - resetPaper(wsPaper) - wsPaper.SetIssued() - paper, err = contract.Buy(ctx, "someissuer", "somepaper", "someowner", "someotherowner", 100, "2019-12-10:10:00") - assert.Nil(t, err, "should not error when good paper and owner") - assert.Equal(t, "someotherowner", paper.Owner, "should update the owner of the paper") - assert.True(t, paper.IsTrading(), "should mark issued paper as trading") - assert.Equal(t, sentPaper, paper, "should update same paper as it returns in the world state") -} - -func TestRedeem(t *testing.T) { - var paper *CommercialPaper - var err error - - mpl := new(MockPaperList) - ctx := new(MockTransactionContext) - ctx.paperList = mpl - - contract := new(Contract) - - var sentPaper *CommercialPaper - wsPaper := new(CommercialPaper) - resetPaper(wsPaper) - - var emptyPaper *CommercialPaper - shouldError := false - - mpl.On("GetPaper", "someissuer", "somepaper").Return(wsPaper, nil) - mpl.On("GetPaper", "someotherissuer", "someotherpaper").Return(emptyPaper, errors.New("GetPaper error")) - mpl.On("UpdatePaper", mock.MatchedBy(func(paper *CommercialPaper) bool { return shouldError })).Return(errors.New("UpdatePaper error")) - mpl.On("UpdatePaper", mock.MatchedBy(func(paper *CommercialPaper) bool { sentPaper = paper; return !shouldError })).Return(nil) - - paper, err = contract.Redeem(ctx, "someotherissuer", "someotherpaper", "someowner", "2021-12-10:10:00") - assert.EqualError(t, err, "GetPaper error", "should error when GetPaper errors") - assert.Nil(t, paper, "should not return paper when GetPaper errors") - - paper, err = contract.Redeem(ctx, "someissuer", "somepaper", "someotherowner", "2021-12-10:10:00") - assert.EqualError(t, err, "Paper someissuer:somepaper is not owned by someotherowner", "should error when paper owned by someone else") - assert.Nil(t, paper, "should not return paper when errors as owned by someone else") - - resetPaper(wsPaper) - wsPaper.SetRedeemed() - paper, err = contract.Redeem(ctx, "someissuer", "somepaper", "someowner", "2021-12-10:10:00") - assert.EqualError(t, err, "Paper someissuer:somepaper is already redeemed", "should error when paper already redeemed") - assert.Nil(t, paper, "should not return paper when errors as already redeemed") - - shouldError = true - resetPaper(wsPaper) - paper, err = contract.Redeem(ctx, "someissuer", "somepaper", "someowner", "2021-12-10:10:00") - assert.EqualError(t, err, "UpdatePaper error", "should error when update paper errors") - assert.Nil(t, paper, "should not return paper when UpdatePaper errors") - shouldError = false - - resetPaper(wsPaper) - paper, err = contract.Redeem(ctx, "someissuer", "somepaper", "someowner", "2021-12-10:10:00") - assert.Nil(t, err, "should not error on good redeem") - assert.True(t, paper.IsRedeemed(), "should return redeemed paper") - assert.Equal(t, sentPaper, paper, "should update same paper as it returns in the world state") -} diff --git a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paperlist.go b/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paperlist.go deleted file mode 100644 index 9946d512..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paperlist.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ledgerapi "github.com/hyperledger/fabric-samples/commercial-paper/organization/magnetocorp/contract-go/ledger-api" - -// ListInterface defines functionality needed -// to interact with the world state on behalf -// of a commercial paper -type ListInterface interface { - AddPaper(*CommercialPaper) error - GetPaper(string, string) (*CommercialPaper, error) - UpdatePaper(*CommercialPaper) error -} - -type list struct { - stateList ledgerapi.StateListInterface -} - -func (cpl *list) AddPaper(paper *CommercialPaper) error { - return cpl.stateList.AddState(paper) -} - -func (cpl *list) GetPaper(issuer string, paperNumber string) (*CommercialPaper, error) { - cp := new(CommercialPaper) - - err := cpl.stateList.GetState(CreateCommercialPaperKey(issuer, paperNumber), cp) - - if err != nil { - return nil, err - } - - return cp, nil -} - -func (cpl *list) UpdatePaper(paper *CommercialPaper) error { - return cpl.stateList.UpdateState(paper) -} - -// NewList create a new list from context -func newList(ctx TransactionContextInterface) *list { - stateList := new(ledgerapi.StateList) - stateList.Ctx = ctx - stateList.Name = "org.papernet.commercialpaperlist" - stateList.Deserialize = func(bytes []byte, state ledgerapi.StateInterface) error { - return Deserialize(bytes, state.(*CommercialPaper)) - } - - list := new(list) - list.stateList = stateList - - return list -} diff --git a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paperlist_test.go b/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paperlist_test.go deleted file mode 100644 index c13ff32b..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paperlist_test.go +++ /dev/null @@ -1,103 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package commercialpaper - -import ( - "errors" - "testing" - - ledgerapi "github.com/hyperledger/fabric-samples/commercial-paper/organization/magnetocorp/contract-go/ledger-api" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" -) - -// ######### -// HELPERS -// ######### - -type MockStateList struct { - mock.Mock -} - -func (msl *MockStateList) AddState(state ledgerapi.StateInterface) error { - args := msl.Called(state) - - return args.Error(0) -} - -func (msl *MockStateList) GetState(key string, state ledgerapi.StateInterface) error { - args := msl.Called(key, state) - - state.(*CommercialPaper).PaperNumber = "somepaper" - - return args.Error(0) -} - -func (msl *MockStateList) UpdateState(state ledgerapi.StateInterface) error { - args := msl.Called(state) - - return args.Error(0) -} - -// ######### -// TESTS -// ######### - -func TestAddPaper(t *testing.T) { - paper := new(CommercialPaper) - - list := new(list) - msl := new(MockStateList) - msl.On("AddState", paper).Return(errors.New("Called add state correctly")) - list.stateList = msl - - err := list.AddPaper(paper) - assert.EqualError(t, err, "Called add state correctly", "should call state list add state with paper") -} - -func TestGetPaper(t *testing.T) { - var cp *CommercialPaper - var err error - - list := new(list) - msl := new(MockStateList) - msl.On("GetState", CreateCommercialPaperKey("someissuer", "somepaper"), mock.MatchedBy(func(state ledgerapi.StateInterface) bool { _, ok := state.(*CommercialPaper); return ok })).Return(nil) - msl.On("GetState", CreateCommercialPaperKey("someotherissuer", "someotherpaper"), mock.MatchedBy(func(state ledgerapi.StateInterface) bool { _, ok := state.(*CommercialPaper); return ok })).Return(errors.New("GetState error")) - list.stateList = msl - - cp, err = list.GetPaper("someissuer", "somepaper") - assert.Nil(t, err, "should not error when get state on state list does not error") - assert.Equal(t, cp.PaperNumber, "somepaper", "should use state list GetState to fill commercial paper") - - cp, err = list.GetPaper("someotherissuer", "someotherpaper") - assert.EqualError(t, err, "GetState error", "should return error when state list get state errors") - assert.Nil(t, cp, "should not return commercial paper on error") -} - -func TestUpdatePaper(t *testing.T) { - paper := new(CommercialPaper) - - list := new(list) - msl := new(MockStateList) - msl.On("UpdateState", paper).Return(errors.New("Called update state correctly")) - list.stateList = msl - - err := list.UpdatePaper(paper) - assert.EqualError(t, err, "Called update state correctly", "should call state list update state with paper") -} - -func TestNewStateList(t *testing.T) { - ctx := new(TransactionContext) - list := newList(ctx) - stateList, ok := list.stateList.(*ledgerapi.StateList) - - assert.True(t, ok, "should make statelist of type ledgerapi.StateList") - assert.Equal(t, ctx, stateList.Ctx, "should set the context to passed context") - assert.Equal(t, "org.papernet.commercialpaperlist", stateList.Name, "should set the name for the list") - - expectedErr := Deserialize([]byte("bad json"), new(CommercialPaper)) - err := stateList.Deserialize([]byte("bad json"), new(CommercialPaper)) - assert.EqualError(t, err, expectedErr.Error(), "should call Deserialize when stateList.Deserialize called") -} diff --git a/commercial-paper/organization/magnetocorp/contract-go/go.mod b/commercial-paper/organization/magnetocorp/contract-go/go.mod deleted file mode 100644 index 03a77c78..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/go.mod +++ /dev/null @@ -1,39 +0,0 @@ -module github.com/hyperledger/fabric-samples/commercial-paper/organization/magnetocorp/contract-go - -go 1.17 - -require ( - github.com/hyperledger/fabric-contract-api-go v1.2.0 - github.com/stretchr/testify v1.8.0 -) - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect - github.com/go-openapi/spec v0.20.6 // indirect - github.com/go-openapi/swag v0.21.1 // 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/golang/protobuf v1.5.2 // indirect - github.com/hyperledger/fabric-chaincode-go v0.0.0-20220720122508-9207360bbddd // indirect - github.com/hyperledger/fabric-protos-go v0.0.0-20220613214546-bf864f01d75e // indirect - github.com/joho/godotenv v1.4.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.8.1 // indirect - github.com/stretchr/objx v0.4.0 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.0.0-20220708220712-1185a9018129 // indirect - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect - golang.org/x/text v0.3.7 // indirect - google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f // indirect - google.golang.org/grpc v1.48.0 // indirect - google.golang.org/protobuf v1.28.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/commercial-paper/organization/magnetocorp/contract-go/go.sum b/commercial-paper/organization/magnetocorp/contract-go/go.sum deleted file mode 100644 index 92a27e54..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/go.sum +++ /dev/null @@ -1,486 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/gherkin-go/v19 v19.0.3/go.mod h1:jY/NP6jUtRSArQQJ5h1FXOUgk5fZK24qtE7vKi776Vw= -github.com/cucumber/godog v0.12.5/go.mod h1:u6SD7IXC49dLpPN35kal0oYEjsXZWee4pW6Tm9t5pIc= -github.com/cucumber/messages-go/v16 v16.0.0/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g= -github.com/cucumber/messages-go/v16 v16.0.1/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/spec v0.20.6 h1:ich1RQ3WDbfoeTqTAb+5EIxNmpKVJZWBNah9RAT0jIQ= -github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -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-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.10.1 h1:ppDLoXv2feQ5nus4IcgtyMdHQkKng2lhJCIm33cblM0= -github.com/gobuffalo/envy v1.10.1/go.mod h1:AWx4++KnNOW3JOeEvhSaq+mvgAvnMYOY1XSIin4Mago= -github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0= -github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= -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/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -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= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-memdb v1.3.0/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g= -github.com/hashicorp/go-memdb v1.3.3/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -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-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -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= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20220720122508-9207360bbddd h1:AIa0b7UPrt8e1YN4/68vhNnPxy/Mrgq9d2bYJ6O/KTE= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20220720122508-9207360bbddd/go.mod h1:OxME3M0bbgoWYHpXIVMzpbXgFqrTZnFmlH0Cpml54m0= -github.com/hyperledger/fabric-contract-api-go v1.2.0 h1:BmArPRmTjiC2brHk2FNlDoJ8bOI0ExKZhj2YqWAiv5o= -github.com/hyperledger/fabric-contract-api-go v1.2.0/go.mod h1:GU2NV95E5LNkFTCL3xcPgXzi8QNLXBZhx7DGnKskuqw= -github.com/hyperledger/fabric-protos-go v0.0.0-20220613214546-bf864f01d75e h1:Ae2p0e+v5ekrl4KgkbCStBTSoV67Cg9fPkEWrv0f3nk= -github.com/hyperledger/fabric-protos-go v0.0.0-20220613214546-bf864f01d75e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= -github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -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/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -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/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -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/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -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/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -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= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -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.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -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.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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -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= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0= -golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -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/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20220718134204-073382fd740c/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f h1:P8EiVSxZwC6xH2niv2N66aqwMtYFg+D54gbjpcqKJtM= -google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -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.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -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= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/commercial-paper/organization/magnetocorp/contract-go/ledger-api/state.go b/commercial-paper/organization/magnetocorp/contract-go/ledger-api/state.go deleted file mode 100644 index 6d8c3f86..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/ledger-api/state.go +++ /dev/null @@ -1,27 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package ledgerapi - -import ( - "strings" -) - -// SplitKey splits a key on colon -func SplitKey(key string) []string { - return strings.Split(key, ":") -} - -// MakeKey joins key parts using colon -func MakeKey(keyParts ...string) string { - return strings.Join(keyParts, ":") -} - -// StateInterface interface states must implement -// for use in a list -type StateInterface interface { - // GetSplitKey return components that combine to form the key - GetSplitKey() []string - Serialize() ([]byte, error) -} diff --git a/commercial-paper/organization/magnetocorp/contract-go/ledger-api/statelist.go b/commercial-paper/organization/magnetocorp/contract-go/ledger-api/statelist.go deleted file mode 100644 index 492efb34..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/ledger-api/statelist.go +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package ledgerapi - -import ( - "fmt" - - "github.com/hyperledger/fabric-contract-api-go/contractapi" -) - -// StateListInterface functions that a state list -// should have -type StateListInterface interface { - AddState(StateInterface) error - GetState(string, StateInterface) error - UpdateState(StateInterface) error -} - -// StateList useful for managing putting data in and out -// of the ledger. Implementation of StateListInterface -type StateList struct { - Ctx contractapi.TransactionContextInterface - Name string - Deserialize func([]byte, StateInterface) error -} - -// AddState puts state into world state -func (sl *StateList) AddState(state StateInterface) error { - key, _ := sl.Ctx.GetStub().CreateCompositeKey(sl.Name, state.GetSplitKey()) - data, err := state.Serialize() - - if err != nil { - return err - } - - return sl.Ctx.GetStub().PutState(key, data) -} - -// GetState returns state from world state. Unmarshalls the JSON -// into passed state. Key is the split key value used in Add/Update -// joined using a colon -func (sl *StateList) GetState(key string, state StateInterface) error { - ledgerKey, _ := sl.Ctx.GetStub().CreateCompositeKey(sl.Name, SplitKey(key)) - data, err := sl.Ctx.GetStub().GetState(ledgerKey) - - if err != nil { - return err - } else if data == nil { - return fmt.Errorf("No state found for %s", key) - } - - return sl.Deserialize(data, state) -} - -// UpdateState puts state into world state. Same as AddState but -// separate as semantically different -func (sl *StateList) UpdateState(state StateInterface) error { - return sl.AddState(state) -} diff --git a/commercial-paper/organization/magnetocorp/contract-go/main.go b/commercial-paper/organization/magnetocorp/contract-go/main.go deleted file mode 100644 index 98606c1b..00000000 --- a/commercial-paper/organization/magnetocorp/contract-go/main.go +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package main - -import ( - "fmt" - - "github.com/hyperledger/fabric-contract-api-go/contractapi" - commercialpaper "github.com/hyperledger/fabric-samples/commercial-paper/organization/magnetocorp/contract-go/commercial-paper" -) - -func main() { - - contract := new(commercialpaper.Contract) - contract.TransactionContextHandler = new(commercialpaper.TransactionContext) - contract.Name = "org.papernet.commercialpaper" - contract.Info.Version = "0.0.1" - - chaincode, err := contractapi.NewChaincode(contract) - - if err != nil { - panic(fmt.Sprintf("Error creating chaincode. %s", err.Error())) - } - - chaincode.Info.Title = "CommercialPaperChaincode" - chaincode.Info.Version = "0.0.1" - - err = chaincode.Start() - - if err != nil { - panic(fmt.Sprintf("Error starting chaincode. %s", err.Error())) - } -} diff --git a/commercial-paper/organization/magnetocorp/contract-java/build.gradle b/commercial-paper/organization/magnetocorp/contract-java/build.gradle deleted file mode 100644 index 160bf421..00000000 --- a/commercial-paper/organization/magnetocorp/contract-java/build.gradle +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ -plugins { - id 'com.github.johnrengelman.shadow' version '5.1.0' - id 'java' -} - - -version '0.0.1' - -sourceCompatibility = 1.8 - -repositories { - mavenCentral() - maven { - url 'https://jitpack.io' - } -} - -dependencies { - implementation group: 'org.hyperledger.fabric-chaincode-java', name: 'fabric-chaincode-shim', version: '2.+' - implementation group: 'org.json', name: 'json', version: '20180813' - testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2' - testImplementation 'org.assertj:assertj-core:3.11.1' - testImplementation 'org.mockito:mockito-core:2.+' -} - -test { - useJUnitPlatform() - testLogging { - events "passed", "skipped", "failed" - } -} - -shadowJar { - baseName = 'chaincode' - version = null - classifier = null - - manifest { - attributes 'Main-Class': 'org.hyperledger.fabric.contract.ContractRouter' - } -} - - -tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters" -} diff --git a/commercial-paper/organization/magnetocorp/contract-java/gradle/wrapper/gradle-wrapper.jar b/commercial-paper/organization/magnetocorp/contract-java/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 5c2d1cf016b3885f6930543d57b744ea8c220a1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55616 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 \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/commercial-paper/organization/magnetocorp/contract-java/gradlew.bat b/commercial-paper/organization/magnetocorp/contract-java/gradlew.bat deleted file mode 100644 index 24467a14..00000000 --- a/commercial-paper/organization/magnetocorp/contract-java/gradlew.bat +++ /dev/null @@ -1,100 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/commercial-paper/organization/magnetocorp/contract-java/settings.gradle b/commercial-paper/organization/magnetocorp/contract-java/settings.gradle deleted file mode 100644 index 0c5f0723..00000000 --- a/commercial-paper/organization/magnetocorp/contract-java/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -rootProject.name = 'papercontract' - diff --git a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaper.java b/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaper.java deleted file mode 100644 index 13d16b66..00000000 --- a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaper.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.example; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.example.ledgerapi.State; -import org.hyperledger.fabric.contract.annotation.DataType; -import org.hyperledger.fabric.contract.annotation.Property; -import org.json.JSONObject; -import org.json.JSONPropertyIgnore; - -@DataType() -public class CommercialPaper extends State { - - // Enumerate commercial paper state values - public final static String ISSUED = "ISSUED"; - public final static String TRADING = "TRADING"; - public final static String REDEEMED = "REDEEMED"; - - @Property() - private String state=""; - - public String getState() { - return state; - } - - public CommercialPaper setState(String state) { - this.state = state; - return this; - } - - @JSONPropertyIgnore() - public boolean isIssued() { - return this.state.equals(CommercialPaper.ISSUED); - } - - @JSONPropertyIgnore() - public boolean isTrading() { - return this.state.equals(CommercialPaper.TRADING); - } - - @JSONPropertyIgnore() - public boolean isRedeemed() { - return this.state.equals(CommercialPaper.REDEEMED); - } - - public CommercialPaper setIssued() { - this.state = CommercialPaper.ISSUED; - return this; - } - - public CommercialPaper setTrading() { - this.state = CommercialPaper.TRADING; - return this; - } - - public CommercialPaper setRedeemed() { - this.state = CommercialPaper.REDEEMED; - return this; - } - - @Property() - private String paperNumber; - - @Property() - private String issuer; - - @Property() - private String issueDateTime; - - @Property() - private int faceValue; - - @Property() - private String maturityDateTime; - - @Property() - private String owner; - - public String getOwner() { - return owner; - } - - public CommercialPaper setOwner(String owner) { - this.owner = owner; - return this; - } - - public CommercialPaper() { - super(); - } - - public CommercialPaper setKey() { - this.key = State.makeKey(new String[] { this.paperNumber }); - return this; - } - - public String getPaperNumber() { - return paperNumber; - } - - public CommercialPaper setPaperNumber(String paperNumber) { - this.paperNumber = paperNumber; - return this; - } - - public String getIssuer() { - return issuer; - } - - public CommercialPaper setIssuer(String issuer) { - this.issuer = issuer; - return this; - } - - public String getIssueDateTime() { - return issueDateTime; - } - - public CommercialPaper setIssueDateTime(String issueDateTime) { - this.issueDateTime = issueDateTime; - return this; - } - - public int getFaceValue() { - return faceValue; - } - - public CommercialPaper setFaceValue(int faceValue) { - this.faceValue = faceValue; - return this; - } - - public String getMaturityDateTime() { - return maturityDateTime; - } - - public CommercialPaper setMaturityDateTime(String maturityDateTime) { - this.maturityDateTime = maturityDateTime; - return this; - } - - @Override - public String toString() { - return "Paper::" + this.key + " " + this.getPaperNumber() + " " + getIssuer() + " " + getFaceValue(); - } - - /** - * Deserialize a state data to commercial paper - * - * @param {Buffer} data to form back into the object - */ - public static CommercialPaper deserialize(byte[] data) { - JSONObject json = new JSONObject(new String(data, UTF_8)); - - String issuer = json.getString("issuer"); - String paperNumber = json.getString("paperNumber"); - String issueDateTime = json.getString("issueDateTime"); - String maturityDateTime = json.getString("maturityDateTime"); - String owner = json.getString("owner"); - int faceValue = json.getInt("faceValue"); - String state = json.getString("state"); - return createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, faceValue,owner,state); - } - - public static byte[] serialize(CommercialPaper paper) { - return State.serialize(paper); - } - - /** - * Factory method to create a commercial paper object - */ - public static CommercialPaper createInstance(String issuer, String paperNumber, String issueDateTime, - String maturityDateTime, int faceValue, String owner, String state) { - return new CommercialPaper().setIssuer(issuer).setPaperNumber(paperNumber).setMaturityDateTime(maturityDateTime) - .setFaceValue(faceValue).setKey().setIssueDateTime(issueDateTime).setOwner(owner).setState(state); - } - - -} diff --git a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContext.java b/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContext.java deleted file mode 100644 index 7a946f2f..00000000 --- a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContext.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.example; - -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.shim.ChaincodeStub; - -class CommercialPaperContext extends Context { - - public CommercialPaperContext(ChaincodeStub stub) { - super(stub); - this.paperList = new PaperList(this); - } - - public PaperList paperList; - -} \ No newline at end of file diff --git a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContract.java b/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContract.java deleted file mode 100644 index a04e62db..00000000 --- a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContract.java +++ /dev/null @@ -1,170 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ -package org.example; - -import java.util.logging.Logger; - -import org.example.ledgerapi.State; -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.contract.ContractInterface; -import org.hyperledger.fabric.contract.annotation.Contact; -import org.hyperledger.fabric.contract.annotation.Contract; -import org.hyperledger.fabric.contract.annotation.Default; -import org.hyperledger.fabric.contract.annotation.Info; -import org.hyperledger.fabric.contract.annotation.License; -import org.hyperledger.fabric.contract.annotation.Transaction; -import org.hyperledger.fabric.shim.ChaincodeStub; - -/** - * A custom context provides easy access to list of all commercial papers - */ - -/** - * Define commercial paper smart contract by extending Fabric Contract class - * - */ -@Contract(name = "org.papernet.commercialpaper", info = @Info(title = "MyAsset contract", description = "", version = "0.0.1", license = @License(name = "SPDX-License-Identifier: Apache-2.0", url = ""), contact = @Contact(email = "java-contract@example.com", name = "java-contract", url = "http://java-contract.me"))) -@Default -public class CommercialPaperContract implements ContractInterface { - - // use the classname for the logger, this way you can refactor - private final static Logger LOG = Logger.getLogger(CommercialPaperContract.class.getName()); - - @Override - public Context createContext(ChaincodeStub stub) { - return new CommercialPaperContext(stub); - } - - public CommercialPaperContract() { - - } - - /** - * Define a custom context for commercial paper - */ - - /** - * Instantiate to perform any setup of the ledger that might be required. - * - * @param {Context} ctx the transaction context - */ - @Transaction - public void instantiate(CommercialPaperContext ctx) { - // No implementation required with this example - // It could be where data migration is performed, if necessary - LOG.info("No data migration to perform"); - } - - /** - * Issue commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} issueDateTime paper issue date - * @param {String} maturityDateTime paper maturity date - * @param {Integer} faceValue face value of paper - */ - @Transaction - public CommercialPaper issue(CommercialPaperContext ctx, String issuer, String paperNumber, String issueDateTime, - String maturityDateTime, int faceValue) { - - System.out.println(ctx); - - // create an instance of the paper - CommercialPaper paper = CommercialPaper.createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, - faceValue,issuer,""); - - // Smart contract, rather than paper, moves paper into ISSUED state - paper.setIssued(); - - // Newly issued paper is owned by the issuer - paper.setOwner(issuer); - - System.out.println(paper); - // Add the paper to the list of all similar commercial papers in the ledger - // world state - ctx.paperList.addPaper(paper); - - // Must return a serialized paper to caller of smart contract - return paper; - } - - /** - * Buy commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} currentOwner current owner of paper - * @param {String} newOwner new owner of paper - * @param {Integer} price price paid for this paper - * @param {String} purchaseDateTime time paper was purchased (i.e. traded) - */ - @Transaction - public CommercialPaper buy(CommercialPaperContext ctx, String issuer, String paperNumber, String currentOwner, - String newOwner, int price, String purchaseDateTime) { - - // Retrieve the current paper using key fields provided - String paperKey = State.makeKey(new String[] { issuer, paperNumber }); - CommercialPaper paper = ctx.paperList.getPaper(paperKey); - - // Validate current owner - if (!paper.getOwner().equals(currentOwner)) { - throw new RuntimeException("Paper " + issuer + paperNumber + " is not owned by " + currentOwner); - } - - // First buy moves state from ISSUED to TRADING - if (paper.isIssued()) { - paper.setTrading(); - } - - // Check paper is not already REDEEMED - if (paper.isTrading()) { - paper.setOwner(newOwner); - } else { - throw new RuntimeException( - "Paper " + issuer + paperNumber + " is not trading. Current state = " + paper.getState()); - } - - // Update the paper - ctx.paperList.updatePaper(paper); - return paper; - } - - /** - * Redeem commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} redeemingOwner redeeming owner of paper - * @param {String} redeemDateTime time paper was redeemed - */ - @Transaction - public CommercialPaper redeem(CommercialPaperContext ctx, String issuer, String paperNumber, String redeemingOwner, - String redeemDateTime) { - - String paperKey = CommercialPaper.makeKey(new String[] {issuer, paperNumber }); - - CommercialPaper paper = ctx.paperList.getPaper(paperKey); - - // Check paper is not REDEEMED - if (paper.isRedeemed()) { - throw new RuntimeException("Paper " + issuer + paperNumber + " already redeemed"); - } - - // Verify that the redeemer owns the commercial paper before redeeming it - if (paper.getOwner().equals(redeemingOwner)) { - paper.setOwner(paper.getIssuer()); - paper.setRedeemed(); - } else { - throw new RuntimeException("Redeeming owner does not own paper" + issuer + paperNumber); - } - - ctx.paperList.updatePaper(paper); - return paper; - } - -} diff --git a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/PaperList.java b/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/PaperList.java deleted file mode 100644 index 0ecd24cd..00000000 --- a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/PaperList.java +++ /dev/null @@ -1,31 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package org.example; - -import org.example.ledgerapi.StateList; -import org.hyperledger.fabric.contract.Context; - -public class PaperList { - - private StateList stateList; - - public PaperList(Context ctx) { - this.stateList = StateList.getStateList(ctx, PaperList.class.getSimpleName(), CommercialPaper::deserialize); - } - - public PaperList addPaper(CommercialPaper paper) { - stateList.addState(paper); - return this; - } - - public CommercialPaper getPaper(String paperKey) { - return (CommercialPaper) this.stateList.getState(paperKey); - } - - public PaperList updatePaper(CommercialPaper paper) { - this.stateList.updateState(paper); - return this; - } -} diff --git a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/State.java b/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/State.java deleted file mode 100644 index 46d35c38..00000000 --- a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/State.java +++ /dev/null @@ -1,60 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ -package org.example.ledgerapi; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.json.JSONObject; - -/** - * State class. States have a class, unique key, and a lifecycle current state - * the current state is determined by the specific subclass - */ -public class State { - - protected String key; - - /** - * @param {String|Object} class An identifiable class of the instance - * @param {keyParts[]} elements to pull together to make a key for the objects - */ - public State() { - - } - - String getKey() { - return this.key; - } - - public String[] getSplitKey() { - return State.splitKey(this.key); - } - - /** - * Convert object to buffer containing JSON data serialization Typically used - * before putState()ledger API - * - * @param {Object} JSON object to serialize - * @return {buffer} buffer with the data to store - */ - public static byte[] serialize(Object object) { - String jsonStr = new JSONObject(object).toString(); - return jsonStr.getBytes(UTF_8); - } - - /** - * Join the keyParts to make a unififed string - * - * @param (String[]) keyParts - */ - public static String makeKey(String[] keyParts) { - return String.join(":", keyParts); - } - - public static String[] splitKey(String key) { - System.out.println("splitting key " + key + " " + java.util.Arrays.asList(key.split(":"))); - return key.split(":"); - } - -} diff --git a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/StateDeserializer.java b/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/StateDeserializer.java deleted file mode 100644 index 891788ea..00000000 --- a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/StateDeserializer.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.example.ledgerapi; - -@FunctionalInterface -public interface StateDeserializer { - State deserialize(byte[] buffer); -} diff --git a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/StateList.java b/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/StateList.java deleted file mode 100644 index d6725860..00000000 --- a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/StateList.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.example.ledgerapi; - -import org.example.ledgerapi.impl.StateListImpl; -import org.hyperledger.fabric.contract.Context; - -public interface StateList { - - /* - * SPDX-License-Identifier: Apache-2.0 - */ - - /** - * StateList provides a named virtual container for a set of ledger states. Each - * state has a unique key which associates it with the container, rather than - * the container containing a link to the state. This minimizes collisions for - * parallel transactions on different states. - */ - - /** - * Store Fabric context for subsequent API access, and name of list - */ - static StateList getStateList(Context ctx, String listName, StateDeserializer deserializer) { - return new StateListImpl(ctx, listName, deserializer); - } - - /** - * Add a state to the list. Creates a new state in worldstate with appropriate - * composite key. Note that state defines its own key. State object is - * serialized before writing. - */ - public StateList addState(State state); - - /** - * Get a state from the list using supplied keys. Form composite keys to - * retrieve state from world state. State data is deserialized into JSON object - * before being returned. - */ - public State getState(String key); - - /** - * Update a state in the list. Puts the new state in world state with - * appropriate composite key. Note that state defines its own key. A state is - * serialized before writing. Logic is very similar to addState() but kept - * separate becuase it is semantically distinct. - */ - public StateList updateState(State state); - -} diff --git a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/impl/StateListImpl.java b/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/impl/StateListImpl.java deleted file mode 100644 index 78a42933..00000000 --- a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/impl/StateListImpl.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.example.ledgerapi.impl; - -import java.util.Arrays; - -import org.example.ledgerapi.State; -import org.example.ledgerapi.StateDeserializer; -import org.example.ledgerapi.StateList; -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.shim.ChaincodeStub; -import org.hyperledger.fabric.shim.ledger.CompositeKey; - -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * StateList provides a named virtual container for a set of ledger states. Each - * state has a unique key which associates it with the container, rather than - * the container containing a link to the state. This minimizes collisions for - * parallel transactions on different states. - */ -public class StateListImpl implements StateList { - - private Context ctx; - private String name; - private Object supportedClasses; - private StateDeserializer deserializer; - - /** - * Store Fabric context for subsequent API access, and name of list - * - * @param deserializer - */ - public StateListImpl(Context ctx, String listName, StateDeserializer deserializer) { - this.ctx = ctx; - this.name = listName; - this.deserializer = deserializer; - - } - - /** - * Add a state to the list. Creates a new state in worldstate with appropriate - * composite key. Note that state defines its own key. State object is - * serialized before writing. - */ - @Override - public StateList addState(State state) { - System.out.println("Adding state " + this.name); - ChaincodeStub stub = this.ctx.getStub(); - System.out.println("Stub=" + stub); - String[] splitKey = state.getSplitKey(); - System.out.println("Split key " + Arrays.asList(splitKey)); - - CompositeKey ledgerKey = stub.createCompositeKey(this.name, splitKey); - System.out.println("ledgerkey is "); - System.out.println(ledgerKey); - - byte[] data = State.serialize(state); - System.out.println("ctx" + this.ctx); - System.out.println("stub" + this.ctx.getStub()); - this.ctx.getStub().putState(ledgerKey.toString(), data); - - return this; - } - - /** - * Get a state from the list using supplied keys. Form composite keys to - * retrieve state from world state. State data is deserialized into JSON object - * before being returned. - */ - @Override - public State getState(String key) { - - CompositeKey ledgerKey = this.ctx.getStub().createCompositeKey(this.name, State.splitKey(key)); - - byte[] data = this.ctx.getStub().getState(ledgerKey.toString()); - if (data != null) { - State state = this.deserializer.deserialize(data); - return state; - } else { - return null; - } - } - - /** - * Update a state in the list. Puts the new state in world state with - * appropriate composite key. Note that state defines its own key. A state is - * serialized before writing. Logic is very similar to addState() but kept - * separate becuase it is semantically distinct. - */ - @Override - public StateList updateState(State state) { - CompositeKey ledgerKey = this.ctx.getStub().createCompositeKey(this.name, state.getSplitKey()); - byte[] data = State.serialize(state); - this.ctx.getStub().putState(ledgerKey.toString(), data); - - return this; - } - -} diff --git a/commercial-paper/organization/magnetocorp/contract/.editorconfig b/commercial-paper/organization/magnetocorp/contract/.editorconfig deleted file mode 100755 index 75a13be2..00000000 --- a/commercial-paper/organization/magnetocorp/contract/.editorconfig +++ /dev/null @@ -1,16 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -root = true - -[*] -indent_style = space -indent_size = 4 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.md] -trim_trailing_whitespace = false diff --git a/commercial-paper/organization/magnetocorp/contract/.eslintignore b/commercial-paper/organization/magnetocorp/contract/.eslintignore deleted file mode 100644 index 15958470..00000000 --- a/commercial-paper/organization/magnetocorp/contract/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -coverage diff --git a/commercial-paper/organization/magnetocorp/contract/.eslintrc.js b/commercial-paper/organization/magnetocorp/contract/.eslintrc.js deleted file mode 100644 index 6772c660..00000000 --- a/commercial-paper/organization/magnetocorp/contract/.eslintrc.js +++ /dev/null @@ -1,37 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -module.exports = { - env: { - node: true, - mocha: true - }, - parserOptions: { - ecmaVersion: 8, - sourceType: 'script' - }, - extends: "eslint:recommended", - rules: { - indent: ['error', 4], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], - 'no-unused-vars': ['error', { args: 'none' }], - 'no-console': 'off', - curly: 'error', - eqeqeq: 'error', - 'no-throw-literal': 'error', - strict: 'error', - 'no-var': 'error', - 'dot-notation': 'error', - 'no-tabs': 'error', - 'no-trailing-spaces': 'error', - 'no-use-before-define': 'error', - 'no-useless-call': 'error', - 'no-with': 'error', - 'operator-linebreak': 'error', - yoda: 'error', - 'quote-props': ['error', 'as-needed'] - } -}; diff --git a/commercial-paper/organization/magnetocorp/contract/.npmignore b/commercial-paper/organization/magnetocorp/contract/.npmignore deleted file mode 100644 index a00ca941..00000000 --- a/commercial-paper/organization/magnetocorp/contract/.npmignore +++ /dev/null @@ -1,77 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# next.js build output -.next - -# nuxt.js build output -.nuxt - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless diff --git a/commercial-paper/organization/magnetocorp/contract/index.js b/commercial-paper/organization/magnetocorp/contract/index.js deleted file mode 100644 index e0ea2c7e..00000000 --- a/commercial-paper/organization/magnetocorp/contract/index.js +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; - -const cpcontract = require('./lib/papercontract.js'); -module.exports.contracts = [cpcontract]; diff --git a/commercial-paper/organization/magnetocorp/contract/ledger-api/state.js b/commercial-paper/organization/magnetocorp/contract/ledger-api/state.js deleted file mode 100644 index f63e792e..00000000 --- a/commercial-paper/organization/magnetocorp/contract/ledger-api/state.js +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; - -/** - * State class. States have a class, unique key, and a lifecycle current state - * the current state is determined by the specific subclass - */ -class State { - - /** - * @param {String|Object} class An indentifiable class of the instance - * @param {keyParts[]} elements to pull together to make a key for the objects - */ - constructor(stateClass, keyParts) { - this.class = stateClass; - this.key = State.makeKey(keyParts); - this.currentState = null; - } - - getClass() { - return this.class; - } - - getKey() { - return this.key; - } - - getSplitKey(){ - return State.splitKey(this.key); - } - - getCurrentState(){ - return this.currentState; - } - - // not used -/* serialize() { - - return State.serialize(this); - } */ - - /** - * Convert object to buffer containing JSON data serialization - * Typically used before putState()ledger API - * @param {Object} JSON object to serialize - * @return {buffer} buffer with the data to store - */ - static serialize(object) { - // don't write the key:value passed in - we already have a real composite key, issuer and paper Number. - delete object.key; - return Buffer.from(JSON.stringify(object)); - } - - /** - * Deserialize object into one of a set of supported JSON classes - * i.e. Covert serialized data to JSON object - * Typically used after getState() ledger API - * @param {data} data to deserialize into JSON object - * @param (supportedClasses) the set of classes data can be serialized to - * @return {json} json with the data to store - */ - static deserialize(data, supportedClasses) { - let json = JSON.parse(data.toString()); - let objClass = supportedClasses[json.class]; - if (!objClass) { - throw new Error(`Unknown class of ${json.class}`); - } - let object = new (objClass)(json); - - return object; - } - - /** - * Deserialize object into specific object class - * Typically used after getState() ledger API - * @param {data} data to deserialize into JSON object - * @return {json} json with the data to store - */ - static deserializeClass(data, objClass) { - let json = JSON.parse(data.toString()); - let object = new (objClass)(json); - return object; - } - - /** - * Join the keyParts to make a unififed string - * @param (String[]) keyParts - */ - static makeKey(keyParts) { - // return keyParts.map(part => JSON.stringify(part)).join(':'); - return keyParts.map(part => part).join(':'); - } - - static splitKey(key){ - return key.split(':'); - } - -} - -module.exports = State; diff --git a/commercial-paper/organization/magnetocorp/contract/ledger-api/statelist.js b/commercial-paper/organization/magnetocorp/contract/ledger-api/statelist.js deleted file mode 100644 index 15ec8370..00000000 --- a/commercial-paper/organization/magnetocorp/contract/ledger-api/statelist.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; -const State = require('./state.js'); - -/** - * StateList provides a named virtual container for a set of ledger states. - * Each state has a unique key which associates it with the container, rather - * than the container containing a link to the state. This minimizes collisions - * for parallel transactions on different states. - */ -class StateList { - - /** - * Store Fabric context for subsequent API access, and name of list - */ - constructor(ctx, listName) { - this.ctx = ctx; - this.name = listName; - this.supportedClasses = {}; - - } - - /** - * Add a state to the list. Creates a new state in worldstate with - * appropriate composite key. Note that state defines its own key. - * State object is serialized before writing. - */ - async addState(state) { - let key = this.ctx.stub.createCompositeKey(this.name, state.getSplitKey()); - let data = State.serialize(state); - await this.ctx.stub.putState(key, data); - } - - /** - * Get a state from the list using supplied keys. Form composite - * keys to retrieve state from world state. State data is deserialized - * into JSON object before being returned. - */ - async getState(key) { - let ledgerKey = this.ctx.stub.createCompositeKey(this.name, State.splitKey(key)); - let data = await this.ctx.stub.getState(ledgerKey); - if (data && data.toString('utf8')) { - let state = State.deserialize(data, this.supportedClasses); - return state; - } else { - return null; - } - } - - /** - * Update a state in the list. Puts the new state in world state with - * appropriate composite key. Note that state defines its own key. - * A state is serialized before writing. Logic is very similar to - * addState() but kept separate becuase it is semantically distinct. - */ - async updateState(state) { - let key = this.ctx.stub.createCompositeKey(this.name, state.getSplitKey()); - let data = State.serialize(state); - await this.ctx.stub.putState(key, data); - } - - /** Stores the class for future deserialization */ - use(stateClass) { - this.supportedClasses[stateClass.getClass()] = stateClass; - } - -} - -module.exports = StateList; diff --git a/commercial-paper/organization/magnetocorp/contract/lib/paper.js b/commercial-paper/organization/magnetocorp/contract/lib/paper.js deleted file mode 100644 index 0629ba71..00000000 --- a/commercial-paper/organization/magnetocorp/contract/lib/paper.js +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; - -// Utility class for ledger state -const State = require('./../ledger-api/state.js'); - -// Enumerate commercial paper state values -const cpState = { - ISSUED: 1, - PENDING: 2, - TRADING: 3, - REDEEMED: 4 -}; - -/** - * CommercialPaper class extends State class - * Class will be used by application and smart contract to define a paper - */ -class CommercialPaper extends State { - - constructor(obj) { - super(CommercialPaper.getClass(), [obj.issuer, obj.paperNumber]); - Object.assign(this, obj); - } - - /** - * Basic getters and setters - */ - getIssuer() { - return this.issuer; - } - - setIssuer(newIssuer) { - this.issuer = newIssuer; - } - - getOwner() { - return this.owner; - } - - setOwnerMSP(mspid) { - this.mspid = mspid; - } - - getOwnerMSP() { - return this.mspid; - } - - setOwner(newOwner) { - this.owner = newOwner; - } - - /** - * Useful methods to encapsulate commercial paper states - */ - setIssued() { - this.currentState = cpState.ISSUED; - } - - setTrading() { - this.currentState = cpState.TRADING; - } - - setRedeemed() { - this.currentState = cpState.REDEEMED; - } - - setPending() { - this.currentState = cpState.PENDING; - } - - isIssued() { - return this.currentState === cpState.ISSUED; - } - - isTrading() { - return this.currentState === cpState.TRADING; - } - - isRedeemed() { - return this.currentState === cpState.REDEEMED; - } - - isPending() { - return this.currentState === cpState.PENDING; - } - - static fromBuffer(buffer) { - return CommercialPaper.deserialize(buffer); - } - - toBuffer() { - return Buffer.from(JSON.stringify(this)); - } - - /** - * Deserialize a state data to commercial paper - * @param {Buffer} data to form back into the object - */ - static deserialize(data) { - return State.deserializeClass(data, CommercialPaper); - } - - /** - * Factory method to create a commercial paper object - */ - static createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, faceValue) { - return new CommercialPaper({ issuer, paperNumber, issueDateTime, maturityDateTime, faceValue }); - } - - static getClass() { - return 'org.papernet.commercialpaper'; - } -} - -module.exports = CommercialPaper; diff --git a/commercial-paper/organization/magnetocorp/contract/lib/papercontract.js b/commercial-paper/organization/magnetocorp/contract/lib/papercontract.js deleted file mode 100644 index c3d2cdb4..00000000 --- a/commercial-paper/organization/magnetocorp/contract/lib/papercontract.js +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; - -// Fabric smart contract classes -const { Contract, Context } = require('fabric-contract-api'); - -// PaperNet specifc classes -const CommercialPaper = require('./paper.js'); -const PaperList = require('./paperlist.js'); -const QueryUtils = require('./queries.js'); - -/** - * A custom context provides easy access to list of all commercial papers - */ -class CommercialPaperContext extends Context { - - constructor() { - super(); - // All papers are held in a list of papers - this.paperList = new PaperList(this); - } - -} - -/** - * Define commercial paper smart contract by extending Fabric Contract class - * - */ -class CommercialPaperContract extends Contract { - - constructor() { - // Unique namespace when multiple contracts per chaincode file - super('org.papernet.commercialpaper'); - } - - /** - * Define a custom context for commercial paper - */ - createContext() { - return new CommercialPaperContext(); - } - - /** - * Instantiate to perform any setup of the ledger that might be required. - * @param {Context} ctx the transaction context - */ - async instantiate(ctx) { - // No implementation required with this example - // It could be where data migration is performed, if necessary - console.log('Instantiate the contract'); - } - - /** - * Issue commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} issueDateTime paper issue date - * @param {String} maturityDateTime paper maturity date - * @param {Integer} faceValue face value of paper - */ - async issue(ctx, issuer, paperNumber, issueDateTime, maturityDateTime, faceValue) { - - // create an instance of the paper - let paper = CommercialPaper.createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, parseInt(faceValue)); - - // Smart contract, rather than paper, moves paper into ISSUED state - paper.setIssued(); - - // save the owner's MSP - let mspid = ctx.clientIdentity.getMSPID(); - paper.setOwnerMSP(mspid); - - // Newly issued paper is owned by the issuer to begin with (recorded for reporting purposes) - paper.setOwner(issuer); - - // Add the paper to the list of all similar commercial papers in the ledger world state - await ctx.paperList.addPaper(paper); - - // Must return a serialized paper to caller of smart contract - return paper; - } - - /** - * Buy commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} currentOwner current owner of paper - * @param {String} newOwner new owner of paper - * @param {Integer} price price paid for this paper // transaction input - not written to asset - * @param {String} purchaseDateTime time paper was purchased (i.e. traded) // transaction input - not written to asset - */ - async buy(ctx, issuer, paperNumber, currentOwner, newOwner, price, purchaseDateTime) { - - // Retrieve the current paper using key fields provided - let paperKey = CommercialPaper.makeKey([issuer, paperNumber]); - let paper = await ctx.paperList.getPaper(paperKey); - - // Validate current owner - if (paper.getOwner() !== currentOwner) { - throw new Error('\nPaper ' + issuer + paperNumber + ' is not owned by ' + currentOwner); - } - - // First buy moves state from ISSUED to TRADING (when running ) - if (paper.isIssued()) { - paper.setTrading(); - } - - // Check paper is not already REDEEMED - if (paper.isTrading()) { - paper.setOwner(newOwner); - // save the owner's MSP - let mspid = ctx.clientIdentity.getMSPID(); - paper.setOwnerMSP(mspid); - } else { - throw new Error('\nPaper ' + issuer + paperNumber + ' is not trading. Current state = ' + paper.getCurrentState()); - } - - // Update the paper - await ctx.paperList.updatePaper(paper); - return paper; - } - - /** - * Buy request: (2-phase confirmation: Commercial paper is 'PENDING' subject to completion of transfer by owning org) - * Alternative to 'buy' transaction - * Note: 'buy_request' puts paper in 'PENDING' state - subject to transfer confirmation [below]. - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} currentOwner current owner of paper - * @param {String} newOwner new owner of paper // transaction input - not written to asset per se - but written to block - * @param {Integer} price price paid for this paper // transaction input - not written to asset per se - but written to block - * @param {String} purchaseDateTime time paper was requested // transaction input - ditto. - */ - async buy_request(ctx, issuer, paperNumber, currentOwner, newOwner, price, purchaseDateTime) { - - - // Retrieve the current paper using key fields provided - let paperKey = CommercialPaper.makeKey([issuer, paperNumber]); - let paper = await ctx.paperList.getPaper(paperKey); - - // Validate current owner - this is really information for the user trying the sample, rather than any 'authorisation' check per se FYI - if (paper.getOwner() !== currentOwner) { - throw new Error('\nPaper ' + issuer + paperNumber + ' is not owned by ' + currentOwner + ' provided as a paraneter'); - } - // paper set to 'PENDING' - can only be transferred (confirmed) by identity from owning org (MSP check). - paper.setPending(); - - // Update the paper - await ctx.paperList.updatePaper(paper); - return paper; - } - - /** - * transfer commercial paper: only the owning org has authority to execute. It is the complement to the 'buy_request' transaction. '[]' is optional below. - * eg. issue -> buy_request -> transfer -> [buy ...n | [buy_request...n | transfer ...n] ] -> redeem - * this transaction 'pair' is an alternative to the straight issue -> buy -> [buy....n] -> redeem ...path - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} newOwner new owner of paper - * @param {String} newOwnerMSP MSP id of the transferee - * @param {String} confirmDateTime confirmed transfer date. - */ - async transfer(ctx, issuer, paperNumber, newOwner, newOwnerMSP, confirmDateTime) { - - // Retrieve the current paper using key fields provided - let paperKey = CommercialPaper.makeKey([issuer, paperNumber]); - let paper = await ctx.paperList.getPaper(paperKey); - - // Validate current owner's MSP in the paper === invoking transferor's MSP id - can only transfer if you are the owning org. - - if (paper.getOwnerMSP() !== ctx.clientIdentity.getMSPID()) { - throw new Error('\nPaper ' + issuer + paperNumber + ' is not owned by the current invoking Organisation, and not authorised to transfer'); - } - - // Paper needs to be 'pending' - which means you need to have run 'buy_pending' transaction first. - if ( ! paper.isPending()) { - throw new Error('\nPaper ' + issuer + paperNumber + ' is not currently in state: PENDING for transfer to occur: \n must run buy_request transaction first'); - } - // else all good - - paper.setOwner(newOwner); - // set the MSP of the transferee (so that, that org may also pass MSP check, if subsequently transferred/sold on) - paper.setOwnerMSP(newOwnerMSP); - paper.setTrading(); - paper.confirmDateTime = confirmDateTime; - - // Update the paper - await ctx.paperList.updatePaper(paper); - return paper; - } - - /** - * Redeem commercial paper - * - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - * @param {String} redeemingOwner redeeming owner of paper - * @param {String} issuingOwnerMSP the MSP of the org that the paper will be redeemed with. - * @param {String} redeemDateTime time paper was redeemed - */ - async redeem(ctx, issuer, paperNumber, redeemingOwner, issuingOwnerMSP, redeemDateTime) { - - let paperKey = CommercialPaper.makeKey([issuer, paperNumber]); - - let paper = await ctx.paperList.getPaper(paperKey); - - // Check paper is not alread in a state of REDEEMED - if (paper.isRedeemed()) { - throw new Error('\nPaper ' + issuer + paperNumber + ' has already been redeemed'); - } - - // Validate current redeemer's MSP matches the invoking redeemer's MSP id - can only redeem if you are the owning org. - - if (paper.getOwnerMSP() !== ctx.clientIdentity.getMSPID()) { - throw new Error('\nPaper ' + issuer + paperNumber + ' cannot be redeemed by ' + ctx.clientIdentity.getMSPID() + ', as it is not the authorised owning Organisation'); - } - - // As this is just a sample, can show additional verification check: that the redeemer provided matches that on record, before redeeming it - if (paper.getOwner() === redeemingOwner) { - paper.setOwner(paper.getIssuer()); - paper.setOwnerMSP(issuingOwnerMSP); - paper.setRedeemed(); - paper.redeemDateTime = redeemDateTime; // record redemption date against the asset (the complement to 'issue date') - } else { - throw new Error('\nRedeeming owner: ' + redeemingOwner + ' organisation does not currently own paper: ' + issuer + paperNumber); - } - - await ctx.paperList.updatePaper(paper); - return paper; - } - - // Query transactions - - /** - * Query history of a commercial paper - * @param {Context} ctx the transaction context - * @param {String} issuer commercial paper issuer - * @param {Integer} paperNumber paper number for this issuer - */ - async queryHistory(ctx, issuer, paperNumber) { - - // Get a key to be used for History query - - let query = new QueryUtils(ctx, 'org.papernet.paper'); - let results = await query.getAssetHistory(issuer, paperNumber); // (cpKey); - return results; - - } - - /** - * queryOwner commercial paper: supply name of owning org, to find list of papers based on owner field - * @param {Context} ctx the transaction context - * @param {String} owner commercial paper owner - */ - async queryOwner(ctx, owner) { - - let query = new QueryUtils(ctx, 'org.papernet.paper'); - let owner_results = await query.queryKeyByOwner(owner); - - return owner_results; - } - - /** - * queryPartial commercial paper - provide a prefix eg. "DigiBank" will list all papers _issued_ by DigiBank etc etc - * @param {Context} ctx the transaction context - * @param {String} prefix asset class prefix (added to paperlist namespace) eg. org.papernet.paperMagnetoCorp asset listing: papers issued by MagnetoCorp. - */ - async queryPartial(ctx, prefix) { - - let query = new QueryUtils(ctx, 'org.papernet.paper'); - let partial_results = await query.queryKeyByPartial(prefix); - - return partial_results; - } - - /** - * queryAdHoc commercial paper - supply a custom mango query - * eg - as supplied as a param: - * ex1: ["{\"selector\":{\"faceValue\":{\"$lt\":8000000}}}"] - * ex2: ["{\"selector\":{\"faceValue\":{\"$gt\":4999999}}}"] - * - * @param {Context} ctx the transaction context - * @param {String} queryString querystring - */ - async queryAdhoc(ctx, queryString) { - - let query = new QueryUtils(ctx, 'org.papernet.paper'); - let querySelector = JSON.parse(queryString); - let adhoc_results = await query.queryByAdhoc(querySelector); - - return adhoc_results; - } - - - /** - * queryNamed - supply named query - 'case' statement chooses selector to build (pre-canned for demo purposes) - * @param {Context} ctx the transaction context - * @param {String} queryname the 'named' query (built here) - or - the adHoc query string, provided as a parameter - */ - async queryNamed(ctx, queryname) { - let querySelector = {}; - switch (queryname) { - case "redeemed": - querySelector = { "selector": { "currentState": 4 } }; // 4 = redeemd state - break; - case "trading": - querySelector = { "selector": { "currentState": 3 } }; // 3 = trading state - break; - case "value": - // may change to provide as a param - fixed value for now in this sample - querySelector = { "selector": { "faceValue": { "$gt": 4000000 } } }; // to test, issue CommPapers with faceValue <= or => this figure. - break; - default: // else, unknown named query - throw new Error('invalid named query supplied: ' + queryname + '- please try again '); - } - - let query = new QueryUtils(ctx, 'org.papernet.paper'); - let adhoc_results = await query.queryByAdhoc(querySelector); - - return adhoc_results; - } - -} - -module.exports = CommercialPaperContract; diff --git a/commercial-paper/organization/magnetocorp/contract/lib/paperlist.js b/commercial-paper/organization/magnetocorp/contract/lib/paperlist.js deleted file mode 100644 index 73528b61..00000000 --- a/commercial-paper/organization/magnetocorp/contract/lib/paperlist.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; - -// Utility class for collections of ledger states -- a state list -const StateList = require('./../ledger-api/statelist.js'); - -const CommercialPaper = require('./paper.js'); - -class PaperList extends StateList { - - constructor(ctx) { - super(ctx, 'org.papernet.paper'); - this.use(CommercialPaper); - } - - async addPaper(paper) { - return this.addState(paper); - } - - async getPaper(paperKey) { - return this.getState(paperKey); - } - - async updatePaper(paper) { - return this.updateState(paper); - } -} - - -module.exports = PaperList; diff --git a/commercial-paper/organization/magnetocorp/contract/lib/queries.js b/commercial-paper/organization/magnetocorp/contract/lib/queries.js deleted file mode 100644 index 9bba6c29..00000000 --- a/commercial-paper/organization/magnetocorp/contract/lib/queries.js +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ -'use strict'; - -const State = require('../ledger-api/state.js'); -//const CommercialPaper = require('./paper.js'); -/** - * Query Class for query functions such as history etc - * - */ -class QueryUtils { - - constructor(ctx, listName) { - this.ctx = ctx; - this.name = listName; - //this.supportedTypes = {}; - } - - // ========================================================================================= - // getAssetHistory takes the composite key as arg, gets returns results as JSON to 'main contract' - // ========================================================================================= - /** - * Get Asset History for a commercial paper - * @param {String} issuer the CP issuer - * @param {String} paperNumber commercial paper number - */ - async getAssetHistory(issuer, paperNumber) { - - let ledgerKey = await this.ctx.stub.createCompositeKey(this.name, [issuer, paperNumber]); - const resultsIterator = await this.ctx.stub.getHistoryForKey(ledgerKey); - let results = await this.getAllResults(resultsIterator, true); - - return results; - } - - // =========================================================================================== - // queryKeyByPartial performs a partial query based on the namespace and asset key prefix provided - - // Read-only function results are not typically submitted to ordering. If the read-only - // results are submitted to ordering, or if the query is used in an update transaction - // and submitted to ordering, then the committing peers will re-execute to guarantee that - // result sets are stable between endorsement time and commit time. The transaction is - // invalidated by the committing peers if the result set has changed between endorsement - // time and commit time. - // - // =========================================================================================== - /** - * queryOwner commercial paper - * @param {String} assetspace the asset space (eg MagnetoCorp's assets) - */ - async queryKeyByPartial(assetspace) { - - if (arguments.length < 1) { - throw new Error('Incorrect number of arguments. Expecting 1'); - } - // ie namespace + prefix to assets etc eg - // "Key":"org.papernet.paperMagnetoCorp0001" (0002, etc) - // "Partial":'org.papernet.paperlistMagnetoCorp"' (using partial key, find keys "0001", "0002" etc) - const resultsIterator = await this.ctx.stub.getStateByPartialCompositeKey(this.name, [assetspace]); - let method = this.getAllResults; - let results = await method(resultsIterator, false); - - return results; - } - - - // ===== Example: Parameterized rich query ================================================= - // queryKeyByOwner queries for assets based on a passed in owner. - // This is an example of a parameterized query accepting a single query parameter (owner). - // Only available on state databases that support rich query (e.g. CouchDB) - // ========================================================================================= - /** - * queryKeyByOwner commercial paper - * @param {String} owner commercial paper owner - */ - async queryKeyByOwner(owner) { - // - let self = this; - if (arguments.length < 1) { - throw new Error('Incorrect number of arguments. Expecting owner name.'); - } - let queryString = {}; - queryString.selector = {}; - // queryString.selector.docType = 'indexOwnerDoc'; - queryString.selector.owner = owner; - // set to (eg) '{selector:{owner:MagnetoCorp}}' - let method = self.getQueryResultForQueryString; - let queryResults = await method(this.ctx, self, JSON.stringify(queryString)); - return queryResults; - } - - // ===== Example: Ad hoc rich query ======================================================== - // queryAdhoc uses a query string to perform a query for marbles.. - // Query string matching state database syntax is passed in and executed as is. - // Supports ad hoc queries that can be defined at runtime by the client. - // If this is not desired, follow the queryKeyByOwner example for parameterized queries. - // Only available on state databases that support rich query (e.g. CouchDB) - // example passed using VS Code ext: ["{\"selector\": {\"owner\": \"MagnetoCorp\"}}"] - // ========================================================================================= - /** - * query By AdHoc string (commercial paper) - * @param {String} queryString actual MangoDB query string (escaped) - */ - async queryByAdhoc(queryString) { - - if (arguments.length < 1) { - throw new Error('Incorrect number of arguments. Expecting ad-hoc string, which gets stringified for mango query'); - } - let self = this; - - if (!queryString) { - throw new Error('queryString must not be empty'); - } - let method = self.getQueryResultForQueryString; - let queryResults = await method(this.ctx, self, JSON.stringify(queryString)); - return queryResults; - } - - // WORKER functions are below this line: these are called by the above functions, where iterator is passed in - - // ========================================================================================= - // getQueryResultForQueryString woerk function executes the passed-in query string. - // Result set is built and returned as a byte array containing the JSON results. - // ========================================================================================= - /** - * Function getQueryResultForQueryString - * @param {Context} ctx the transaction context - * @param {any} self within scope passed in - * @param {String} the query string created prior to calling this fn - */ - async getQueryResultForQueryString(ctx, self, queryString) { - - // console.log('- getQueryResultForQueryString queryString:\n' + queryString); - - const resultsIterator = await ctx.stub.getQueryResult(queryString); - let results = await self.getAllResults(resultsIterator, false); - - return results; - - } - - /** - * Function getAllResults - * @param {resultsIterator} iterator within scope passed in - * @param {Boolean} isHistory query string created prior to calling this fn - */ - async getAllResults(iterator, isHistory) { - let allResults = []; - let res = { done: false, value: null }; - - while (true) { - res = await iterator.next(); - let jsonRes = {}; - if (res.value && res.value.value.toString()) { - if (isHistory && isHistory === true) { - //jsonRes.TxId = res.value.tx_id; - jsonRes.TxId = res.value.txId; - jsonRes.Timestamp = res.value.timestamp; - jsonRes.Timestamp = new Date((res.value.timestamp.seconds.low * 1000)); - let ms = res.value.timestamp.nanos / 1000000; - jsonRes.Timestamp.setMilliseconds(ms); - if (res.value.is_delete) { - jsonRes.IsDelete = res.value.is_delete.toString(); - } else { - try { - jsonRes.Value = JSON.parse(res.value.value.toString('utf8')); - // report the commercial paper states during the asset lifecycle, just for asset history reporting - switch (jsonRes.Value.currentState) { - case 1: - jsonRes.Value.currentState = 'ISSUED'; - break; - case 2: - jsonRes.Value.currentState = 'PENDING'; - break; - case 3: - jsonRes.Value.currentState = 'TRADING'; - break; - case 4: - jsonRes.Value.currentState = 'REDEEMED'; - break; - default: // else, unknown named query - jsonRes.Value.currentState = 'UNKNOWN'; - } - - } catch (err) { - console.log(err); - jsonRes.Value = res.value.value.toString('utf8'); - } - } - } else { // non history query .. - jsonRes.Key = res.value.key; - try { - jsonRes.Record = JSON.parse(res.value.value.toString('utf8')); - } catch (err) { - console.log(err); - jsonRes.Record = res.value.value.toString('utf8'); - } - } - allResults.push(jsonRes); - } - // check to see if we have reached the end - if (res.done) { - // explicitly close the iterator - console.log('iterator is done'); - await iterator.close(); - return allResults; - } - - } // while true - } - -} -module.exports = QueryUtils; diff --git a/commercial-paper/organization/magnetocorp/contract/package.json b/commercial-paper/organization/magnetocorp/contract/package.json deleted file mode 100644 index 2c4a6449..00000000 --- a/commercial-paper/organization/magnetocorp/contract/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "papernet-js", - "version": "0.0.1", - "description": "Papernet Contract", - "main": "index.js", - "engines": { - "node": ">=8", - "npm": ">=5" - }, - "scripts": { - "lint": "eslint .", - "pretest": "npm run lint", - "test": "nyc mocha test --recursive", - "start": "fabric-chaincode-node start", - "mocha": "mocha test --recursive" - }, - "engineStrict": true, - "author": "hyperledger", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "^2.0.0", - "fabric-shim": "^2.0.0" - }, - "devDependencies": { - "chai": "^4.1.2", - "chai-as-promised": "^7.1.1", - "eslint": "^4.19.1", - "mocha": "^5.2.0", - "nyc": "^12.0.2", - "sinon": "^6.0.0", - "sinon-chai": "^3.2.0" - }, - "nyc": { - "exclude": [ - "coverage/**", - "test/**" - ], - "reporter": [ - "text-summary", - "html" - ], - "all": true, - "check-coverage": true, - "statements": 100, - "branches": 100, - "functions": 100, - "lines": 100 - } -} diff --git a/commercial-paper/organization/magnetocorp/contract/test/contract.js b/commercial-paper/organization/magnetocorp/contract/test/contract.js deleted file mode 100644 index 63576eed..00000000 --- a/commercial-paper/organization/magnetocorp/contract/test/contract.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ -'use strict'; - -const Chaincode = require('../lib/chaincode'); -const { Stub } = require('fabric-shim'); - -require('chai').should(); -const sinon = require('sinon'); - -describe('Chaincode', () => { - - describe('#Init', () => { - - it('should work', async () => { - const cc = new Chaincode(); - const stub = sinon.createStubInstance(Stub); - stub.getFunctionAndParameters.returns({ fcn: 'initFunc', params: [] }); - const res = await cc.Init(stub); - res.status.should.equal(Stub.RESPONSE_CODE.OK); - }); - - }); - - describe('#Invoke', async () => { - - it('should work', async () => { - const cc = new Chaincode(); - const stub = sinon.createStubInstance(Stub); - stub.getFunctionAndParameters.returns({ fcn: 'initFunc', params: [] }); - let res = await cc.Init(stub); - res.status.should.equal(Stub.RESPONSE_CODE.OK); - stub.getFunctionAndParameters.returns({ fcn: 'invokeFunc', params: [] }); - res = await cc.Invoke(stub); - res.status.should.equal(Stub.RESPONSE_CODE.OK); - }); - - }); - -}); diff --git a/commercial-paper/organization/magnetocorp/gateway/.gitkeep b/commercial-paper/organization/magnetocorp/gateway/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/commercial-paper/organization/magnetocorp/magnetocorp.sh b/commercial-paper/organization/magnetocorp/magnetocorp.sh deleted file mode 100755 index c061d275..00000000 --- a/commercial-paper/organization/magnetocorp/magnetocorp.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: Apache-2.0 -TMPFILE=`mktemp` -shopt -s extglob - -function _exit(){ - printf "Exiting:%s\n" "$1" - exit -1 -} - - -: ${CHANNEL_NAME:="mychannel"} -: ${DELAY:="3"} -: ${MAX_RETRY:="5"} -: ${VERBOSE:="false"} - -# Where am I? -DIR=${PWD} - -# Locate the test-network -cd "${DIR}/../../../test-network" -env | sort > $TMPFILE - -OVERRIDE_ORG="2" -. ./scripts/envVar.sh - - -parsePeerConnectionParameters 1 2 - -# set the fabric config path -export FABRIC_CFG_PATH="${DIR}/../../../config" -export PATH="${DIR}/../../../bin:${PWD}:$PATH" - -env | sort | comm -1 -3 $TMPFILE - | sed -E 's/(.*)=(.*)/export \1="\2"/' -rm $TMPFILE - -cd "${DIR}" diff --git a/commercial-paper/organization/magnetocorp/t.js b/commercial-paper/organization/magnetocorp/t.js deleted file mode 100644 index 031abd31..00000000 --- a/commercial-paper/organization/magnetocorp/t.js +++ /dev/null @@ -1 +0,0 @@ -console.log(process.argv); \ No newline at end of file