From e40a7458703eb80fdc8e733a31ecc356135db29d Mon Sep 17 00:00:00 2001 From: Gregory Haskins Date: Wed, 1 Feb 2017 22:21:10 -0500 Subject: [PATCH] Import release v0.10.1 This is a legacy import of the release originally managed in pure github. You may find the history of this release in the archives here: https://github.com/hyperledger-archives/fabric-chaintool/releases/tag/v0.10.1 Change-Id: I57fcb68c85ccf92b6eee4b57f97f41ddf0f59e2b Signed-off-by: Gregory Haskins --- README.md | 41 ++--- examples/example02/README.md | 58 +++---- .../org.hyperledger.chaincode.example02.cci | 6 +- .../example02/client/{sdk => cljs}/Makefile | 0 .../client/{sdk => cljs}/project.clj | 0 .../{rest/cljs => cljs/protos}/appinit.proto | 0 .../org.hyperledger.chaincode.example02.proto | 0 .../{sdk => cljs}/src/example02/core.cljs | 0 .../hlc => cljs/src/example02/hfc}/core.cljs | 0 .../hlc => cljs/src/example02/hfc}/user.cljs | 0 .../{sdk => cljs}/src/example02/main.cljs | 0 .../{sdk => cljs}/src/example02/rpc.cljs | 0 .../{sdk => cljs}/src/example02/util.cljs | 0 .../client/lib/fabric-ca-client-0.1.0.tgz | Bin 0 -> 20625 bytes .../client/lib/fabric-client-0.1.0.tgz | Bin 0 -> 66900 bytes examples/example02/client/nodejs/client.js | 153 +++++++++++++++++ examples/example02/client/nodejs/lib/util.js | 80 +++++++++ examples/example02/client/nodejs/package.json | 20 +++ .../nodejs => nodejs/protos}/appinit.proto | 0 .../org.hyperledger.chaincode.example02.proto | 0 examples/example02/client/rest/cljs/Makefile | 17 -- .../example02/client/rest/cljs/project.clj | 24 --- .../client/rest/cljs/src/example02/core.cljs | 43 ----- .../client/rest/cljs/src/example02/main.cljs | 98 ----------- .../client/rest/cljs/src/example02/rpc.cljs | 45 ----- .../example02/client/rest/nodejs/index.js | 101 ----------- .../example02/client/rest/nodejs/package.json | 14 -- examples/example02/client/sdk/appinit.proto | 19 --- .../org.hyperledger.chaincode.example02.proto | 29 ---- examples/invoker/src/chaincode/chaincode.go | 4 +- .../org.hyperledger.chaincode.example02.cci | 7 +- ...ledger.chaincode.example.parameterless.cci | 2 +- ...rg.hyperledger.chaincode.system.sample.cci | 7 +- project.clj | 6 +- resources/generators/golang.stg | 160 +++++++++--------- .../org.hyperledger.chaintool.meta.cci | 2 +- resources/parsers/interface/grammar.bnf | 7 +- src/chaintool/build/core.clj | 14 +- src/chaintool/build/interface.clj | 10 +- src/chaintool/core.clj | 5 + src/chaintool/platforms/api.clj | 2 + src/chaintool/platforms/golang/core.clj | 9 +- src/chaintool/platforms/golang/system.clj | 5 + src/chaintool/platforms/golang/userspace.clj | 6 + src/chaintool/protobuf/generate.clj | 15 +- src/chaintool/subcommands/env.clj | 19 +++ test/chaintool/build/test_interface.clj | 2 +- test/chaintool/protobuf/test_generate.clj | 2 +- 48 files changed, 447 insertions(+), 585 deletions(-) rename examples/example02/client/{sdk => cljs}/Makefile (100%) rename examples/example02/client/{sdk => cljs}/project.clj (100%) rename examples/example02/client/{rest/cljs => cljs/protos}/appinit.proto (100%) rename examples/example02/client/{rest/cljs => cljs/protos}/org.hyperledger.chaincode.example02.proto (100%) rename examples/example02/client/{sdk => cljs}/src/example02/core.cljs (100%) rename examples/example02/client/{sdk/src/example02/hlc => cljs/src/example02/hfc}/core.cljs (100%) rename examples/example02/client/{sdk/src/example02/hlc => cljs/src/example02/hfc}/user.cljs (100%) rename examples/example02/client/{sdk => cljs}/src/example02/main.cljs (100%) rename examples/example02/client/{sdk => cljs}/src/example02/rpc.cljs (100%) rename examples/example02/client/{sdk => cljs}/src/example02/util.cljs (100%) create mode 100644 examples/example02/client/lib/fabric-ca-client-0.1.0.tgz create mode 100644 examples/example02/client/lib/fabric-client-0.1.0.tgz create mode 100644 examples/example02/client/nodejs/client.js create mode 100644 examples/example02/client/nodejs/lib/util.js create mode 100644 examples/example02/client/nodejs/package.json rename examples/example02/client/{rest/nodejs => nodejs/protos}/appinit.proto (100%) rename examples/example02/client/{rest/nodejs => nodejs/protos}/org.hyperledger.chaincode.example02.proto (100%) delete mode 100644 examples/example02/client/rest/cljs/Makefile delete mode 100644 examples/example02/client/rest/cljs/project.clj delete mode 100644 examples/example02/client/rest/cljs/src/example02/core.cljs delete mode 100644 examples/example02/client/rest/cljs/src/example02/main.cljs delete mode 100644 examples/example02/client/rest/cljs/src/example02/rpc.cljs delete mode 100644 examples/example02/client/rest/nodejs/index.js delete mode 100644 examples/example02/client/rest/nodejs/package.json delete mode 100644 examples/example02/client/sdk/appinit.proto delete mode 100644 examples/example02/client/sdk/org.hyperledger.chaincode.example02.proto create mode 100644 src/chaintool/subcommands/env.clj diff --git a/README.md b/README.md index 2a45a63..c0f2e8a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ _chaintool_ is a toolchain to assist in various phases of [Hyperledger Fabric](h ### Why? -Current chaincode development is rather unstructured outside of the coarse-level callbacks for invoke or query passing a {function-name, argument-array} string-based tuple. The result of this is that input translation/validation is a manual, explicit, and likely fragile process in each chaincode function. Additionally, any potential chaincode consumer needs to study the chaincode source in order to ascertain its API. +Current chaincode development is rather unstructured outside of the coarse-level callbacks for Invoke() passing opaque bytes. The result of this is that input translation/validation is a manual, explicit, and likely fragile process in each chaincode function. Additionally, any potential chaincode consumer needs to study the chaincode source in order to ascertain its API. Consider that some chaincode applications may employ confidentiality to hide their source, while others may wish to employ alternative programming languages. This aside, chaincode deployment lifecycles may be long enough to require us to be aware of managing potential API incompatibilities between the chaincode and its clients. It starts to become clear that there are some advantages to allowing chaincode to express its API interfaces in a way that is independent from the underlying implementation/language and in a manner that supports some form of schema management. @@ -30,7 +30,7 @@ _chaintool_ provides some other benefits too, such as consistent language-neutra ``` $ chaintool -h -chaintool version: v0.7 +chaintool version: v0.10.1 Usage: chaintool [general-options] action [action-options] @@ -60,7 +60,7 @@ In all cases, you may obtain subcommand specific help by invoking "chaintool _$s ``` $ chaintool package -h -chaintool version: v0.7 +chaintool version: v0.10.1 Description: chaintool package - Package the chaincode into a CAR file for deployment @@ -210,7 +210,7 @@ The only core requirement is that both _chaintool_ and the chosen Hyperledger ne #### Interface Declarations -Interfaces (as included in ./src/interfaces) may be in one or two categories: Provided or Consumed. _Provided_ means that the chaincode implements the interface and supports having clients or other chaincode invoke methods as declared. Likewise, _consumed_ indicates that the chaincode expects to perform inter-chaincode invoke/query operations to a disparate chaincode instance that provides the interface. It is perfectly fine (though perhaps uncommon) for a chaincode to both provide and consume a given interface (such as for proxy contracts which may accept operations in a polymorphic manner before passing operations on to a concrete instance). +Interfaces (as included in ./src/interfaces) may be in one or two categories: Provided or Consumed. _Provided_ means that the chaincode implements the interface and supports having clients or other chaincode invoke methods as declared. Likewise, _consumed_ indicates that the chaincode expects to perform inter-chaincode invoke operations to a disparate chaincode instance that provides the interface. It is perfectly fine (though perhaps uncommon) for a chaincode to both provide and consume a given interface (such as for proxy contracts which may accept operations in a polymorphic manner before passing operations on to a concrete instance). Both Provides and Consumes are expressed as an array of 1 or more entries. For example: @@ -273,20 +273,14 @@ message BalanceResult { int32 balance = 1; } -transactions { +functions { void MakePayment(PaymentParams) = 1; void DeleteAccount(Entity) = 2; -} - -queries { - BalanceResult CheckBalance(Entity) = 1; + BalanceResult CheckBalance(Entity) = 3; } ``` -The _message_ definitions are almost 1:1 with protobuf grammar. The largest divergence is w.r.t. the _transactions_ and _queries_ sections. These two are similar to one another as well as to the notion of service/rpc in protobuf grammar. The reason we diverged is for a few different reasons: - -- Chaincode has a strong delineation between and invoke and a query, and it was important for the parser to be able to understand the breakdown so that the proper code could be emitted -- It was felt that the lack of "field indices" in the protobuf service/rpc grammar was a large shortcoming in ABI compatibility. Therefore, the grammar used here retains the notion of indices even for function calls. +The _message_ definitions are almost 1:1 with protobuf grammar. The largest divergence is w.r.t. the _functions_ section. This section is similiar to the notion of service/rpc in protobuf grammar. We diverged from the protobuf/grpc grammar because it was felt that the lack of "field indices" was a large shortcoming in ABI compatibility. Therefore, the grammar used here retains the notion of indices even for function calls. The main purpose of the grammar is to define RPC functions. For reasons of ABI stability, it was decided that all RPCs will have the following properties: - Be indexed (e.g. ABI depends on index stability, not function name) @@ -316,23 +310,16 @@ message ChaincodeInput { } ``` -Chaintool deterministically maps transactions/queries declared within a CCI to an [encoded function name](#function-encoding), and expects the corresponding input parameter to be a base64 encoded protobuf message as the first and only arg string. +Chaintool deterministically maps functions declared within a CCI to an [encoded function name](#function-encoding), and expects the corresponding input parameter to be a base64 encoded protobuf message as the first and only arg string. Example: ``` -{"function":"org.hyperledger.chaincode.example02/query/1","args":["CgNmb28="]}} +{"function":"org.hyperledger.chaincode.example02/fcn/3","args":["CgNmb28="]}} ``` #### Function Encoding -Function naming follows the convention *interface-name/method-type/method-index*. For instance, invoking *MakePayment* from our [example](./examples/example02/app/src/interfaces/org.hyperledger.chaincode.example02.cci) would be *org.hyperledger.chaintool.example02/txn/1*. Because its transaction #1 in the org.hyperledger.chaintool.example02 interface. - -##### Method Types - -There are two types of methods: transactions and queries. We therefore have two values in the function name that correspond to the underlying method type: - -- "txn" - transactions -- "query" - queries +Function naming follows the convention *interface-name/method-type/method-index*. For instance, invoking *MakePayment* from our [example](./examples/example02/app/src/interfaces/org.hyperledger.chaincode.example02.cci) would be *org.hyperledger.chaintool.example02/fcn/1*. Because its function #1 in the org.hyperledger.chaintool.example02 interface. ### Output Protocol @@ -368,9 +355,9 @@ message PaymentParams { // // Available RPC functions exported by this interface // -// void MakePayment(PaymentParams) -> org.hyperledger.chaincode.example02/txn/1 -// void DeleteAccount(Entity) -> org.hyperledger.chaincode.example02/txn/2 -// BalanceResult CheckBalance(Entity) -> org.hyperledger.chaincode.example02/query/1 +// void MakePayment(PaymentParams) -> org.hyperledger.chaincode.example02/fcn/1 +// void DeleteAccount(Entity) -> org.hyperledger.chaincode.example02/fcn/2 +// BalanceResult CheckBalance(Entity) -> org.hyperledger.chaincode.example02/fcn/3 ``` ## Metadata @@ -409,7 +396,7 @@ message Facts { repeated Fact facts = 1; } -queries { +functions { Interfaces GetInterfaces(GetInterfacesParams) = 1; InterfaceDescriptor GetInterface(GetInterfaceParams) = 2; Facts GetFacts(GetFactsParams) = 3; diff --git a/examples/example02/README.md b/examples/example02/README.md index 931beab..3226222 100644 --- a/examples/example02/README.md +++ b/examples/example02/README.md @@ -14,48 +14,36 @@ This directory contains an implementation of the chaincode application called "e │   ├── appinit.cci │   └── org.hyperledger.chaincode.example02.cci └── client - ├── rest - │   ├── cljs - │   │   ├── Makefile - │   │   ├── appinit.proto - │   │   ├── org.hyperledger.chaincode.example02.proto - │   │   ├── project.clj - │   │   └── src - │   │   └── example02 - │   │   ├── core.cljs - │   │   ├── main.cljs - │   │   └── rpc.cljs - │   └── nodejs - │   ├── appinit.proto - │   ├── index.js - │   ├── org.hyperledger.chaincode.example02.proto - │   └── package.json - └── sdk - ├── Makefile + ├── cljs + │   ├── Makefile + │   ├── appinit.proto + │   ├── org.hyperledger.chaincode.example02.proto + │   ├── project.clj + │   └── src + │   └── example02 + │   ├── core.cljs + │   ├── hlc + │   │   ├── core.cljs + │   │   └── user.cljs + │   ├── main.cljs + │   ├── rpc.cljs + │   └── util.cljs + └── nodejs ├── appinit.proto + ├── index.js + ├── util.js ├── org.hyperledger.chaincode.example02.proto - ├── project.clj - └── src - └── example02 - ├── core.cljs - ├── hlc - │   ├── core.cljs - │   └── user.cljs - ├── main.cljs - ├── rpc.cljs - └── util.cljs + └── package.json ``` * app - contains a org.hyperledger.chaincode.golang platform based chaincode application. * This is the code deployed to the blockchain * client - client applications for interacting with the chaincode application - * rest - REST api based clients - * nodejs - A simple demonstration of using nodejs+REST. - * cljs - A complete client for example02 over REST written in ClojureScript - * sdk - SDK based client, written in ClojureScript + * nodejs - A simple demonstration of using nodejs. + * cljs - A complete client for example02 written in ClojureScript ## Deploying and interacting with the example02 ### Step 1 - Fabric environment -You will need a functioning peer that has chaintool v0.7 or higher available in the $PATH. You may check the version of chaintool you have with 'chaintool -h'. Once confirmed, start the peer with _peer node start_ as you normally would. It is advised to keep the configuration as simple as possible (1 VP, no security, noops consensus) +You will need a functioning peer that has chaintool v0.10.1 or higher available in the $PATH. You may check the version of chaintool you have with 'chaintool -h'. Once confirmed, start the peer with _peer node start_ as you normally would. It is advised to keep the configuration as simple as possible (1 VP, no security, noops consensus) ### Step 2 - Package the chaincode application Run 'chaintool package' from the app folder, noting the CAR output path @@ -82,11 +70,11 @@ Chaincode SHA3: f7026e0675b22a9d78b9f7f0cb97c93165bdefedc86de97f00e76b506c7 #### Note: The _chaintool package_ command is designed to package for deployment, not development. If you started your node with _peer node start --peer-chaincodedev_, run _chaintool build_ instead. This is analogous to building non-chaintool chaincode using _go build_. The output will be placed in the _app/build/bin/_ directory. ### Step 3 - Compile the client -Run 'make' from the client/rest/cljs folder +Run 'make' from the client/cljs folder ``` $ make lein npm install -example02@0.1.0-SNAPSHOT /Users/ghaskins/sandbox/git/chaintool/examples/example02/client/rest/cljs +example02@0.1.0-SNAPSHOT /Users/ghaskins/sandbox/git/chaintool/examples/example02/client/cljs ├─┬ protobufjs@5.0.1 │ ├─┬ ascli@1.0.0 │ │ ├── colour@0.7.1 diff --git a/examples/example02/app/src/interfaces/org.hyperledger.chaincode.example02.cci b/examples/example02/app/src/interfaces/org.hyperledger.chaincode.example02.cci index ad02021..f9f40e3 100644 --- a/examples/example02/app/src/interfaces/org.hyperledger.chaincode.example02.cci +++ b/examples/example02/app/src/interfaces/org.hyperledger.chaincode.example02.cci @@ -13,11 +13,9 @@ message BalanceResult { int32 balance = 1; } -transactions { +functions { void MakePayment(PaymentParams) = 1; void DeleteAccount(Entity) = 2; + BalanceResult CheckBalance(Entity) = 3; } -queries { - BalanceResult CheckBalance(Entity) = 1; -} diff --git a/examples/example02/client/sdk/Makefile b/examples/example02/client/cljs/Makefile similarity index 100% rename from examples/example02/client/sdk/Makefile rename to examples/example02/client/cljs/Makefile diff --git a/examples/example02/client/sdk/project.clj b/examples/example02/client/cljs/project.clj similarity index 100% rename from examples/example02/client/sdk/project.clj rename to examples/example02/client/cljs/project.clj diff --git a/examples/example02/client/rest/cljs/appinit.proto b/examples/example02/client/cljs/protos/appinit.proto similarity index 100% rename from examples/example02/client/rest/cljs/appinit.proto rename to examples/example02/client/cljs/protos/appinit.proto diff --git a/examples/example02/client/rest/cljs/org.hyperledger.chaincode.example02.proto b/examples/example02/client/cljs/protos/org.hyperledger.chaincode.example02.proto similarity index 100% rename from examples/example02/client/rest/cljs/org.hyperledger.chaincode.example02.proto rename to examples/example02/client/cljs/protos/org.hyperledger.chaincode.example02.proto diff --git a/examples/example02/client/sdk/src/example02/core.cljs b/examples/example02/client/cljs/src/example02/core.cljs similarity index 100% rename from examples/example02/client/sdk/src/example02/core.cljs rename to examples/example02/client/cljs/src/example02/core.cljs diff --git a/examples/example02/client/sdk/src/example02/hlc/core.cljs b/examples/example02/client/cljs/src/example02/hfc/core.cljs similarity index 100% rename from examples/example02/client/sdk/src/example02/hlc/core.cljs rename to examples/example02/client/cljs/src/example02/hfc/core.cljs diff --git a/examples/example02/client/sdk/src/example02/hlc/user.cljs b/examples/example02/client/cljs/src/example02/hfc/user.cljs similarity index 100% rename from examples/example02/client/sdk/src/example02/hlc/user.cljs rename to examples/example02/client/cljs/src/example02/hfc/user.cljs diff --git a/examples/example02/client/sdk/src/example02/main.cljs b/examples/example02/client/cljs/src/example02/main.cljs similarity index 100% rename from examples/example02/client/sdk/src/example02/main.cljs rename to examples/example02/client/cljs/src/example02/main.cljs diff --git a/examples/example02/client/sdk/src/example02/rpc.cljs b/examples/example02/client/cljs/src/example02/rpc.cljs similarity index 100% rename from examples/example02/client/sdk/src/example02/rpc.cljs rename to examples/example02/client/cljs/src/example02/rpc.cljs diff --git a/examples/example02/client/sdk/src/example02/util.cljs b/examples/example02/client/cljs/src/example02/util.cljs similarity index 100% rename from examples/example02/client/sdk/src/example02/util.cljs rename to examples/example02/client/cljs/src/example02/util.cljs diff --git a/examples/example02/client/lib/fabric-ca-client-0.1.0.tgz b/examples/example02/client/lib/fabric-ca-client-0.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..d0576119fd45b122ddb23cbaf7f88237029115f4 GIT binary patch literal 20625 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
    X95y$KB1jq;?0lq&i?CaBF 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", "Path to chaincode.car") + .action(function(options){ + return connect() + .then(function() { + return deploy({ + 'partyA': {'entity':'A', 'value':100}, + 'partyB': {'entity':'B', 'value':200}}, + options.path); + }) + .catch(function(err) { + console.log("error:" + err); + }); + }); + +program + .command('makepayment ') + .description('makepayment description') + .action(function(partySrc, partyDst, amount){ + return connect() + .then(function() { + return makePayment({ + 'partySrc': partySrc, + 'partyDst': partyDst, + 'amount': parseInt(amount)}); + }) + .catch(function(err) { + console.log("error:" + err); + }); + }); + +program + .command('checkbalance ') + .description('checkbalance description') + .action(function(id){ + return connect() + .then(function() { + return checkBalance({'id':id}); + }) + .then(function(result) { + console.log("balance:" + result.balance); + }) + .catch(function(err) { + console.log("error:" + err); + }); + }); + + +program.parse(process.argv); diff --git a/examples/example02/client/nodejs/lib/util.js b/examples/example02/client/nodejs/lib/util.js new file mode 100644 index 0000000..b2c56bd --- /dev/null +++ b/examples/example02/client/nodejs/lib/util.js @@ -0,0 +1,80 @@ +var hfc = require('fabric-client'); +var utils = require('fabric-client/lib/utils.js'); +var User = require('fabric-client/lib/User.js'); + +module.exports = { + setStateStore: function(client, path) { + return new Promise(function(resolve, reject) { + return hfc.newDefaultKeyValueStore({path: path}) + .then(function(store) { + client.setStateStore(store); + resolve(true); + }); + }); + }, + + getUser: function(client, cop, username, password) { + return client.getUserContext(username) + .then( + function(user) { + if (user && user.isEnrolled()) { + return Promise.resolve(user); + } else { + // need to enroll it with COP server + console.log("enrolling"); + return cop.enroll({ + enrollmentID: username, + enrollmentSecret: password + }).then( + function(enrollment) { + console.log("enrollment"); + var member = new User(username, client); + return member.setEnrollment(enrollment.key, enrollment.certificate) + .then(function() { + return client.setUserContext(member); + }); + } + ); + } + } + ); + }, + + intradelay: function() { + return new Promise(function(resolve, reject) { + setTimeout(resolve, 20000); + }); + }, + + processProposalResponse: function(chain, results) { + var proposalResponses = results[0]; + //logger.debug('deploy proposalResponses:'+JSON.stringify(proposalResponses)); + var proposal = results[1]; + var header = results[2]; + var all_good = true; + + for(var i in proposalResponses) { + let one_good = false; + + if (proposalResponses && + proposalResponses[0].response && + proposalResponses[0].response.status === 200) { + + one_good = true; + } + all_good = all_good & one_good; + } + + if (all_good) { + var request = { + proposalResponses: proposalResponses, + proposal: proposal, + header: header + }; + return chain.sendTransaction(request); + } else { + throw "bad result:" + results; + } + + } +}; diff --git a/examples/example02/client/nodejs/package.json b/examples/example02/client/nodejs/package.json new file mode 100644 index 0000000..7e3d369 --- /dev/null +++ b/examples/example02/client/nodejs/package.json @@ -0,0 +1,20 @@ +{ + "name": "chaintool-example02", + "version": "0.0.1", + "description": "", + "main": "client.js", + "dependencies": { + "protobufjs":"5.0.1", + "commander":"2.9.0", + "winston":"2.3.1" + }, + "files": [ + "protos", + "lib" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/examples/example02/client/rest/nodejs/appinit.proto b/examples/example02/client/nodejs/protos/appinit.proto similarity index 100% rename from examples/example02/client/rest/nodejs/appinit.proto rename to examples/example02/client/nodejs/protos/appinit.proto diff --git a/examples/example02/client/rest/nodejs/org.hyperledger.chaincode.example02.proto b/examples/example02/client/nodejs/protos/org.hyperledger.chaincode.example02.proto similarity index 100% rename from examples/example02/client/rest/nodejs/org.hyperledger.chaincode.example02.proto rename to examples/example02/client/nodejs/protos/org.hyperledger.chaincode.example02.proto diff --git a/examples/example02/client/rest/cljs/Makefile b/examples/example02/client/rest/cljs/Makefile deleted file mode 100644 index 7d75171..0000000 --- a/examples/example02/client/rest/cljs/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -SRCS = $(shell find src -type f) -LEIN = $(shell which lein || echo ../../../../../lein) - -all: client - -client: ./out/example02.js - -node_modules: project.clj - $(LEIN) npm install - -./out/example02.js: $(SRCS) node_modules Makefile - $(LEIN) cljsbuild once - @echo "Compilation complete: use \"node $@ --help\" for execution instructions" - -clean: - -@rm -rf ./out ||: - -@rm -rf node_modules ||: diff --git a/examples/example02/client/rest/cljs/project.clj b/examples/example02/client/rest/cljs/project.clj deleted file mode 100644 index 612798a..0000000 --- a/examples/example02/client/rest/cljs/project.clj +++ /dev/null @@ -1,24 +0,0 @@ -(defproject example02 "0.1.0-SNAPSHOT" - :min-lein-version "2.0.0" - :description "Clojurescript client for chaintool version of example02" - :url "http://example.com/FIXME" - :dependencies [[org.clojure/clojure "1.8.0"] - [org.clojure/clojurescript "1.8.34"] - [org.clojure/tools.cli "0.3.3"]] - :jvm-opts ^:replace ["-Xmx1g" "-server"] - :plugins [[lein-npm "0.6.1"] - [lein-cljsbuild "1.1.3"]] - :npm {:dependencies [[source-map-support "0.4.0"] - [protobufjs "5.0.1"]]} - :source-paths ["src" "target/classes"] - :clean-targets ["out" "release"] - :target-path "target" - :cljsbuild {:builds [{:id "example02" - :source-paths ["src"] - :compiler {:output-to "out/example02.js" - :output-dir "out" - :source-map true - :optimizations :none - :target :nodejs - :main "example02.main" - :pretty-print true}}]}) diff --git a/examples/example02/client/rest/cljs/src/example02/core.cljs b/examples/example02/client/rest/cljs/src/example02/core.cljs deleted file mode 100644 index 6f37d99..0000000 --- a/examples/example02/client/rest/cljs/src/example02/core.cljs +++ /dev/null @@ -1,43 +0,0 @@ -(ns example02.core - (:require [cljs.nodejs :as nodejs] - [example02.rpc :as rpc])) - -(def pb (nodejs/require "protobufjs")) -(def builder (.newBuilder pb)) - -(defn- loadproto [name] - (do - (.loadProtoFile pb (str "./" name ".proto") builder) - (.build builder name))) - -(def init (loadproto "appinit")) -(def app (loadproto "org.hyperledger.chaincode.example02")) - -(defn deploy [{:keys [args] :as options}] - (rpc/deploy (assoc options - :func "init" - :args (init.Init. args) - :cb (fn [resp] (println "Response:" resp))))) - -(defn make-payment [{:keys [args] :as options}] - (rpc/invoke (assoc options - :func "org.hyperledger.chaincode.example02/txn/1" - :args (app.PaymentParams. args) - :cb (fn [resp] (println "Response:" resp))))) - -(defn delete-account [{:keys [args] :as options}] - (rpc/invoke (assoc options - :func "org.hyperledger.chaincode.example02/txn/2" - :args (app.Entity. args) - :cb (fn [resp] (println "Response:" resp))))) - -(defn check-balance [{:keys [args] :as options}] - (rpc/query (assoc options - :func "org.hyperledger.chaincode.example02/query/1" - :args (app.Entity. args) - :cb (fn [resp] - (if (= (->> resp :result :status) "OK") - (let [result (->> resp :result :message app.BalanceResult.decode64)] - (println "Success: Balance =" (.-balance result))) - ;; else - (println "Failure:" resp)))))) diff --git a/examples/example02/client/rest/cljs/src/example02/main.cljs b/examples/example02/client/rest/cljs/src/example02/main.cljs deleted file mode 100644 index b0211c2..0000000 --- a/examples/example02/client/rest/cljs/src/example02/main.cljs +++ /dev/null @@ -1,98 +0,0 @@ -(ns example02.main - (:require [clojure.string :as string] - [cljs.nodejs :as nodejs] - [cljs.tools.cli :refer [parse-opts]] - [example02.core :as core])) - - -(nodejs/enable-util-print!) - -(def _commands - [["deploy" - {:fn core/deploy - :default-args #js {:partyA #js { - :entity "foo" - :value 100 - } - :partyB #js { - :entity "bar" - :value 100 - }}}] - ["make-payment" - {:fn core/make-payment - :default-args #js {:partySrc "foo" - :partyDst "bar" - :amount 10}}] - ["delete-account" - {:fn core/delete-account - :default-args #js {:id "foo"}}] - ["check-balance" - {:fn core/check-balance - :default-args #js {:id "foo"}}]]) - -(def commands (into {} _commands)) -(defn print-commands [] (->> commands keys vec print-str)) - -(def options - [[nil "--host HOST" "Host name" - :default "localhost"] - [nil "--port PORT" "Port number" - :default 5000 - :parse-fn #(js/parseInt %) - :validate [#(< 0 % 65536) "Must be a number between 0 and 65536"]] - ["-p" "--path PATH" "Path/URL to the chaincode (deploy only, mutually exclsive with -n)"] - ["-n" "--name NAME" "Name of the chaincode (mutually exclusive with -p)"] - ["-c" "--command CMD" (str "One of " (print-commands)) - :default "check-balance" - :validate [#(contains? commands %) (str "Supported commands: " (print-commands))]] - ["-a" "--args ARGS" "JSON formatted arguments to submit"] - ["-h" "--help"]]) - -(defn exit [status msg & rest] - (do - (apply println msg rest) - status)) - -(defn prep-usage [msg] (->> msg flatten (string/join \newline))) - -(defn usage [options-summary] - (prep-usage ["Usage: example02 [options]" - "" - "Options Summary:" - options-summary - "" - ])) - -(defn run [{:keys [path name command args] :as options}] - (let [desc (commands command) - _args (if (nil? args) (:default-args desc) (.parse js/JSON args))] - (cond - - (and (some? path) (some? name)) - (println "ERROR: -p and -n are mutually exclusive") - - (and (nil? path) (nil? name)) - (println "ERROR: Must specify either -p or -n") - - (and (some? path) (not= command "deploy")) - (println "ERROR: -p only valid with deploy command") - - :else - (let [id (if (some? path) #js {:path path} #js {:name name})] - (println (str "Running " command "(" (.stringify js/JSON _args) ")")) - ((:fn desc) (assoc options :id id :args _args)))))) - -(defn -main [& args] - (let [{:keys [options arguments errors summary]} (parse-opts args options)] - (cond - - (:help options) - (exit 0 (usage summary)) - - (not= errors nil) - (exit -1 "Error: " (string/join errors)) - - :else - (run options)))) - -(set! *main-cli-fn* -main) diff --git a/examples/example02/client/rest/cljs/src/example02/rpc.cljs b/examples/example02/client/rest/cljs/src/example02/rpc.cljs deleted file mode 100644 index d1a7cad..0000000 --- a/examples/example02/client/rest/cljs/src/example02/rpc.cljs +++ /dev/null @@ -1,45 +0,0 @@ -(ns example02.rpc - (:require [cljs.nodejs :as nodejs])) - -(def http (nodejs/require "http")) - -(defn- stringify [json] - (.stringify js/JSON json)) - -(defn- response-handler [cb resp] - (.setEncoding resp "utf8") - (.on resp "data" (fn [data] - (let [resp (js->clj (.parse js/JSON data) :keywordize-keys true)] - (cb (select-keys resp [:error :result])))))) - -(defn- post [{:keys [host port path method id func args cb]}] - (let [meta #js {:host host - :port port - :path path - :method "POST" - :headers #js {:Content-Type "application/json"}} - data (stringify - #js {:jsonrpc "2.0" - :method method - :params #js {:type 3 - :chaincodeID id - :ctorMsg #js {:function func - :args #js [(.toBase64 args)]}} - :id "1"}) - req (.request http meta (partial response-handler cb))] - - (println "HTTP POST:" (str "http://" host ":" port) "-" data) - (.write req data) - (.end req))) - -(defn- chaincode-post [args] - (post (assoc args :path "/chaincode"))) - -(defn deploy [args] - (chaincode-post (assoc args :method "deploy"))) - -(defn invoke [args] - (chaincode-post (assoc args :method "invoke"))) - -(defn query [args] - (chaincode-post (assoc args :method "query"))) diff --git a/examples/example02/client/rest/nodejs/index.js b/examples/example02/client/rest/nodejs/index.js deleted file mode 100644 index 069ae30..0000000 --- a/examples/example02/client/rest/nodejs/index.js +++ /dev/null @@ -1,101 +0,0 @@ -var http = require('http'); -var pb = require("protobufjs"); - -var builder = pb.newBuilder({ convertFieldsToCamelCase: true }); - -pb.loadProtoFile("./appinit.proto", builder); -var init = builder.build("appinit"); - -pb.loadProtoFile("./org.hyperledger.chaincode.example02.proto", builder); -var app = builder.build("org.hyperledger.chaincode.example02"); - -function Deploy(id, params) { - - invoke('deploy', id, 'init', new init.Init(params), function(res) { - res.setEncoding('utf8'); - res.on('data', function (chunk) { - var resp = JSON.parse(chunk); - console.log('Response: ' + chunk); - }); - - }); -} - -function CheckBalance(id, params) { - - invoke('query', id, 'org.hyperledger.chaincode.example02/query/1', new app.Entity(params), function(res) { - res.setEncoding('utf8'); - res.on('data', function (chunk) { - var resp = JSON.parse(chunk); - if (resp.result.status == "OK") { - var result = app.BalanceResult.decode64(resp.result.message); - console.log("BalanceResult: " + result.balance); - } else { - console.log('ERROR: ' + chunk); - } - }); - - }); -} - -function invoke(method, id, func, args, cb) { - var post_data = JSON.stringify({ - 'jsonrpc': '2.0', - 'method': method, - 'params': { - 'type': 3, - 'chaincodeID': id, - 'ctorMsg': { - 'function': func, - 'args':[args.toBase64()] - } - }, - "id": 1 - }); - console.log(post_data); - post(post_data, '/chaincode', cb); -} - -function post(pdata, path, cb) { - var post_options = { - host: 'localhost', - port: '5000', - path: path, - method: 'POST', - headers: { - 'Content-Type': 'application/json' - } - }; - - var post_req = http.request(post_options, cb); - - // post the data - post_req.write(pdata); - post_req.end(); - -} - -Deploy( - { - 'name': 'mycc' - }, - { - 'partyA': { - 'entity': 'foo', - 'value': 100 - }, - 'partyB': { - 'entity': 'bar', - 'value': 100 - } - } -); - -CheckBalance( - { - 'name': 'mycc' - }, - { - "id": "foo" - } -); diff --git a/examples/example02/client/rest/nodejs/package.json b/examples/example02/client/rest/nodejs/package.json deleted file mode 100644 index 4f2cb22..0000000 --- a/examples/example02/client/rest/nodejs/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "protobuf", - "version": "1.0.0", - "description": "", - "main": "index.js", - "dependencies": { - "protobufjs":"5.0.1" - }, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC" -} diff --git a/examples/example02/client/sdk/appinit.proto b/examples/example02/client/sdk/appinit.proto deleted file mode 100644 index d92e13d..0000000 --- a/examples/example02/client/sdk/appinit.proto +++ /dev/null @@ -1,19 +0,0 @@ -// -// Generated by chaintool. DO NOT EDIT!! -// - -syntax = "proto3"; - -package appinit; - -message Init { - Party partyA = 1; - Party partyB = 2; -} - -message Party { - string entity = 1; - int32 value = 2; -} - - diff --git a/examples/example02/client/sdk/org.hyperledger.chaincode.example02.proto b/examples/example02/client/sdk/org.hyperledger.chaincode.example02.proto deleted file mode 100644 index 6a51ace..0000000 --- a/examples/example02/client/sdk/org.hyperledger.chaincode.example02.proto +++ /dev/null @@ -1,29 +0,0 @@ -// -// Generated by chaintool. DO NOT EDIT!! -// - -syntax = "proto3"; - -package org.hyperledger.chaincode.example02; - -message BalanceResult { - int32 balance = 1; -} - -message Entity { - string id = 1; -} - -message PaymentParams { - string partySrc = 1; - string partyDst = 2; - int32 amount = 3; -} - - -// -// Available RPC functions exported by this interface -// -// void MakePayment(PaymentParams) -> org.hyperledger.chaincode.example02/txn/1 -// void DeleteAccount(Entity) -> org.hyperledger.chaincode.example02/txn/2 -// BalanceResult CheckBalance(Entity) -> org.hyperledger.chaincode.example02/query/1 diff --git a/examples/invoker/src/chaincode/chaincode.go b/examples/invoker/src/chaincode/chaincode.go index ecf09c1..66695e9 100755 --- a/examples/invoker/src/chaincode/chaincode.go +++ b/examples/invoker/src/chaincode/chaincode.go @@ -17,7 +17,7 @@ specific language governing permissions and limitations under the License. */ -package chaincode +package main import ( "fmt" @@ -90,7 +90,7 @@ func (t *ChaincodeExample) CheckBalance(stub shim.ChaincodeStubInterface, param func main() { self := &ChaincodeExample{} - interfaces := ccs.Interfaces { + interfaces := ccs.Interfaces{ "org.hyperledger.chaincode.example02": self, "appinit": self, } diff --git a/examples/invoker/src/interfaces/org.hyperledger.chaincode.example02.cci b/examples/invoker/src/interfaces/org.hyperledger.chaincode.example02.cci index ad02021..dc0a39f 100644 --- a/examples/invoker/src/interfaces/org.hyperledger.chaincode.example02.cci +++ b/examples/invoker/src/interfaces/org.hyperledger.chaincode.example02.cci @@ -13,11 +13,8 @@ message BalanceResult { int32 balance = 1; } -transactions { +functions { void MakePayment(PaymentParams) = 1; void DeleteAccount(Entity) = 2; -} - -queries { - BalanceResult CheckBalance(Entity) = 1; + BalanceResult CheckBalance(Entity) = 3; } diff --git a/examples/parameterless/src/interfaces/org.hyperledger.chaincode.example.parameterless.cci b/examples/parameterless/src/interfaces/org.hyperledger.chaincode.example.parameterless.cci index 7fa5a9c..503262f 100644 --- a/examples/parameterless/src/interfaces/org.hyperledger.chaincode.example.parameterless.cci +++ b/examples/parameterless/src/interfaces/org.hyperledger.chaincode.example.parameterless.cci @@ -3,6 +3,6 @@ message MyReturnType { string foo = 1; } -queries { +functions { MyReturnType TestParameterless() = 1; } diff --git a/examples/sample_syscc/interfaces/org.hyperledger.chaincode.system.sample.cci b/examples/sample_syscc/interfaces/org.hyperledger.chaincode.system.sample.cci index ad02021..dc0a39f 100644 --- a/examples/sample_syscc/interfaces/org.hyperledger.chaincode.system.sample.cci +++ b/examples/sample_syscc/interfaces/org.hyperledger.chaincode.system.sample.cci @@ -13,11 +13,8 @@ message BalanceResult { int32 balance = 1; } -transactions { +functions { void MakePayment(PaymentParams) = 1; void DeleteAccount(Entity) = 2; -} - -queries { - BalanceResult CheckBalance(Entity) = 1; + BalanceResult CheckBalance(Entity) = 3; } diff --git a/project.clj b/project.clj index 0669530..82e4ad8 100644 --- a/project.clj +++ b/project.clj @@ -1,6 +1,6 @@ -(defproject chaintool "0.10.0" - :description "hyperledger chaincode tool" - :url "https://github.com/ghaskins/chaintool" +(defproject chaintool "0.10.1" + :description "Hyperledger Fabric chaincode tool" + :url "https://github.com/hyperledger/fabric-chaintool" :license {:name "Apache License" :url "http://www.apache.org/licenses/LICENSE-2.0.txt"} :min-lein-version "2.0.0" diff --git a/resources/generators/golang.stg b/resources/generators/golang.stg index 8c5d770..4246fd1 100755 --- a/resources/generators/golang.stg +++ b/resources/generators/golang.stg @@ -21,6 +21,7 @@ import ( "github.com/hyperledger/fabric/core/system_chaincode/api" "github.com/hyperledger/fabric/core/chaincode/shim" + pb "github.com/hyperledger/fabric/protos/peer" "/ccs/api" ) @@ -31,39 +32,51 @@ type stubHandler struct { dispatchers Dispatchers } -var txnre = regexp.MustCompile("([a-zA-Z0-9.]*)/txn/([0-9]*)") -var queryre = regexp.MustCompile("([a-zA-Z0-9.]*)/query/([0-9]*)") +var functionspec = regexp.MustCompile("([a-zA-Z0-9.]*)/fcn/([0-9]*)") // Initialization function, called only once -func (self *stubHandler) Init(stub shim.ChaincodeStubInterface) ([]byte, error) { +func (self *stubHandler) Init(stub shim.ChaincodeStubInterface) pb.Response { function, args := stub.GetFunctionAndParameters() if len(args) != 1 { - return nil, errors.New("Expected exactly one argument") + return shim.Error("Expected exactly one argument") } if function != "init" { - return nil, errors.New("Function must be \"init\"") + return shim.Error("Function must be \"init\"") } dispatcher, ok := self.dispatchers["appinit"] if !ok { - return nil, errors.New("Interface not found") + return shim.Error("Interface not found") } - return dispatcher.DispatchTxn(stub, 1, args[0]) + return dispatcher.Dispatch(stub, 1, args[0]) } // Callback representing the invocation of a chaincode - +func (self *stubHandler) Invoke(stub shim.ChaincodeStubInterface) pb.Response { -// Callback representing the query of a chaincode - + function, args := stub.GetFunctionAndParameters() -func (self *stubHandler) decodeFunction(re *regexp.Regexp, function string) (api.Dispatcher, int, error) { + var params string; - spec := re.FindAllStringSubmatch(function, -1) + if len(args) > 0 { + params = args[0] + } + + dispatcher, index, err := self.decodeFunction(function) + if err != nil { + return shim.Error(err.Error()) + } + + return dispatcher.Dispatch(stub, index, params) +} + +func (self *stubHandler) decodeFunction(function string) (api.Dispatcher, int, error) { + + spec := functionspec.FindAllStringSubmatch(function, -1) if spec == nil { return nil, 0, errors.New("Could not parse function name") } @@ -73,7 +86,7 @@ func (self *stubHandler) decodeFunction(re *regexp.Regexp, function string) (api return nil, 0, errors.New("Interface not found") } - index, err := strconv.Atoi(spec[0][2]) + index, err := strconv.Atoi(spec[0][2]) if err != nil { return nil, 0, errors.New("Could not convert function index") } @@ -145,11 +158,11 @@ package api import ( "errors" "github.com/hyperledger/fabric/core/chaincode/shim" + pb "github.com/hyperledger/fabric/protos/peer" ) type Dispatcher interface { - DispatchTxn(stub shim.ChaincodeStubInterface, function int, params string) ([]byte, error) - DispatchQuery(stub shim.ChaincodeStubInterface, function int, params string) ([]byte, error) + Dispatch(stub shim.ChaincodeStubInterface, function int, params string) pb.Response } type Factory interface { @@ -258,14 +271,14 @@ package import ( "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric/core/chaincode/shim" + pb "github.com/hyperledger/fabric/protos/peer" "/ccs/api" "encoding/base64" - "errors" + "fmt" ) type CCInterface interface { - - + } @@ -286,27 +299,17 @@ func (self *factoryImpl) Create(intf interface{}) (api.Dispatcher, error) { return &stubImpl{intf: intf.(CCInterface)}, nil } -func (self *stubImpl) DispatchTxn(stub shim.ChaincodeStubInterface, function int, params string) ([]byte, error) { +func (self *stubImpl) Dispatch(stub shim.ChaincodeStubInterface, function int, params string) pb.Response { // Handle different functions switch { - + default: - return nil, errors.New("Received unknown function invocation") - } -} - -func (self *stubImpl) DispatchQuery(stub shim.ChaincodeStubInterface, function int, params string) ([]byte, error) { - // Handle different functions - switch { - - default: - return nil, errors.New("Received unknown function invocation") + return shim.Error("Received unknown function invocation") } } /* Server stubs */ - - + - + >> -compositename(txn, intf, func) ::= "\"/txnquery/\"" +compositename(intf, func) ::= "\"/fcn/\"" implementservers(intf, functions) ::= " }; separator=\"\n\">" -implementclients(txn, intf, functions) ::= " }; separator=\"\n\">" -dispatchfunctions(txn, intf, functions) ::= " }; separator=\"\n\">" +implementclients(intf, functions) ::= " }; separator=\"\n\">" +dispatchfunctions(intf, functions) ::= " }; separator=\"\n\">" declarefunctions(intf, functions) ::= << (shim.ChaincodeStubInterface, *) (*, error)error }; separator="\n"> >> -dispatchfunction(txn, intf, func) ::= +dispatchfunction(intf, func) ::= << case function == : return self.proxy(stub, params) >> -implementhandler(txn) ::= -<< -func (self *stubHandler) InvokeQuery(stub shim.ChaincodeStubInterface) ([]byte, error) { - - function, args := stub.GetFunctionAndParameters() - - var params string; - - if len(args) > 0 { - params = args[0] - } - - dispatcher, index, err := self.decodeFunction(txnrequeryre, function) - if err != nil { - return nil, err - } - - return dispatcher.DispatchTxnQuery(stub, index, params) -} ->> - implementserver(intf, func) ::= << -func (self *stubImpl) proxy(stub shim.ChaincodeStubInterface, _params string) ([]byte, error) { +func (self *stubImpl) proxy(stub shim.ChaincodeStubInterface, _params string) pb.Response { var err error; @@ -395,67 +377,77 @@ func (self *stubImpl) proxy(stub shim.ChaincodeStubInterface, _params params := &{} _pbinput, err := base64.StdEncoding.DecodeString(_params) if (err != nil) { - return nil, err + return shim.Error(fmt.Sprintf("base64 decode error: %s", err)) } err = proto.Unmarshal(_pbinput, params) if (err != nil) { - return nil, err + return shim.Error(fmt.Sprintf("protobuf unmarshal error: %s", err)) } result, err := err = self.intf.(stub, params) if (err != nil) { - return nil, err + return shim.Error(err.Error()) } _pboutput, err := proto.Marshal(result) if (err != nil) { - return nil, err + return shim.Error(fmt.Sprintf("protobuf marshal error: %s", err)) } _result := base64.StdEncoding.EncodeToString(_pboutput) - return []byte(_result), nil + return shim.Success([]byte(_result)) - return nil, nil + return shim.Success(nil) } >> -implementclient(txn, intf, func) ::= +implementclient(intf, func) ::= << func (stub shim.ChaincodeStubInterface, chaincodeName string, params *) <\\> (*, error)error { - args := make([]string, 1) + + args := make([][]byte, 2) + + args := make([][]byte, 1) + var err error + args[0] = []byte() + _pboutput, err := proto.Marshal(params) if (err != nil) { return nil, err } - args[0] = base64.StdEncoding.EncodeToString(_pboutput) + args[1] = make([]byte, base64.StdEncoding.EncodedLen(len(_pboutput))) + base64.StdEncoding.Encode(args[1], _pboutput) - _result, err :=_, err = stub.InvokeQueryChaincode(chaincodeName, , args) - - - result := &{} - _pbinput, err := base64.StdEncoding.DecodeString(string(_result)) - if (err != nil) { - return nil, err - } - err = proto.Unmarshal(_pbinput, result) - if (err != nil) { - return nil, err + resp := stub.InvokeChaincode(chaincodeName, args) + if resp.Status \< shim.ERROR { + + result := &{} + _pbinput, err := base64.StdEncoding.DecodeString(string(resp.Payload)) + if (err != nil) { + return nil, fmt.Errorf("Error decoding base64 return value: %s", err) + } + err = proto.Unmarshal(_pbinput, result) + if (err != nil) { + return nil, fmt.Errorf("Error unmarshalling return value: %s", err) + } + return result, nil + + return nil + } - return result, nil - - return err - + + return nil, fmt.Errorf("RPC failure: %s", resp.Message) } >> diff --git a/resources/metadata/org.hyperledger.chaintool.meta.cci b/resources/metadata/org.hyperledger.chaintool.meta.cci index 319d34c..8d76ca0 100644 --- a/resources/metadata/org.hyperledger.chaintool.meta.cci +++ b/resources/metadata/org.hyperledger.chaintool.meta.cci @@ -28,7 +28,7 @@ message Facts { repeated Fact facts = 1; } -queries { +functions { Interfaces GetInterfaces(GetInterfacesParams) = 1; InterfaceDescriptor GetInterface(GetInterfaceParams) = 2; Facts GetFacts(GetFactsParams) = 3; diff --git a/resources/parsers/interface/grammar.bnf b/resources/parsers/interface/grammar.bnf index a3e6854..b6c6f01 100644 --- a/resources/parsers/interface/grammar.bnf +++ b/resources/parsers/interface/grammar.bnf @@ -1,5 +1,5 @@ -interface ::= ( message | enum )* transactions? queries? +interface ::= ( message | enum )* functions? message ::= <"message"> ident messageBody @@ -9,10 +9,9 @@ enumField ::= enumName <"="> enumValue <";"> ::= ident ::= intLit -transactions ::= <"transactions"> functions -queries ::= <"queries"> functions +functions ::= <"functions"> functionblock - ::= <"{"> function* <"}"> + ::= <"{"> function* <"}"> function ::= rettype functionName <"("> param? <")"> <"="> index <";"> functionName := ident rettype ::= ident diff --git a/src/chaintool/build/core.clj b/src/chaintool/build/core.clj index d063540..c464633 100644 --- a/src/chaintool/build/core.clj +++ b/src/chaintool/build/core.clj @@ -16,7 +16,15 @@ [chaintool.platforms.api :as platforms.api]) (:refer-clojure :exclude [compile])) -(defn compile [{:keys [config] :as params}] + +(defn- run [fcn {:keys [config] :as params}] (when-let [platform (platforms.core/find config)] - ;; generate platform output (shim, protobufs, etc) - (platforms.api/build platform params))) + (fcn platform params))) + +;; generate platform output (shim, protobufs, etc) +(defn compile [params] + (run platforms.api/build params)) + +;; display environment variables used for build +(defn env [params] + (run platforms.api/env params)) diff --git a/src/chaintool/build/interface.clj b/src/chaintool/build/interface.clj index 1d33952..967f5c7 100644 --- a/src/chaintool/build/interface.clj +++ b/src/chaintool/build/interface.clj @@ -119,9 +119,9 @@ (if-let [results (ast/find term ast)] (getfunctions results))) -(defn gettransactions [ast] (getgeneric ast :transactions)) -(defn getqueries [ast] (getgeneric ast :queries)) -(defn getallfunctions [ast] (into {} (vector (gettransactions ast) (getqueries ast)))) +(defn getallfunctions [ast] (->> (getgeneric ast :functions) + vector + (into {}))) (defn find-definition-in-local [name ast] (let [start (zip/leftmost ast)] @@ -368,8 +368,8 @@ (let [ast (interfaces "appinit")] (cond - ;; We do not allow any explicit transactions or queries in the project interface - (or (ast/find :transactions ast) (ast/find :queries ast)) + ;; We do not allow any explicit functions in the project interface + (ast/find :functions ast) (str "appinit.cci: illegal RPCs detected") ;; We cannot continue if the user didnt supply a message "Init" which will diff --git a/src/chaintool/core.clj b/src/chaintool/core.clj index 0d0e3ea..c4c4f73 100644 --- a/src/chaintool/core.clj +++ b/src/chaintool/core.clj @@ -21,6 +21,7 @@ [chaintool.subcommands.package :as packagecmd] [chaintool.subcommands.proto :as protocmd] [chaintool.subcommands.unpack :as unpackcmd] + [chaintool.subcommands.env :as envcmd] [chaintool.util :as util] [clojure.string :as string] [clojure.tools.cli :refer [parse-opts]] @@ -78,6 +79,10 @@ :validate (fn [options arguments] (= (count arguments) 1)) :options common-options} + {:name "env" :desc "Display variables used in the build environment" + :handler envcmd/run + :options common-path-options} + {:name "proto" :desc "Compiles a CCI file to a .proto" :handler protocmd/run :arguments "path/to/file.cci" diff --git a/src/chaintool/platforms/api.clj b/src/chaintool/platforms/api.clj index 47c9016..677252a 100644 --- a/src/chaintool/platforms/api.clj +++ b/src/chaintool/platforms/api.clj @@ -15,6 +15,8 @@ (ns chaintool.platforms.api) (defprotocol Platform + ;; Displays environment variables relevant to the build environment + (env [this params]) ;; Compiles the platform (build [this params]) ;; Cleans any previous builds of the platform diff --git a/src/chaintool/platforms/golang/core.clj b/src/chaintool/platforms/golang/core.clj index d762e53..276418f 100644 --- a/src/chaintool/platforms/golang/core.clj +++ b/src/chaintool/platforms/golang/core.clj @@ -34,7 +34,7 @@ ;; (deftype Function [^String rettype ^String name ^String param ^Integer index]) -(deftype Interface [^String name ^String package ^String packageCamel ^String packagepath ^ArrayList transactions ^ArrayList queries]) +(deftype Interface [^String name ^String package ^String packageCamel ^String packagepath ^ArrayList functions]) (deftype InterfaceDefinition [^String name ^String bytes]) (deftype Fact [^String name ^String value]) @@ -101,9 +101,8 @@ (build-function v)))) (defn- build-interface [base name interface] - (let [transactions (build-functions (:transactions interface)) - queries (build-functions (:queries interface))] - (vector name (->Interface name (package-name name) (package-camel name) (package-path base name) transactions queries)))) + (let [functions (build-functions (:functions interface))] + (vector name (->Interface name (package-name name) (package-camel name) (package-path base name) functions)))) (defn- build-interfaces [base interfaces] (into {} (map (fn [[name interface]] (build-interface base name interface)) interfaces))) @@ -251,7 +250,7 @@ (emit-server-stub base name functions opath)))) ;; and now special case the appinit interface - (emit-server-stub base "appinit" {:transactions {1 {:rettype "void", :functionName "Init", :param "Init", :index 1, :subType nil, :typeName nil}}} opath)) + (emit-server-stub base "appinit" {:functions {1 {:rettype "void", :functionName "Init", :param "Init", :index 1, :subType nil, :typeName nil}}} opath)) ;; generate our client stubs (dorun (for [name (intf/getconsumes config)] diff --git a/src/chaintool/platforms/golang/system.clj b/src/chaintool/platforms/golang/system.clj index deff5f8..5ad428a 100644 --- a/src/chaintool/platforms/golang/system.clj +++ b/src/chaintool/platforms/golang/system.clj @@ -41,6 +41,11 @@ (deftype GolangSystemPlatform [] platforms.api/Platform + ;;----------------------------------------------------------------- + ;; env - Emits the GOPATH used for building system chaincode + ;;----------------------------------------------------------------- + (env [_ _]) + ;;----------------------------------------------------------------- ;; build - generates all golang platform artifacts within the ;; default location in the build area diff --git a/src/chaintool/platforms/golang/userspace.clj b/src/chaintool/platforms/golang/userspace.clj index 6d0bdcb..9ca6e4f 100644 --- a/src/chaintool/platforms/golang/userspace.clj +++ b/src/chaintool/platforms/golang/userspace.clj @@ -30,6 +30,12 @@ (deftype GolangUserspacePlatform [] platforms.api/Platform + ;;----------------------------------------------------------------- + ;; env - Emits the GOPATH used for building golang chaincode + ;;----------------------------------------------------------------- + (env [_ {:keys [path]}] + (println (str "GOPATH=" (buildgopath path)))) + ;;----------------------------------------------------------------- ;; build - generates all golang platform artifacts within the ;; default location in the build area diff --git a/src/chaintool/protobuf/generate.clj b/src/chaintool/protobuf/generate.clj index 54efbb2..338903e 100644 --- a/src/chaintool/protobuf/generate.clj +++ b/src/chaintool/protobuf/generate.clj @@ -44,14 +44,11 @@ (conj defs loc) defs)))))) -(def function-class - {:transactions "txn" - :queries "query"}) - (defn- getallfunctions [ast] - (flatten (for [[type functions] (intf/getallfunctions ast)] - (for [[_ func] functions] - (assoc func :type (function-class type)))))) + (let [{:keys [functions]} (intf/getallfunctions ast)] + (-> functions + vals + flatten))) ;;----------------------------------------------------------------- ;; buildX - build our ST friendly objects from the AST @@ -120,8 +117,8 @@ (mapv vec) (into {}))) -(defn- buildfunction [name {:keys [rettype functionName param index type] :as ast}] - (let [key (str name "/" type "/" index)] +(defn- buildfunction [name {:keys [rettype functionName param index] :as ast}] + (let [key (str name "/fcn/" index)] (->Function key rettype functionName param))) (defn- buildfunctions [name ast] diff --git a/src/chaintool/subcommands/env.clj b/src/chaintool/subcommands/env.clj new file mode 100644 index 0000000..0bfefce --- /dev/null +++ b/src/chaintool/subcommands/env.clj @@ -0,0 +1,19 @@ +;; Licensed under the Apache License, Version 2.0 (the "License"); +;; you may not use this file except in compliance with the License. +;; You may obtain a copy of the License at +;; +;; http://www.apache.org/licenses/LICENSE-2.0 +;; +;; Unless required by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS IS" BASIS, +;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;; See the License for the specific language governing permissions and +;; limitations under the License. + +(ns chaintool.subcommands.env + (:require [chaintool.config.util :as config.util] + [chaintool.build.core :as build.core])) + +(defn run [options args] + (let [[path config] (config.util/load-from-options options)] + (build.core/env {:path path :config config}))) diff --git a/test/chaintool/build/test_interface.clj b/test/chaintool/build/test_interface.clj index ec944ac..d0ac037 100644 --- a/test/chaintool/build/test_interface.clj +++ b/test/chaintool/build/test_interface.clj @@ -150,7 +150,7 @@ (def example-no-parameters " - queries { + functions { string Parameterless() = 1; } diff --git a/test/chaintool/protobuf/test_generate.clj b/test/chaintool/protobuf/test_generate.clj index 2742913..9ac21e9 100644 --- a/test/chaintool/protobuf/test_generate.clj +++ b/test/chaintool/protobuf/test_generate.clj @@ -96,7 +96,7 @@ (def parameterless-function (zip/vector-zip - [:interface [:queries [:function [:rettype "string"] [:functionName "Parameterless"] [:index "1"]]]])) + [:interface [:functions [:function [:rettype "string"] [:functionName "Parameterless"] [:index "1"]]]])) (deftest parameterless-test (let [result (round-about parameterless-function)]