diff --git a/docs/API/AttributesUsage.md b/docs/API/AttributesUsage.md deleted file mode 100644 index c928b10db0b..00000000000 --- a/docs/API/AttributesUsage.md +++ /dev/null @@ -1,248 +0,0 @@ -# Attributes usage - -## Overview - -The Attributes feature allows chaincode to make use of extended data in a transaction certificate. These attributes are certified by the Attributes Certificate Authority (ACA) so the chaincode can trust in the authenticity of the attributes' values. - -To view complete documentation about attributes design please read ['Attributes support'](../tech/attributes.md). - -## Use case: Authorizable counter - -A common use case for the Attributes feature is Attributes Based Access Control (ABAC) which allows specific permissions to be granted to a chaincode invoker based on attribute values carried in the invoker's certificate. - -['Authorizable counter'](../../examples/chaincode/go/authorizable_counter/authorizable_counter.go) is a simple example of ABAC, in this case only invokers whose "position" attribute has the value 'Software Engineer' will be able to increment the counter. On the other hand any invoker will be able to read the counter value. - -In order to implement this example we used ['VerifyAttribyte' ](https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim#ChaincodeStub.VerifyAttribute) function to check the attribute value from the chaincode code. - -``` -isOk, _ := stub.VerifyAttribute("position", []byte("Software Engineer")) // Here the ABAC API is called to verify the attribute, just if the value is verified the counter will be incremented. -if isOk { - // Increment counter code -} -``` - -The same behavior can be achieved by making use of ['Attribute support'](https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim/crypto/attr) API, in this case an attribute handler must be instantiated. - -``` -attributesHandler, _ := attr.NewAttributesHandlerImpl(stub) -isOk, _ := attributesHandler.VerifyAttribute("position", []byte("Software Engineer")) -if isOk { - // Increment counter code -} -``` -If attributes are accessed more than once, using `attributeHandler` is more efficient since the handler makes use of a cache to store values and keys. - -In order to get the attribute value, in place of just verifying it, the following code can be used: - -``` -attributesHandler, _ := attr.NewAttributesHandlerImpl(stub) -value, _ := attributesHandler.GetValue("position") -``` - -## Enabling attributes - -To make use of this feature the following property has to be set in the membersrvc.yaml file: - - -- aca.enabled = true - -Another way is using environment variables: - -``` -MEMBERSRVC_CA_ACA_ENABLED=true ./membersrvc -``` - -## Enabling attributes encryption* - -In order to make use of attributes encryption the following property has to be set in the membersrvc.yaml file: - -- tca.attribute-encryption.enabled = true - -Or using environment variables: - -``` -MEMBERSRVC_CA_ACA_ENABLED=true MEMBERSRVC_CA_TCA_ATTRIBUTE-ENCRYPTION_ENABLED=true ./membersrvc -``` - -### Deploy API making use of attributes - -#### CLI -``` -$ ./peer chaincode deploy --help -Deploy the specified chaincode to the network. - -Usage: - peer chaincode deploy [flags] - -Global Flags: - -a, --attributes="[]": User attributes for the chaincode in JSON format - -c, --ctor="{}": Constructor message for the chaincode in JSON format - -l, --lang="golang": Language the chaincode is written in - --logging-level="": Default logging level and overrides, see core.yaml for full syntax - -n, --name="": Name of the chaincode returned by the deploy transaction - -p, --path="": Path to chaincode - --test.coverprofile="coverage.cov": Done - -t, --tid="": Name of a custom ID generation algorithm (hashing and decoding) e.g. sha256base64 - -u, --username="": Username for chaincode operations when security is enabled - -v, --version[=false]: Display current version of fabric peer server -``` -To deploy a chaincode with attributes "company" and "position" it should be written in the following way: - -``` -./peer chaincode deploy -u userName -n mycc -c '{"Function":"init", "Args": []}' -a '["position", "company"]' - -``` - -Or: - -``` -./peer chaincode deploy -u userName -n mycc -c '{"Args": ["init"]}' -a '["position", "company"]' - -``` - -#### REST - -``` -POST host:port/chaincode - -{ - "jsonrpc": "2.0", - "method": "deploy", - "params": { - "type": 1, - "chaincodeID":{ - "name": "mycc" - }, - "input": { - "function":"init", - "args":[] - } - "attributes": ["position", "company"] - }, - "id": 1 -} -``` - -### Invoke API making use of attributes - -#### CLI -``` -$ ./peer chaincode invoke --help -Invoke the specified chaincode. - -Usage: - peer chaincode invoke [flags] - -Global Flags: - -a, --attributes="[]": User attributes for the chaincode in JSON format - -c, --ctor="{}": Constructor message for the chaincode in JSON format - -l, --lang="golang": Language the chaincode is written in - --logging-level="": Default logging level and overrides, see core.yaml for full syntax - -n, --name="": Name of the chaincode returned by the deploy transaction - -p, --path="": Path to chaincode - --test.coverprofile="coverage.cov": Done - -t, --tid="": Name of a custom ID generation algorithm (hashing and decoding) e.g. sha256base64 - -u, --username="": Username for chaincode operations when security is enabled - -v, --version[=false]: Display current version of fabric peer server -``` -To invoke "autorizable counter" with attributes "company" and "position" it should be written as follows: - -``` -./peer chaincode invoke -u userName -n mycc -c '{"Function":"increment", "Args": []}' -a '["position", "company"]' - -``` - -Or: - -``` -./peer chaincode invoke -u userName -n mycc -c '{"Args": ["increment"]}' -a '["position", "company"]' - -``` - -#### REST - -``` -POST host:port/chaincode - -{ - "jsonrpc": "2.0", - "method": "invoke", - "params": { - "type": 1, - "chaincodeID":{ - "name": "mycc" - }, - "ctorMsg": { - "function":"increment", - "args":[] - } - "attributes": ["position", "company"] - }, - "id": 1 -} -``` - -### Query API making use of attributes - -#### CLI -``` -$ ./peer chaincode query --help -Query using the specified chaincode. - -Usage: - peer chaincode query [flags] - -Flags: - -x, --hex[=false]: If true, output the query value byte array in hexadecimal. Incompatible with --raw - -r, --raw[=false]: If true, output the query value as raw bytes, otherwise format as a printable string - - -Global Flags: - -a, --attributes="[]": User attributes for the chaincode in JSON format - -c, --ctor="{}": Constructor message for the chaincode in JSON format - -l, --lang="golang": Language the chaincode is written in - --logging-level="": Default logging level and overrides, see core.yaml for full syntax - -n, --name="": Name of the chaincode returned by the deploy transaction - -p, --path="": Path to chaincode - --test.coverprofile="coverage.cov": Done - -t, --tid="": Name of a custom ID generation algorithm (hashing and decoding) e.g. sha256base64 - -u, --username="": Username for chaincode operations when security is enabled - -v, --version[=false]: Display current version of fabric peer server -``` -To query "autorizable counter" with attributes "company" and "position" it should be written in this way: - -``` -./peer chaincode query -u userName -n mycc -c '{"Function":"read", "Args": []}' -a '["position", "company"]' - -``` - -Or: - -``` -./peer chaincode query -u userName -n mycc -c '{"Args": ["read"]}' -a '["position", "company"]' - -``` - -#### REST - -``` -POST host:port/chaincode - -{ - "jsonrpc": "2.0", - "method": "query", - "params": { - "type": 1, - "chaincodeID":{ - "name": "mycc" - }, - "ctorMsg": { - "function":"read", - "args":[] - } - "attributes": ["position", "company"] - }, - "id": 1 -} -``` -* Attributes encryption is not yet available. diff --git a/docs/API/CLI.md b/docs/API/CLI.md deleted file mode 100644 index 7ef7c0bf0c0..00000000000 --- a/docs/API/CLI.md +++ /dev/null @@ -1,78 +0,0 @@ -# Command-line Interface (CLI) - -To view the currently available CLI commands, execute the following: - -``` - cd /opt/gopath/src/github.com/hyperledger/fabric - build/bin/peer -``` - -You will see output similar to the example below (**NOTE:** rootcommand below -is hardcoded in [main.go](https://github.com/hyperledger/fabric/blob/master/main.go). -Currently, the build will create a *peer* executable file). - -``` - Usage: - peer [flags] - peer [command] - - Available Commands: - version Print fabric peer version. - node node specific commands. - network network specific commands. - chaincode chaincode specific commands. - help Help about any command - - Flags: - -h, --help[=false]: help for peer - --logging-level="": Default logging level and overrides, see core.yaml for full syntax - --test.coverprofile="coverage.cov": Done - -v, --version[=false]: Show current version number of fabric peer server - - - Use "peer [command] --help" for more information about a command. - -``` - -The `peer` command supports several subcommands and flags, as shown above. To -facilitate its use in scripted applications, the `peer` command always -produces a non-zero return code in the event of command failure. Upon success, -many of the subcommands produce a result on **stdout** as shown in the table -below: - -Command | **stdout** result in the event of success ---- | --- -`version` | String form of `peer.version` defined in [core.yaml](https://github.com/hyperledger/fabric/blob/master/peer/core.yaml) -`node start` | N/A -`node status` | String form of [StatusCode](https://github.com/hyperledger/fabric/blob/master/protos/server_admin.proto#L36) -`node stop` | String form of [StatusCode](https://github.com/hyperledger/fabric/blob/master/protos/server_admin.proto#L36) -`network login` | N/A -`network list` | The list of network connections to the peer node. -`chaincode deploy` | The chaincode container name (hash) required for subsequent `chaincode invoke` and `chaincode query` commands -`chaincode invoke` | The transaction ID (UUID) -`chaincode query` | By default, the query result is formatted as a printable -string. Command line options support writing this value as raw bytes (-r, --raw), -or formatted as the hexadecimal representation of the raw bytes (-x, --hex). If -the query response is empty then nothing is output. - -## Deploy a Chaincode - -Deploy creates the docker image for the chaincode and subsequently deploys the -package to the validating peer. An example is below. - -``` -peer chaincode deploy -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' -``` -Or: - -``` -peer chaincode deploy -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args": ["init", "a","100", "b", "200"]}' -``` - -The response to the chaincode deploy command will contain the chaincode -identifier (hash) which will be required on subsequent `chaincode invoke` -and `chaincode query` commands in order to uniquely identify the deployed -chaincode. - -**Note:** If your GOPATH environment variable contains more than one element, -the chaincode must be found in the first one or deployment will fail. diff --git a/docs/API/ChaincodeAPI.md b/docs/API/ChaincodeAPI.md deleted file mode 100644 index d3748096fa3..00000000000 --- a/docs/API/ChaincodeAPI.md +++ /dev/null @@ -1,5 +0,0 @@ -# Chaincode APIs - -When the `Init`, `Invoke` or `Query` function of a chaincode is called, the fabric passes the `stub *shim.ChaincodeStub` parameter. This `stub` can be used to call APIs to access to the ledger services, transaction context, or to invoke other chaincodes. - -The current APIs are defined in the [shim package](https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim), generated by `godoc`. However, it includes functions from [chaincode.pb.go](https://github.com/hyperledger/fabric/blob/master/core/chaincode/shim/chaincode.pb.go) such as `func (*Column) XXX_OneofFuncs` that are not intended as public API. The best is to look at the function definitions in [chaincode.go](https://github.com/hyperledger/fabric/blob/master/core/chaincode/shim/chaincode.go) and [chaincode samples](https://github.com/hyperledger/fabric/tree/master/examples/chaincode) for usage. diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md deleted file mode 100644 index b536f63bfb6..00000000000 --- a/docs/CONTRIBUTING.md +++ /dev/null @@ -1,206 +0,0 @@ -# Contributions Welcome! - -We welcome contributions to the Hyperledger Project in many forms, and -there's always plenty to do! - -First things first, please review the Hyperledger Project's [Code of Conduct](https://wiki.hyperledger.org/community/hyperledger-project-code-of-conduct) -before participating. It is important that we keep things civil. - -## Getting a Linux Foundation account - -In order to participate in the development of the Hyperledger Fabric project, -you will need a [Linux Foundation account](Gerrit/lf-account.md). You will need -to use your LF ID to access to all the Hyperledger community development tools, -including [Gerrit](https://gerrit.hyperledger.org), -[Jira](https://jira.hyperledger.org) and the -[Wiki](https://wiki.hyperledger.org/start) (for editing, only). - -### Setting up your SSH key - -For Gerrit, before you can submit any change set for review, you will need to -register your public SSH key. Login to [Gerrit](https://gerrit.hyperledger.org) -with your [LFID](Gerrit/lf-account.md), and click on your name in the upper -right-hand corner of your browser window and then click 'Settings'. In the -left-hand margin, you should see a link for 'SSH Public Keys'. Copy-n-paste -your [public SSH key](https://help.github.com/articles/generating-an-ssh-key/) -into the window and press 'Add'. - -## Getting help - -If you are looking for something to work on, or need some expert assistance in -debugging a problem or working out a fix to an issue, our -[community](https://www.hyperledger.org/community) is always eager to help. We -hang out on [Chat](https://chat.hyperledger.org/channel/fabric/), IRC -(#hyperledger on freenode.net) and the [mailing lists](http://lists.hyperledger.org/). -Most of us don't bite :grin: and will be glad to help. The only silly question -is the one you don't ask. Questions are in fact a great way to help improve the -project as they highlight where our documentation could be clearer. - -## Requirements and Use Cases - -We have a [Requirements -WG](https://wiki.hyperledger.org/groups/requirements/requirements-wg) that is -documenting use cases and from those use cases deriving requirements. If you are -interested in contributing to this effort, please feel free to join the -discussion in [chat](https://chat.hyperledger.org/channel/requirements/). - -## Reporting bugs - -If you are a user and you find a bug, please submit an issue using -[JIRA](https://jira.hyperledger.org). Please try to provide -sufficient information for someone else to reproduce the issue. One of the -project's maintainers should respond to your issue within 24 hours. If not, -please bump the issue with a comment and request that it be reviewed. You can -also post to the `#fabric-maintainers` channel in -[chat](https://chat.hyperledger.org/channel/fabric-maintainers). - -## Fixing issues and working stories - -Review the [issues list](https://github.com/hyperledger/fabric/issues) and find -something that interests you. You could also check the -["help-wanted"](https://jira.hyperledger.org/issues/?jql=project%20%3D%20Fabric%20AND%20labels%20%3D%20help-wanted) -list. It is wise to start with something relatively straight forward and -achievable, and that no one is already assigned. If no one is assigned, -then assign the issue to yourself. Please be considerate and rescind the -assignment if you cannot finish in a reasonable time, or add a comment -saying that you are still actively working the issue if you need a little -more time. - -## Working with a local clone and Gerrit - -We are using [Gerrit](https://gerrit.hyperledger.org/r/#/admin/projects/fabric) -to manage code contributions. If you are unfamiliar, please review this -[document](Gerrit/gerrit.md) before proceeding. - -After you have familiarized yourself with `Gerrit`, and maybe played around with -the `lf-sandbox` -[project](https://gerrit.hyperledger.org/r/#/admin/projects/lf-sandbox,branches), -you should be ready to set up your local development -[environment](dev-setup/devenv.md). - -Next, try [building the project](dev-setup/build.md) in your local development -environment to ensure that everything is set up correctly. - -[Logging control](Setup/logging-control.md) describes how to tweak the logging -levels of various components within the Fabric. Finally, every source file -needs to include a [license header](dev-setup/headers.txt): modified to include -a copyright statement for the principle author(s). - -## What makes a good change request? - -* One change at a time. Not five, not three, not ten. One and only one. Why? -Because it limits the blast area of the change. If we have a regression, it is -much easier to identify the culprit commit than if we have some composite -change that impacts more of the code. - -* Include a link to the JIRA story for the change. Why? Because a) we want to -track our velocity to better judge what we think we can deliver and when and b) -because we can justify the change more effectively. In many cases, there -should be some discussion around a proposed change and we want to link back to -that from the change itself. - -* Include unit and integration tests (or changes to existing tests) with every -change. This does not mean just happy path testing, either. It also means -negative testing of any defensive code that it correctly catches input errors. -When you write code, you are responsible to test it and provide the tests that -demonstrate that your change does what it claims. Why? Because -without this we have no clue whether our current code base actually works. - -* Unit tests should have NO external dependencies. You should be able to run -unit tests in place with `go test` or equivalent for the language. Any test -that requires some external dependency (e.g. needs to be scripted to run another -component) needs appropriate mocking. Anything else is not unit testing, it is -integration testing by definition. Why? Because many open source developers -do Test Driven Development. They place a watch on the directory that invokes -the tests automagically as the code is changed. This is far more efficient -than having to run a whole build between code changes. - -* Minimize the lines of code per CR. Why? Maintainers have day jobs, too. If -you send a 1,000 or 2,000 LOC change, how long do you think it takes to review -all of that code? Keep your changes to < 200-300 LOC if possible. If you have a -larger change, decompose it into multiple independent changess. If you are adding -a bunch of new functions to fulfill the requirements of a new capability, add -them separately with their tests, and then write the code that uses them to -deliver the capability. Of course, there are always exceptions. If you add a -small change and then add 300 LOC of tests, you will be forgiven;-) -If you need to make a change that has broad impact or a bunch of generated -code (protobufs, etc.). Again, there can be exceptions. - -* Write a meaningful commit message. Include a meaningful 50 (or less) character -title, followed by a blank line, followed my a more comprehensive description -of the change. Be sure to include the JIRA identifier corresponding to the -change (e.g. [FAB-1234]). This can be in the title but should also be in the -body of the commit message. - -e.g. -``` -[FAB-1234] fix foobar() panic - -Fix [FAB-1234] added a check to ensure that when foobar(foo string) is called, -that there is a non-empty string argument. -``` - -Finally, be responsive. Don't let a change request fester with review comments -such that it gets to a point that it requires a rebase. It only further delays -getting it merged and adds more work for you - to remediate the merge conflicts. - -## Coding guidelines - -Be sure to check out the language-specific -[style guides](Style-guides/go-style.md) before making any changes. This will -ensure a smoother review. - -## Communication - -We use [RocketChat](https://chat.hyperledger.org/) for communication and -Google Hangouts™ for screen sharing between developers. Our development -planning and prioritization is done in [JIRA](https://jira.hyperledger.org), -and we take longer running discussions/decisions to the -[mailing list](http://lists.hyperledger.org/mailman/listinfo/hyperledger-fabric). - -## Maintainers - -The project's [maintainers](MAINTAINERS.md) are responsible for reviewing and -merging all patches submitted for review and they guide the over-all technical -direction of the project within the guidelines established by the Hyperledger -Project's Technical Steering Committee (TSC). - -### Becoming a maintainer - -This project is managed under an open governance model as described in our -[charter](https://www.hyperledger.org/about/charter). Projects or sub-projects -will be lead by a set of maintainers. New sub-projects can designate an initial -set of maintainers that will be approved by the top-level project's existing -maintainers when the project is first approved. The project's maintainers will, -from time-to-time, consider adding or removing a maintainer. An existing -maintainer can submit a change set to the [MAINTAINERS.md](MAINTAINERS.md) file. -If there are less than eight maintainers, a majority of the existing maintainers -on that project are required to merge the change set. If there are more than -eight existing maintainers, then if five or more of the maintainers concur with -the proposal, the change set is then merged and the individual is added to -(or alternatively, removed from) the maintainers group. explicit resignation, -some infraction of the [code of conduct](https://wiki.hyperledger.org/community/hyperledger-project-code-of-conduct) -or consistently demonstrating poor judgement. - -## Legal stuff - -**Note:** Each source file must include a license header for the Apache Software -License 2.0. A template of that header can be found [here](https://github.com/hyperledger/fabric/blob/master/docs/dev-setup/headers.txt). - -We have tried to make it as easy as possible to make contributions. This -applies to how we handle the legal aspects of contribution. We use the same -approach—the [Developer's Certificate of Origin 1.1 (DCO)](docs/biz/DCO1.1.txt)—that -the Linux® Kernel [community](http://elinux.org/Developer_Certificate_Of_Origin) -uses to manage code contributions. - -We simply ask that when submitting a patch for review, the developer must include -a sign-off statement in the commit message. - -Here is an example Signed-off-by line, which indicates that the submitter -accepts the DCO: - -``` -Signed-off-by: John Doe -``` -You can include this automatically when you commit a change to your local git -repository using `git commit -s`. diff --git a/docs/MAINTAINERS.md b/docs/MAINTAINERS.md deleted file mode 100644 index 74d61ac8cf3..00000000000 --- a/docs/MAINTAINERS.md +++ /dev/null @@ -1,16 +0,0 @@ -## Maintainers - -| Name | Gerrit | GitHub | Slack | email | -|---|---|---|---|---| -| Binh Nguyen | binhn | binhn | binhn | binhn@us.ibm.com | -| Chris Ferris | ChristopherFerris | christo4ferris | cbf | chris.ferris@gmail.com | -| Gabor Hosszu | hgabre | gabre | hgabor | gabor@digitalasset.com | -| Gari Singh | mastersingh24 | mastersingh24 | garisingh | gari.r.singh@gmail.com | -| Greg Haskins | greg.haskins | ghaskins | ghaskins | gregory.haskins@gmail.com | -| Jason Yellick | jyellick | jyellick | jyellick | jyellick@us.ibm.com | -| Jim Zhang | jimthematrix | jimthematrix | jzhang | jim_the_matrix@hotmail.com | -| Jonathan Levi | JonathanLevi | JonathanLevi | JonathanLevi | jonathan@hacera.com | -| Sheehan Anderson | sheehan | srderson | sheehan | sranderson@gmail.com | -| Srinivasan Muralidharan | muralisr | muralisrini | muralisr | muralisr@us.ibm.com | -| Tamas Blummer | TamasBlummer | tamasblummer | tamas | tamas@digitalasset.com | -| Yacov Manevich | yacovm | yacovm | yacovm | yacovm@il.ibm.com | diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000000..e70f20a2e0a --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = hyperledger-fabricdocs +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/Setup/Chaincode-setup.md b/docs/Setup/Chaincode-setup.md deleted file mode 100644 index f7592ea9f89..00000000000 --- a/docs/Setup/Chaincode-setup.md +++ /dev/null @@ -1,522 +0,0 @@ -## Writing, Building, and Running Chaincode in a Development Environment - -Chaincode developers need a way to test and debug their chaincode without having to set up a complete peer network. By default, when you want to interact with chaincode, you need to first `Deploy` it using the CLI, REST API, gRPC API, or SDK. Upon receiving this request, the peer node would typically spin up a Docker container with the relevant chaincode. This can make things rather complicated for debugging chaincode under development, because of the turnaround time with the `launch chaincode - debug docker container - fix problem - launch chaincode - lather - rinse - repeat` cycle. As such, the fabric peer has a `--peer-chaincodedev` flag that can be passed on start-up to instruct the peer node not to deploy the chaincode as a Docker container. - -The following instructions apply to _developing_ chaincode in Go or Java. They do not apply to running in a production environment. However, if _developing_ chaincode in Java, please see the [Java chaincode setup](https://github.com/hyperledger/fabric/blob/master/docs/Setup/JAVAChaincode.md) instructions first, to be sure your environment is properly configured. - -**Note:** We have added support for [System chaincode](https://github.com/hyperledger/fabric/blob/master/docs/SystemChaincode-noop.md). - -## Choices - -Once again, you have the choice of using one of the following approaches: - -- [Option 1](#option-1-vagrant-development-environment) using the **Vagrant** [development environment](https://github.com/hyperledger/fabric/blob/master/docs/dev-setup/devenv.md) that is used for developing the fabric itself -- [Option 2](#option-2-docker-for-mac-or-windows) using Docker for Mac or Windows -- [Option 3](#option-3-docker-toolbox) using Docker toolbox - -By using options *2* or *3*, above, you avoid having to build everything from scratch, and there's no need to keep a clone of the fabric GitHub repos current/up-to-date. Instead, you can simply pull and run the `fabric-peer` and `fabric-membersrvc` images directly from DockerHub. - -You will need multiple terminal windows - essentially one for each component. One runs the validating peer; another runs the chaincode; the third runs the CLI or REST API commands to execute transactions. Finally, when running with security enabled, an additional fourth window is required to run the **Certificate Authority (CA)** server. Detailed instructions are provided in the sections below. - -## Option 1 Vagrant development environment - -### Security Setup (optional) - -From the `devenv` subdirectory of your fabric workspace environment, `ssh` into Vagrant: - -``` -cd $GOPATH/src/github.com/hyperledger/fabric/devenv -vagrant ssh -``` - -To set up the local development environment with security enabled, you must first build and run the **Certificate Authority (CA)** server: - -``` -cd $GOPATH/src/github.com/hyperledger/fabric -make membersrvc && membersrvc -``` - -Running the above commands builds and runs the CA server with the default setup, which is defined in the [membersrvc.yaml](https://github.com/hyperledger/fabric/blob/master/membersrvc/membersrvc.yaml) configuration file. The default configuration includes multiple users who are already registered with the CA; these users are listed in the `eca.users` section of the configuration file. To register additional users with the CA for testing, modify the `eca.users` section of the [membersrvc.yaml](https://github.com/hyperledger/fabric/blob/master/membersrvc/membersrvc.yaml) file to include additional `enrollmentID` and `enrollmentPW` pairs. Note the integer that precedes the `enrollmentPW`. That integer indicates the role of the user, where 1 = client, 2 = non-validating peer, 4 = validating peer, and 8 = auditor. - -### Running the validating peer - -In a **new** terminal window, from the `devenv` subdirectory of your fabric workspace environment, `ssh` into Vagrant: - -``` -cd $GOPATH/src/github.com/hyperledger/fabric/devenv -vagrant ssh -``` - -Build and run the peer process. - -``` -cd $GOPATH/src/github.com/hyperledger/fabric -make peer -peer node start --peer-chaincodedev -``` - -Alternatively, rather than tweaking the `core.yaml` and rebuilding, you can enable security and privacy on the peer with environment variables: - -``` -CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer node start --peer-chaincodedev -``` - -Now, you are ready to start [running the chaincode](#running-the-chaincode). - -## Option 2 Docker for Mac or Windows - -If you would prefer to simply run the fabric components as built and published by the Hyperledger project on your Mac or Windows laptop/server using the Docker for [Mac](https://docs.docker.com/engine/installation/mac/) or [Windows](https://docs.docker.com/engine/installation/windows/) platform, following these steps. If using [Docker Toolbox](https://docs.docker.com/toolbox/overview/), please skip to [Option 3](#option-3-docker-toolbox), below. - -### Pull images from DockerHub - -First, pull the latest images published by the Hyperledger fabric project from DockerHub. - -``` -docker pull hyperledger/fabric-peer:latest -docker pull hyperledger/fabric-membersrvc:latest -``` - -### Running the Peer and CA - -To run the fabric-peer and fabric-membersrvc images, we'll use [Docker Compose](https://docs.docker.com/compose/). It significantly simplifies things. To do that, we'll create a docker-compose.yml file with a description of the two services we'll be running. Here's the docker-compose.yml to launch the two processes: - -``` -membersrvc: - image: hyperledger/fabric-membersrvc - ports: - - "7054:7054" - command: membersrvc -vp0: - image: hyperledger/fabric-peer - ports: - - "7050:7050" - - "7051:7051" - - "7053:7053" - environment: - - CORE_PEER_ADDRESSAUTODETECT=true - - CORE_VM_ENDPOINT=unix:///var/run/docker.sock - - CORE_LOGGING_LEVEL=DEBUG - - CORE_PEER_ID=vp0 - - CORE_PEER_PKI_ECA_PADDR=membersrvc:7054 - - CORE_PEER_PKI_TCA_PADDR=membersrvc:7054 - - CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054 - - CORE_SECURITY_ENABLED=true - - CORE_SECURITY_ENROLLID=test_vp0 - - CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT - links: - - membersrvc - command: sh -c "sleep 5; peer node start --peer-chaincodedev" -``` - -Save that in a directory with the name `docker-compose.yml`. Then, run `docker-compose up` to start the two processes. - -Now, you are ready to start [running the chaincode](#running-the-chaincode). - -## Option 3 Docker Toolbox - -If you are using [Docker Toolbox](https://docs.docker.com/toolbox/overview/), please follow these instructions. - -### Pull images from DockerHub - -First, pull the latest images published by the Hyperledger fabric project from DockerHub. - -``` - docker pull hyperledger/fabric-peer:latest - docker pull hyperledger/fabric-membersrvc:latest -``` - -### Running the Peer and CA - -To run the fabric-peer and fabric-membersrvc images, we'll use [Docker Compose](https://docs.docker.com/compose/). It significantly simplifies things. To do that, we'll create a docker-compose.yml file with a description of the two services we'll be running. Here's the docker-compose.yml to launch the two processes: - -``` -membersrvc: - image: hyperledger/fabric-membersrvc - command: membersrvc -vp0: - image: hyperledger/fabric-peer - environment: - - CORE_PEER_ADDRESSAUTODETECT=true - - CORE_VM_ENDPOINT=http://172.17.0.1:2375 - - CORE_LOGGING_LEVEL=DEBUG - - CORE_PEER_ID=vp0 - - CORE_PEER_PKI_ECA_PADDR=membersrvc:7054 - - CORE_PEER_PKI_TCA_PADDR=membersrvc:7054 - - CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054 - - CORE_SECURITY_ENABLED=true - - CORE_SECURITY_ENROLLID=test_vp0 - - CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT - links: - - membersrvc - command: sh -c "sleep 5; peer node start --peer-chaincodedev" -``` -Save that in a directory with the name `docker-compose.yml`. Then, run `docker-compose up` to start the two processes. - -## Running the chaincode - -Start a **new** terminal window. - -### Vagrant - -If you are using [Option 1](#option-1-vagrant-development-environment), you'll need to `ssh` to Vagrant. Otherwise, [skip](#not-vagrant) this step. - -``` -cd $GOPATH/src/github.com/hyperledger/fabric/devenv -vagrant ssh -``` - -Next, we'll build the **chaincode_example02** code, which is provided in the Hyperledger fabric source code repository. If you are using [Option 1](#option-1-vagrant-development-environment), then you can do this from your clone of the fabric repository. - -``` -cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -go build -``` - -### Not Vagrant - -If you are using either [Option 2](#option-2-docker-for-mac-or-windows) or [Option 3](#option-3-docker-toolbox), you'll need to download the sample chaincode. The chaincode project must be placed somewhere under the `src` directory in your local `$GOPATH` as shown below. - -``` -mkdir -p $GOPATH/src/github.com/chaincode_example02/ -cd $GOPATH/src/github.com/chaincode_example02 -curl --request GET https://raw.githubusercontent.com/hyperledger/fabric/master/examples/chaincode/go/chaincode_example02/chaincode_example02.go > chaincode_example02.go -``` - -Next, you'll need to clone the Hyperledger fabric to your local $GOPATH, so that you can build your chaincode. **Note:** this is a temporary stop-gap until we can provide an independent package for the chaincode shim. - -``` -mkdir -p $GOPATH/src/github.com/hyperledger -cd $GOPATH/src/github.com/hyperledger -git clone http://gerrit.hyperledger.org/r/fabric -``` - -Now, you should be able to build your chaincode. - -``` -cd $GOPATH/src/github.com/chaincode_example02 -go build -``` - -When you are ready to start creating your own Go chaincode, create a new subdirectory under $GOPATH/src. You can copy the **chaincode_example02** file to the new directory and modify it. - -### Starting and registering the chaincode - -Run the following chaincode command to start and register the chaincode with the validating peer: - -``` -CORE_CHAINCODE_ID_NAME=mycc CORE_PEER_ADDRESS=0.0.0.0:7051 ./chaincode_example02 -``` - -The chaincode console will display the message "Received REGISTERED, ready for invocations", which indicates that the chaincode is ready to receive requests. Follow the steps below to send a chaincode deploy, invoke or query transaction. If the "Received REGISTERED" message is not displayed, then an error has occurred during the deployment; revisit the previous steps to resolve the issue. - -## Running the CLI or REST API - - * [chaincode deploy via CLI and REST](#chaincode-deploy-via-cli-and-rest) - * [chaincode invoke via CLI and REST](#chaincode-invoke-via-cli-and-rest) - * [chaincode query via CLI and REST](#chaincode-query-via-cli-and-rest) - -If you were running with security enabled, see [Removing temporary files when security is enabled](#removing-temporary-files-when-security-is-enabled) to learn how to clean up the temporary files. - -See the [logging control](https://github.com/hyperledger/fabric/blob/master/docs/Setup/logging-control.md) reference for information on controlling -logging output from the `peer` and chaincodes. - -### Terminal 3 (CLI or REST API) - -#### **Note on REST API port** - -The default REST interface port is `7050`. It can be configured in [core.yaml](https://github.com/hyperledger/fabric/blob/master/peer/core.yaml) using the `rest.address` property. If using Vagrant, the REST port mapping is defined in [Vagrantfile](https://github.com/hyperledger/fabric/blob/master/devenv/Vagrantfile). - -#### **Note on security functionality** - -Current security implementation assumes that end user authentication takes place at the application layer and is not handled by the fabric. Authentication may be performed through any means considered appropriate for the target application. Upon successful user authentication, the application will perform user registration with the CA exactly once. If registration is attempted a second time for the same user, an error will result. During registration, the application sends a request to the certificate authority to verify the user registration and if successful, the CA responds with the user certificates and keys. The enrollment and transaction certificates received from the CA will be stored locally inside `/var/hyperledger/production/crypto/client/` directory. This directory resides on a specific peer node which allows the user to transact only through this specific peer while using the stored crypto material. If the end user needs to perform transactions through more then one peer node, the application is responsible for replicating the crypto material to other peer nodes. This is necessary as registering a given user with the CA a second time will fail. - -With security enabled, the CLI commands and REST payloads must be modified to include the `enrollmentID` of a registered user who is logged in; otherwise an error will result. A registered user can be logged in through the CLI or the REST API by following the instructions below. To log in through the CLI, issue the following commands, where `username` is one of the `enrollmentID` values listed in the `eca.users` section of the [membersrvc.yaml](https://github.com/hyperledger/fabric/blob/master/membersrvc/membersrvc.yaml) file. - -From your command line terminal, move to the `devenv` subdirectory of your workspace environment. Log into a Vagrant terminal by executing the following command: - -``` - vagrant ssh -``` - -Register the user though the CLI, substituting for `` appropriately: - -``` - cd $GOPATH/src/github.com/hyperledger/fabric/peer - peer network login -``` - -The command will prompt for a password, which must match the `enrollmentPW` listed for the target user in the `eca.users` section of the [membersrvc.yaml](https://github.com/hyperledger/fabric/blob/master/membersrvc/membersrvc.yaml) file. If the password entered does not match the `enrollmentPW`, an error will result. - -To log in through the REST API, send a POST request to the `/registrar` endpoint, containing the `enrollmentID` and `enrollmentPW` listed in the `eca.users` section of the [membersrvc.yaml](https://github.com/hyperledger/fabric/blob/master/membersrvc/membersrvc.yaml) file. - -**REST Request:** - -``` -POST localhost:7050/registrar - -{ - "enrollId": "jim", - "enrollSecret": "6avZQLwcUe9b" -} -``` - -**REST Response:** - -``` -200 OK -{ - "OK": "Login successful for user 'jim'." -} -``` - -#### chaincode deploy via CLI and REST - -First, send a chaincode deploy transaction, only once, to the validating peer. The CLI connects to the validating peer using the properties defined in the core.yaml file. **Note:** The deploy transaction typically requires a `path` parameter to locate, build, and deploy the chaincode. However, because these instructions are specific to local development mode and the chaincode is deployed manually, the `name` parameter is used instead. -``` -peer chaincode deploy -n mycc -c '{"Args": ["init", "a","100", "b", "200"]}' -``` - -Alternatively, you can run the chaincode deploy transaction through the REST API. - -**REST Request:** - -``` -POST /chaincode - -{ - "jsonrpc": "2.0", - "method": "deploy", - "params": { - "type": 1, - "chaincodeID":{ - "name": "mycc" - }, - "input": { - "args":["init", "a", "100", "b", "200"] - } - }, - "id": 1 -} -``` - -**REST Response:** - -``` -{ - "jsonrpc": "2.0", - "result": { - "status": "OK", - "message": "mycc" - }, - "id": 1 -} -``` - -**Note:** When security is enabled, modify the CLI command and the REST API payload to pass the `enrollmentID` of a logged in user. To log in a registered user through the CLI or the REST API, follow the instructions in the [note on security functionality](#note-on-security-functionality). On the CLI, the `enrollmentID` is passed with the `-u` parameter; in the REST API, the `enrollmentID` is passed with the `secureContext` element. If you are enabling security and privacy on the peer process with environment variables, it is important to include these environment variables in the command when executing all subsequent peer operations (e.g. deploy, invoke, or query). - - CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode deploy -u jim -n mycc -c '{"Args": ["init", "a","100", "b", "200"]}' - -**REST Request:** - -``` -POST /chaincode - -{ - "jsonrpc": "2.0", - "method": "deploy", - "params": { - "type": 1, - "chaincodeID":{ - "name": "mycc" - }, - "input": { - "args":["init", "a", "100", "b", "200"] - }, - "secureContext": "jim" - }, - "id": 1 -} -``` - -The deploy transaction initializes the chaincode by executing a target initializing function. Though the example shows "init", the name could be arbitrarily chosen by the chaincode developer. You should see the following output in the chaincode window: -``` - Received INIT(uuid:005dea42-d57f-4983-803e-3232e551bf61), initializing chaincode - Aval = 100, Bval = 200 -``` - -#### Chaincode invoke via CLI and REST - -Run the chaincode invoking transaction on the CLI as many times as desired. The `-n` argument should match the value provided in the chaincode window (started in Vagrant terminal 2): - -``` - peer chaincode invoke -l golang -n mycc -c '{"Args": ["invoke", "a", "b", "10"]}' -``` - -Alternatively, run the chaincode invoking transaction through the REST API. - -**REST Request:** - -``` -POST /chaincode - -{ - "jsonrpc": "2.0", - "method": "invoke", - "params": { - "type": 1, - "chaincodeID":{ - "name":"mycc" - }, - "input": { - "args":["invoke", "a", "b", "10"] - } - }, - "id": 3 -} -``` - -**REST Response:** - -``` -{ - "jsonrpc": "2.0", - "result": { - "status": "OK", - "message": "5a4540e5-902b-422d-a6ab-e70ab36a2e6d" - }, - "id": 3 -} -``` - -**Note:** When security is enabled, modify the CLI command and REST API payload to pass the `enrollmentID` of a logged in user. To log in a registered user through the CLI or the REST API, follow the instructions in the [note on security functionality](#note-on-security-functionality). On the CLI, the `enrollmentID` is passed with the `-u` parameter; in the REST API, the `enrollmentID` is passed with the `secureContext` element. If you are enabling security and privacy on the peer process with environment variables, it is important to include these environment variables in the command when executing all subsequent peer operations (e.g. deploy, invoke, or query). - - CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode invoke -u jim -l golang -n mycc -c '{"Args": ["invoke", "a", "b", "10"]}' - -**REST Request:** - -``` -POST /chaincode - -{ - "jsonrpc": "2.0", - "method": "invoke", - "params": { - "type": 1, - "chaincodeID":{ - "name":"mycc" - }, - "input": { - "args":["invoke", "a", "b", "10"] - }, - "secureContext": "jim" - }, - "id": 3 -} -``` - -The invoking transaction runs the specified chaincode function name "invoke" with the arguments. This transaction transfers 10 units from A to B. You should see the following output in the chaincode window: - -``` - Received RESPONSE. Payload 200, Uuid 075d72a4-4d1f-4a1d-a735-4f6f60d597a9 - Aval = 90, Bval = 210 -``` - -#### Chaincode query via CLI and REST - -Run a query on the chaincode to retrieve the desired values. The `-n` argument should match the value provided in the chaincode window (started in Vagrant terminal 2): - -``` - peer chaincode query -l golang -n mycc -c '{"Args": ["query", "b"]}' -``` - -The response should be similar to the following: - -``` - {"Name":"b","Amount":"210"} -``` - -If a name other than "a" or "b" is provided in a query sent to `chaincode_example02`, you should see an error response similar to the following: - -``` - {"Error":"Nil amount for c"} -``` - -Alternatively, run the chaincode query transaction through the REST API. - -**REST Request:** -``` -POST /chaincode - -{ - "jsonrpc": "2.0", - "method": "query", - "params": { - "type": 1, - "chaincodeID":{ - "name":"mycc" - }, - "input": { - "args":["query", "a"] - } - }, - "id": 5 -} -``` - -**REST Response:** -``` -{ - "jsonrpc": "2.0", - "result": { - "status": "OK", - "message": "90" - }, - "id": 5 -} -``` - -**Note:** When security is enabled, modify the CLI command and REST API payload to pass the `enrollmentID` of a logged in user. To log in a registered user through the CLI or the REST API, follow the instructions in the [note on security functionality](#note-on-security-functionality). On the CLI, the `enrollmentID` is passed with the `-u` parameter; in the REST API, the `enrollmentID` is passed with the `secureContext` element. If you are enabling security and privacy on the peer process with environment variables, it is important to include these environment variables in the command when executing all subsequent peer operations (e.g. deploy, invoke, or query). - -``` - CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode query -u jim -l golang -n mycc -c '{"Args": ["query", "b"]}' -``` - -**REST Request:** -``` -POST /chaincode - -{ - "jsonrpc": "2.0", - "method": "query", - "params": { - "type": 1, - "chaincodeID":{ - "name":"mycc" - }, - "input": { - "args":["query", "a"] - }, - "secureContext": "jim" - }, - "id": 5 -} -``` - -#### Removing temporary files when security is enabled - -**Note:** this step applies **ONLY** if you were using Option 1 above. For Option 2 or 3, the cleanup is handled by Docker. - -After the completion of a chaincode test with security enabled, remove the temporary files that were created by the CA server process. To remove the client enrollment certificate, enrollment key, transaction certificate chain, etc., run the following commands. Note, that you must run these commands if you want to register a user who has already been registered previously. - -From your command line terminal, `ssh` into Vagrant: - -``` -cd $GOPATH/src/github.com/hyperledger/fabric/devenv -vagrant ssh -``` - -And then run: - -``` -rm -rf /var/hyperledger/production -``` diff --git a/docs/Setup/JAVAChaincode.md b/docs/Setup/JAVAChaincode.md deleted file mode 100644 index 519420126e7..00000000000 --- a/docs/Setup/JAVAChaincode.md +++ /dev/null @@ -1,129 +0,0 @@ -## Java chaincode - -Note: This guide generally assumes you have followed the Chaincode development environment setup tutorial [here](https://github.com/hyperledger/fabric/blob/master/docs/Setup/Chaincode-setup.md). - -### To get started developing Java chaincode - -1. Ensure you have gradle - * Download the binary distribution from [http://gradle.org/gradle-download/](http://gradle.org/gradle-download/) - * Unpack, move to the desired location, and add gradle's bin directory to your system path - * Ensure `gradle -v` works from the command-line, and shows version 2.12 or greater - * Optionally, enable the [gradle daemon](https://docs.gradle.org/current/userguide/gradle_daemon.html) for faster builds -2. Ensure you have the Java 1.8 **JDK** installed. Also ensure Java's directory is on your path with `java -version` - * Additionally, you will need to have the [`JAVA HOME`](https://docs.oracle.com/cd/E19182-01/821-0917/6nluh6gq9/index.html) variable set to your **JDK** installation in your system path -3. From your command line terminal, move to the `devenv` subdirectory of your workspace environment. Log into a Vagrant terminal by executing the following command: - - ``` - vagrant ssh - ``` - -4. Build and run the peer process. - - ``` - cd $GOPATH/src/github.com/hyperledger/fabric - make peer - peer node start - ``` - -5. The following steps is for deploying chaincode in non-dev mode. - - * Deploy the chaincode, - -``` - peer chaincode deploy -l java -p /opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/java/SimpleSample -c '{"Args": ["init", "a","100", "b", "200"]}' -``` - -`6d9a704d95284593fe802a5de89f84e86fb975f00830bc6488713f9441b835cf32d9cd07b087b90e5cb57a88360f90a4de39521a5595545ad689cd64791679e9` - - * This command will give the 'name' for this chaincode, and use this value in all the further commands with the -n (name) parameter - - - * PS. This may take a few minutes depending on the environment as it deploys the chaincode in the container, - -* Invoke a transfer transaction, - -``` - peer chaincode invoke -l java \ - -n 6d9a704d95284593fe802a5de89f84e86fb975f00830bc6488713f9441b835cf32d9cd07b087b90e5cb57a88360f90a4de39521a5595545ad689cd64791679e9 \ - -c '{"Args": ["transfer", "a", "b", "10"]}' -``` -`c7dde1d7-fae5-4b68-9ab1-928d61d1e346` - -* Query the values of a and b after the transfer - -``` - peer chaincode query -l java \ - -n 6d9a704d95284593fe802a5de89f84e86fb975f00830bc6488713f9441b835cf32d9cd07b087b90e5cb57a88360f90a4de39521a5595545ad689cd64791679e9 \ - -c '{ "Args": ["query", "a"]}' - {"Name":"a","Amount":"80"} - - - peer chaincode query -l java \ - -n 6d9a704d95284593fe802a5de89f84e86fb975f00830bc6488713f9441b835cf32d9cd07b087b90e5cb57a88360f90a4de39521a5595545ad689cd64791679e9 \ - -c '{ "Args": ["query", "b"]}' - {"Name":"b","Amount":"220"} -``` - - -### Java chaincode deployment in DEV Mode - -1. Follow the step 1 to 3 as above, -2. Build and run the peer process -``` - cd $GOPATH/src/github.com/hyperledger/fabric - make peer - peer node start --peer-chaincodedev -``` -3. Open the second Vagrant terminal and build the Java shim layer and publish it to Local Maven Repo -``` -cd $GOPATH/src/github.com/hyperledger/fabric/core/chaincode/shim/java -gradle -b build.gradle clean -gradle -b build.gradle build -``` -4. Change to examples folder to build and run, -``` - cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/java/SimpleSample - gradle -b build.gradle build -``` -5. Run the SimpleSample chaincode using the `gradle -b build.gradle run` - -6. Open the third Vagrant terminal to run init and invoke on the chaincode - - peer chaincode deploy -l java -n SimpleSample -c '{"Args": ["init", "a","100", "b", "200"]}' -``` -2016/06/28 19:10:15 Load docker HostConfig: %+v &{[] [] [] [] false map[] [] false [] [] [] [] host { 0} [] { map[]} false [] 0 0 0 false 0 0 0 0 []} -19:10:15.461 [crypto] main -> INFO 002 Log level recognized 'info', set to INFO -SimpleSample -``` - peer chaincode invoke -l java -n SimpleSample -c '{"Args": ["transfer", "a", "b", "10"]}' - -``` -2016/06/28 19:11:13 Load docker HostConfig: %+v &{[] [] [] [] false map[] [] false [] [] [] [] host { 0} [] { map[]} false [] 0 0 0 false 0 0 0 0 []} -19:11:13.553 [crypto] main -> INFO 002 Log level recognized 'info', set to INFO -978ff89e-e4ef-43da-a9f8-625f2f6f04e5 -``` - peer chaincode query -l java -n SimpleSample -c '{ "Args": ["query", "a"]}' -``` -2016/06/28 19:12:19 Load docker HostConfig: %+v &{[] [] [] [] false map[] [] false [] [] [] [] host { 0} [] { map[]} false [] 0 0 0 false 0 0 0 0 []} -19:12:19.289 [crypto] main -> INFO 002 Log level recognized 'info', set to INFO -{"Name":"a","Amount":"90"} -``` - peer chaincode query -l java -n SimpleSample -c '{"Args": ["query", "b"]}' -``` -2016/06/28 19:12:25 Load docker HostConfig: %+v &{[] [] [] [] false map[] [] false [] [] [] [] host { 0} [] { map[]} false [] 0 0 0 false 0 0 0 0 []} -19:12:25.667 [crypto] main -> INFO 002 Log level recognized 'info', set to INFO -{"Name":"b","Amount":"210"} -``` - -### Developing new JAVA chaincode -1. Create a new Java project structure. -2. Use existing `build.grade` from any example JAVA Chaincode project like `examples/chaincode/java/SimpleSample`. -3. Make your main class extend ChaincodeBase class and implement the following methods from base class. - 1. `public String run(ChaincodeStub stub, String function, String[] args) ` - 2. `public String query(ChaincodeStub stub, String function, String[] args)` - 3. `public String getChaincodeID()` -4. Modify the `mainClassName` in `build.gradle` to point to your new class. -5. Build this project using `gradle -b build.gradle build` -6. Run this chaincode after starting a peer in dev-mode as above using `gradle -b build.gradle run` - - diff --git a/docs/Setup/Network-setup.md b/docs/Setup/Network-setup.md deleted file mode 100644 index 88242f01dee..00000000000 --- a/docs/Setup/Network-setup.md +++ /dev/null @@ -1,261 +0,0 @@ -## Setting Up a Network - -This document covers setting up a network on your local machine for various development and testing activities. Unless you are intending to contribute to the development of the Hyperledger Fabric project, you'll probably want to follow the more commonly used approach below - [leveraging published Docker images](#leveraging-published-docker-images) for the various Hyperledger Fabric components, directly. Otherwise, skip down to the [secondary approach](#building-your-own-images) below. - -### Leveraging published Docker images - -This approach simply leverages the Docker images that the Hyperledger Fabric project publishes to [DockerHub](https://hub.docker.com/u/hyperledger/) and either Docker commands or Docker Compose descriptions of the network one wishes to create. - -#### Installing Docker - -**Note:** When running Docker _natively_ on Mac and Windows, there is no IP forwarding support available. Hence, running more than one fabric-peer image is not advised because you do not want to have multiple processes binding to the same port. For most application and chaincode development/testing running with a single fabric peer should not be an issue unless you are interested in performance and resilience testing the fabric's capabilities, such as consensus. For more advanced testing, we strongly recommend using the fabric's Vagrant [development environment](../dev-setup/devenv.md). - -With this approach, there are multiple choices as to how to run Docker: using [Docker Toolbox](https://docs.docker.com/toolbox/overview/) or one of the new native Docker runtime environments for [Mac OSX](https://docs.docker.com/engine/installation/mac/) or [Windows](https://docs.docker.com/engine/installation/windows/). There are some subtle differences between how Docker runs natively on Mac and Windows versus in a virtualized context on Linux. We'll call those out where appropriate below, when we get to the point of actually running the various components. - -#### Pulling the images from DockerHub - -Once you have Docker (1.11 or greater) installed and running, -prior to starting any of the fabric components, you will need to first pull the fabric images from DockerHub. - -``` - docker pull hyperledger/fabric-peer:latest - docker pull hyperledger/fabric-membersrvc:latest -``` - -### Building your own images - -**Note:** _This approach is not necessarily recommended for most users_. If you have pulled images from DockerHub as described in the previous section, you may proceed to the [next step](#starting-up-validating-peers). - -The second approach would be to leverage the [development environment](../dev-setup/devenv.md) setup (which we will assume you have already established) to build and deploy your own binaries and/or Docker images from a clone of the [hyperledger/fabric](https://github.com/hyperledger/fabric) GitHub repository. This approach is suitable for developers that might wish to contribute directly to the Hyperledger Fabric project, or that wish to deploy from a fork of the Hyperledger code base. - -The following commands should be run from _within_ the Vagrant environment described in [Setting Up Development Environment](../dev-setup/devenv.md). - -To create the Docker image for the `hyperledger/fabric-peer`: - -``` -cd $GOPATH/src/github.com/hyperledger/fabric -make peer-image -``` - -To create the Docker image for the `hyperledger/fabric-membersrvc`: - -``` -make membersrvc-image -``` - -### Starting up validating peers - -Check the available images again with `docker images`. You should see `hyperledger/fabric-peer` and `hyperledger/fabric-membersrvc` images. For example, - -``` -$ docker images -REPOSITORY TAG IMAGE ID CREATED SIZE -hyperledger/fabric-membersrvc latest 7d5f6e0bcfac 12 days ago 1.439 GB -hyperledger/fabric-peer latest 82ef20d7507c 12 days ago 1.445 GB -``` -If you don't see these, go back to the previous step. - -With the relevant Docker images in hand, we can start running the peer and membersrvc services. - -#### Determine value for CORE_VM_ENDPOINT variable - -Next, we need to determine the address of your docker daemon for the CORE_VM_ENDPOINT. If you are working within the Vagrant development environment, or a Docker Toolbox environment, you can determine this with the `ip add` command. For example, - -``` -$ ip add - -<<< detail removed >>> - -3: docker0: mtu 1500 qdisc noqueue state DOWN group default - link/ether 02:42:ad:be:70:cb brd ff:ff:ff:ff:ff:ff - inet 172.17.0.1/16 scope global docker0 - valid_lft forever preferred_lft forever - inet6 fe80::42:adff:febe:70cb/64 scope link - valid_lft forever preferred_lft forever -``` - -Your output might contain something like `inet 172.17.0.1/16 scope global docker0`. That means the docker0 interface is on IP address 172.17.0.1. Use that IP address for the `CORE_VM_ENDPOINT` option. For more information on the environment variables, see `core.yaml` configuration file in the `fabric` repository. - -If you are using the native Docker for Mac or Windows, the value for `CORE_VM_ENDPOINT` should be set to `unix:///var/run/docker.sock`. \[TODO] double check this. I believe that `127.0.0.1:2375` also works. - -#### Assigning a value for CORE_PEER_ID - -The ID value of `CORE_PEER_ID` must be unique for each validating peer, and it must be a lowercase string. We often use a convention of naming the validating peers vpN where N is an integer starting with 0 for the root node and incrementing N by 1 for each additional peer node started. e.g. vp0, vp1, vp2, ... - -#### Consensus - -By default, we are using a consensus plugin called `NOOPS`, which doesn't really do consensus. If you are running a single peer node, running anything other than `NOOPS` makes little sense. If you want to use some other consensus plugin in the context of multiple peer nodes, please see the [Using a Consensus Plugin](#using-a-consensus-plugin) section, below. - -#### Docker Compose - -We'll be using Docker Compose to launch our various Fabric component containers, as this is the simplest approach. You should have it installed from the initial setup steps. Installing Docker Toolbox or any of the native Docker runtimes should have installed Compose. - -#### Start up a validating peer: - -Let's launch the first validating peer (the root node). We'll set CORE_PEER_ID to vp0 and CORE_VM_ENDPOINT as above. Here's the docker-compose.yml for launching a single container within the **Vagrant** [development environment](../dev-setup/devenv.md): - -``` -vp0: - image: hyperledger/fabric-peer - environment: - - CORE_PEER_ID=vp0 - - CORE_PEER_ADDRESSAUTODETECT=true - - CORE_VM_ENDPOINT=http://172.17.0.1:2375 - - CORE_LOGGING_LEVEL=DEBUG - command: peer node start -``` -You can launch this Compose file as follows, from the same directory as the docker-compose.yml file: - -``` -$ docker-compose up -``` - -Here's the corresponding Docker command: -``` -$ docker run --rm -it -e CORE_VM_ENDPOINT=http://172.17.0.1:2375 -e CORE_LOGGING_LEVEL=DEBUG -e CORE_PEER_ID=vp0 -e CORE_PEER_ADDRESSAUTODETECT=true hyperledger/fabric-peer peer node start -``` - -If you are running Docker for Mac or Windows, we'll need to explicitly map the ports, and we will need a different value for CORE_VM_ENDPOINT as we discussed above. - -Here's the docker-compose.yml for Docker on Mac or Windows: - -``` -vp0: - image: hyperledger/fabric-peer - ports: - - "7050:7050" - - "7051:7051" - - "7052:7052" - environment: - - CORE_PEER_ADDRESSAUTODETECT=true - - CORE_VM_ENDPOINT=unix:///var/run/docker.sock - - CORE_LOGGING_LEVEL=DEBUG - command: peer node start -``` - -This single peer configuration, running the `NOOPS` 'consensus' plugin, should satisfy many development/test scenarios. `NOOPS` is not really providing consensus, it is essentially a no-op that simulates consensus. For instance, if you are simply developing and testing chaincode; this should be adequate unless your chaincode is leveraging membership services for identity, access control, confidentiality and privacy. - -#### Running with the CA - -If you want to take advantage of security (authentication and authorization), privacy and confidentiality, then you'll need to run the Fabric's certificate authority (CA). Please refer to the [CA Setup](ca-setup.md) instructions. - -#### Start up additional validating peers: - -Following the pattern we established [above](#assigning-a-value-for-core_peer_id) we'll use `vp1` as the ID for the second validating peer. If using Docker Compose, we can simply link the two peer nodes. -Here's the docker-compose.yml for a **Vagrant** environment with two peer nodes - vp0 and vp1: -``` -vp0: - image: hyperledger/fabric-peer - environment: - - CORE_PEER_ADDRESSAUTODETECT=true - - CORE_VM_ENDPOINT=http://172.17.0.1:2375 - - CORE_LOGGING_LEVEL=DEBUG - command: peer node start -vp1: - extends: - service: vp0 - environment: - - CORE_PEER_ID=vp1 - - CORE_PEER_DISCOVERY_ROOTNODE=vp0:7051 - links: - - vp0 -``` - -If we wanted to use the docker command line to launch another peer, we need to get the IP address of the first validating peer, which will act as the root node to which the new peer(s) will connect. The address is printed out on the terminal window of the first peer (e.g. 172.17.0.2) and should be passed in with the `CORE_PEER_DISCOVERY_ROOTNODE` environment variable. - -``` -docker run --rm -it -e CORE_VM_ENDPOINT=http://172.17.0.1:2375 -e CORE_PEER_ID=vp1 -e CORE_PEER_ADDRESSAUTODETECT=true -e CORE_PEER_DISCOVERY_ROOTNODE=172.17.0.2:7051 hyperledger/fabric-peer peer node start -``` - - -### Using a Consensus Plugin -A consensus plugin might require some specific configuration that you need to set up. For example, to use the Practical Byzantine Fault Tolerant (PBFT) consensus plugin provided as part of the fabric, perform the following configuration: - -1. In `core.yaml`, set the `peer.validator.consensus` value to `pbft` -2. In `core.yaml`, make sure the `peer.id` is set sequentially as `vpN` where `N` is an integer that starts from `0` and goes to `N-1`. For example, with 4 validating peers, set the `peer.id` to`vp0`, `vp1`, `vp2`, `vp3`. -3. In `consensus/pbft/config.yaml`, set the `general.mode` value to `batch` and the `general.N` value to the number of validating peers on the network, also set `general.batchsize` to the number of transactions per batch. -4. In `consensus/pbft/config.yaml`, optionally set timer values for the batch period (`general.timeout.batch`), the acceptable delay between request and execution (`general.timeout.request`), and for view-change (`general.timeout.viewchange`) - -See `core.yaml` and `consensus/pbft/config.yaml` for more detail. - -All of these setting may be overridden via the command line environment variables, e.g. `CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=pbft` or `CORE_PBFT_GENERAL_MODE=batch` - -### Logging control - -See [Logging Control](logging-control.md) for information on controlling -logging output from the `peer` and deployed chaincodes. - - diff --git a/docs/Setup/NodeSDK-setup.md b/docs/Setup/NodeSDK-setup.md deleted file mode 100755 index f23a4dafa13..00000000000 --- a/docs/Setup/NodeSDK-setup.md +++ /dev/null @@ -1,27 +0,0 @@ -## Hyperledger Fabric Client (HFC) SDK for Node.js - -The Hyperledger Fabric Client (HFC) SDK provides a powerful and easy to use API -to interact with a Hyperledger Fabric blockchain. - -This document assumes that you already have set up a Node.js development -environment. If not, go [here](https://nodejs.org/en/download/package-manager/) -to download and install Node.js for your OS. You'll also want the latest version -of `npm` installed. For that, execute `sudo npm install npm -g` to get the -latest version. - -### Installing the hfc module - -We publish the `hfc` node module to `npm`. To install `hfc` from npm simply -execute the following command: - -``` -npm install -g hfc -``` - -See [Hyperledger fabric Node.js client SDK](http://fabric-sdk-node.readthedocs.io/en/latest/node-sdk-guide) for more information. - - -## Hyperledger fabric network - -First, you'll want to have a running peer node and member services. The -instructions for setting up a network are [here](Network-setup.md). You may also use the [Fabric-starter-kit](../starter/fabric-starter-kit.md) that provides the network. diff --git a/docs/Setup/TLSSetup.md b/docs/Setup/TLSSetup.md deleted file mode 100644 index abc6b03497d..00000000000 --- a/docs/Setup/TLSSetup.md +++ /dev/null @@ -1,66 +0,0 @@ -### Steps to enable TLS for all sever (ECA , ACA , TLSCA , TCA) and between ACA client to server communications. - -1. Go to **memebersrvc.yaml** file under the fabric/membersrvc directory and edit security section, that is: -``` - security: - serverhostoverride: - tls_enabled: false - client: - cert: - file: -``` -To enable TLS between the ACA client and the rest of the CA Services set the `tls_enbabled` flag to `true`. - -2. Next, set **serverhostoverride** field to match **CN** (Common Name) of TLS Server certificate. To extract the Common Name from TLS Server's certificate, for example using OpenSSL, you can use the following command: - -``` -openssl x509 -in < -###### CSR fields - -- **CN** is the Common Name -- **keys** specifies the algorithm and key size as described below -- **O** is the organization name -- **OU** is the organization unit -- **L** is the location or city -- **ST** is the state -- **C** is the country - -The `fabric-ca server init` command generates a self-signed X.509 certificate. -It stores the certificate in the `server-cert.pem` file and the key in the -`server-key.pem` file in the Fabric CA server's home directory. - -###### Algorithms and key sizes - -The CSR-JSON-FILE can be customized to generate X.509 certificates and keys -that support both RSA and Elliptic Curve (ECDSA). The following setting is -an example of the implementation of Elliptic Curve Digital Signature -Algorithm (ECDSA) with curve `prime256v1` and signature algorithm -`ecdsa-with-SHA256`: -``` -"key": { - "algo": "ecdsa" - "size": 256 -} -``` -The choice of algorithm and key size are based on security needs. - -Elliptic Curve (ECDSA) offers the following key size options: - -| size | ASN1 OID | Signature Algorithm | -|-------------|:-------------:|:-----:| -| 256 | prime256v1 | ecdsa-with-SHA256 | -| 384 | secp384r1 | ecdsa-with-SHA384 | -| 521 | secp521r1 | ecdsa-with-SHA512 | - -RSA offers the following key size options: - -| size | Modulus (bits)| Signature Algorithm | -|-------------|:-------------:|:-----:| -| 2048 | 2048 | sha256WithRSAEncryption | -| 4096 | 4096 | sha512WithRSAEncryption | - -#### Starting the server - -Create a file named `server-config.json` as shown below -in your fabric-ca server's home directory (e.g. *$HOME/fabric-ca/server*). - -``` -{ - "tls_disable": false, - "ca_cert": "server-cert.pem", - "ca_key": "server-key.pem", - "driver":"sqlite3", - "data_source":"fabric-ca.db", - "user_registry": { "max_enrollments": 0 }, - "tls": { - "tls_cert": "server-cert.pem", - "tls_key": "server-key.pem" - }, - "users": { - "admin": { - "pass": "adminpw", - "type": "client", - "group": "bank_a", - "attrs": [ - {"name":"hf.Registrar.Roles","value":"client,peer,validator,auditor"}, - {"name":"hf.Registrar.DelegateRoles", "value": "client"} - ] - } - }, - "groups": { - "banks_and_institutions": { - "banks": ["bank_a", "bank_b", "bank_c"], - "institutions": ["institution_a"] - } - }, - "signing": { - "default": { - "usages": ["cert sign"], - "expiry": "8000h", - "ca_constraint": {"is_ca": true} - } - } -} -``` - -Now you may start the Fabric CA server as follows: - -``` -# cd $FABRIC_CA_HOME -# fabric-ca server start -address '0.0.0.0' -config server-config.json -``` - -To cause the fabric-ca server to listen on `http` rather than `https`, -set `tls_disable` to `true` in the `server-config.json` file. - -To limit the number of times that the same secret (or password) can -be used for enrollment, set the `max_enrollments` in the `server-config.json` -file to the appropriate value. If you set the value to 1, the fabric-ca -server allows passwords to only be used once for a particular enrollment ID. -If you set the value to 0, the fabric-ca server places no limit on the number -of times that a secret can be reused for enrollment. -The default value is 0. - -The fabric-ca server should now be listening on port 7054. - -You may skip to the [Fabric CA Client](#fabric-ca-client) section -if you do not want to configure the fabric-ca server to run in a -cluster or to use LDAP. - -#### Server database configuration - -This section describes how to configure the fabric-ca server to connect -to Postgres or MySQL databases. The default database is SQLite and the -default database file is `fabric-ca.db` in the Fabric CA's home directory. - -If you don't care about running the fabric-ca server in a cluster, you may -skip this section; otherwise, you must configure either Postgres or MySQL -as described below. - -###### Postgres - -The following sample may be added to the `server-config.json` file in order -to connect to a Postgres database. Be sure to customize the various values -appropriately. - -``` -"driver":"postgres", -"data_source":"host=localhost port=5432 user=Username password=Password dbname=fabric-ca sslmode=verify-full", -``` - -Specifying *sslmode* enables SSL, and a value of *verify-full* means to verify -that the certificate presented by the postgres server was signed by a trusted CA -and that the postgres server's host name matches the one in the certificate. - -We also need to set the TLS configuration in the fabric-ca server-config file. -If the database server requires client authentication, then a client cert and -key file needs to be provided. The following should be present in the fabric-ca -server config: - -``` -"tls":{ - ... - "db_client":{ - "ca_certfiles":["CA.pem"], - "client":[{"keyfile":"client-key.pem","certfile":"client-cert.pem"}] - } -}, -``` - -**ca_certfiles** - The names of the trusted root certificate files. - -**certfile** - Client certificate file. - -**keyfile** - Client key file. - -###### MySQL - -The following sample may be added to the `server-config.json` file in order -to connect to a MySQL database. Be sure to customize the various values -appropriately. - -``` -... -"driver":"mysql", -"data_source":"root:rootpw@tcp(localhost:3306)/fabric-ca?parseTime=true&tls=custom", -... -``` - -If connecting over TLS to the MySQL server, the `tls.db_client` section is -also required as described in the **Postgres** section above. - -#### LDAP - -The fabric-ca server can be configured to read from an LDAP server. - -In particular, the fabric-ca server may connect to an LDAP server to do the following: - - * authenticate a user prior to enrollment, and - * retrieve a user's attribute values which are used for authorization. - -In order to configure the fabric-ca server to connect to an LDAP server, add a section -of the following form to your fabric-ca server's configuration file: - -``` -{ - "ldap": { - "url": "scheme://adminDN:pass@host[:port][/base]" - "userfilter": "filter" - } -``` - -where: - * `scheme` is one of *ldap* or *ldaps*; - * `adminDN` is the distinquished name of the admin user; - * `pass` is the password of the admin user; - * `host` is the hostname or IP address of the LDAP server; - * `port` is the optional port number, where default 389 for *ldap* and 636 for *ldaps*; - * `base` is the optional root of the LDAP tree to use for searches; - * `filter` is a filter to use when searching to convert a login user name to - a distinquished name. For example, a value of `(uid=%s)` searches for LDAP - entries with the value of a `uid` attribute whose value is the login user name. - Similarly, `(email=%s)` may be used to login with an email address. - -The following is a sample configuration section for the default settings for the - OpenLDAP server whose docker image is at `https://github.com/osixia/docker-openldap`. - -``` - "ldap": { - "url": "ldap://cn=admin,dc=example,dc=org:admin@localhost:10389/dc=example,dc=org", - "userfilter": "(uid=%s)" - }, -``` - -See `FABRIC_CA/testdata/testconfig-ldap.json` for the complete configuration file with this section. -Also see `FABRIC_CA/scripts/run-ldap-tests` for a script which starts an OpenLDAP docker image, configures it, -runs the LDAP tests in FABRIC_CA/cli/server/ldap/ldap_test.go, and stops the OpenLDAP server. - -###### When LDAP is configured, enrollment works as follows: - - * A fabric-ca client or client SDK sends an enrollment request with a basic authorization header. - * The fabric-ca server receives the enrollment request, decodes the user/pass in the authorization header, looks up the DN (Distinquished Name) associated with the user using the "userfilter" from the configuration file, and then attempts an LDAP bind with the user's password. If successful, the enrollment processing is authorized and can proceed. - -###### When LDAP is configured, attribute retrieval works as follows: - - * A client SDK sends a request for a batch of tcerts **with one or more attributes** to the fabric-ca server. - * The fabric-ca server receives the tcert request and does as follows: - * extracts the enrollment ID from the token in the authorization header - (after validating the token); - * does an LDAP search/query to the LDAP server, requesting all of the - attribute names received in the tcert request; - * the attribute values are placed in the tcert as normal - -#### Setting up a cluster of fabric-ca servers - -You may use any IP sprayer to load balance to a cluster of fabric-ca -servers. This section provides an example of how to set up Haproxy -to route to a fabric-ca server cluster. Be sure to change -hostname and port to reflect the settings of your fabric-ca servers. - -haproxy.conf - -``` -global - maxconn 4096 - daemon - -defaults - mode http - maxconn 2000 - timeout connect 5000 - timeout client 50000 - timeout server 50000 - -listen http-in - bind *:7054 - balance roundrobin - server server1 hostname1:port - server server2 hostname2:port - server server3 hostname3:port -``` - - -## Fabric CA Client - -This section describes how to use the fabric-ca client. - -The default fabric-ca client's home directory is `$HOME/fabric-ca`, but -this can be changed by setting the `FABRIC_CA_HOME` environment variable. - -You must create a file named **client-config.json** in the fabric-ca -client's home directory. -The following is a sample client-config.json file: - -``` -{ - "ca_certfiles":["server-cert.pem"], - "signing": { - "default": { - "usages": ["cert sign"], - "expiry": "8000h" - } - } -} -``` - -You must also copy the server's certificate into the client's home directory. -In the examples in this document, the server's certificate is at -`$HOME/fabric-ca/server/server-cert.pem`. The file name must -match the name in the *client-config.json* file. - - -#### Enroll the bootstrap user - -Unless the fabric-ca server is configured to use LDAP, it must -be configured with at least one pre-registered bootstrap user. -In the previous server-config.json in this document, that user -has an enrollment ID of *admin* with an enrollment secret of *adminpw*. - - -First, create a CSR (Certificate Signing Request) JSON file similar to -the following. Customize it as desired. - -``` -{ - "key": { "algo": "ecdsa", "size": 256 }, - "names": [ - { - "O": "Hyperledger Fabric", - "OU": "Fabric CA", - "L": "Raleigh", - "ST": "North Carolina", - "C": "US" - } - ] -} -``` - -See [CSR fields](#csr-fields) for a description of the fields in this file. -When enrolling, the CN (Common Name) field is automatically set to the enrollment ID -which is *admin* in this example, so it can be omitted from the csr.json file. - -The following command enrolls the admin user and stores an enrollment certificate (ECert) -in the fabric-ca client's home directory. - -``` -# export FABRIC_CA_HOME=$HOME/fabric-ca/clients/admin -# fabric-ca client enroll -config client-config.json admin adminpw http://localhost:7054 csr.json -``` - -You should see a message similar to `[INFO] enrollment information was successfully stored in` -which indicates where the certificate and key files were stored. - -The enrollment certificate is stored at `$FABRIC_CA_ENROLLMENT_DIR/cert.pem` by default, but a different path can be specified by setting the `FABRIC_CA_CERT_FILE` environment variable. - -The enrollment key is stored at `$FABRIC_CA_ENROLLMENT_DIR/key.pem` by default, but a different -path can be specified by setting the `FABRIC_CA_KEY_FILE` environment variable. - -If `FABRIC_CA_ENROLLMENT_DIR` is not set, the value of the `FABRIC_CA_HOME` -environment variable is used in its place. - -#### Register a new identity - -The user performing the register request must be currently enrolled, and -must also have the proper authority to register the type of user being -registered. - -In particular, the invoker's identity must have been registered with the attribute -"hf.Registrar.Roles". This attribute specifies the types of identities -that the registrar is allowed to register. - -For example, the attributes for a registrar might be as follows, indicating -that this registrar identity can register peer, application, and user identities. - -``` -"attrs": [{"name":"hf.Registrar.Roles", "value":"peer,app,user"}] -``` - -To register a new identity, you must first create a JSON file similar to the one below -which defines information for the identity being registered. -This is a sample of registration information for a peer. - -``` -{ - "id": "peer1", - "type": "peer", - "group": "bank_a", - "attrs": [{"name":"SomeAttrName","value":"SomeAttrValue"}] -} -``` - -The **id** field is the enrollment ID of the identity. - -The **type** field is the type of the identity: orderer, peer, app, or user. - -The **group** field must be a valid group name as found in the *server-config.json* -file. - -The **attrs** field is optional and is not required for a peer, but is shown -here as example of how you associate attributes with any identity. - -Assuming you store the information above in a file named **register.json**, -the following command uses the **admin** user's credentials to -register the **peer1** identity. - -``` -# export FABRIC_CA_HOME=$HOME/fabric-ca/clients/admin -# cd $FABRIC_CA_HOME -# fabric-ca client register -config client-config.json register.json http://localhost:7054 -``` - -The output of a successful *fabric-ca client register* command is a -password similar to `One time password: gHIexUckKpHz`. Make a note of -your password to use in the following section to enroll a peer. - -#### Enrolling a peer identity - -Now that you have successfully registered a peer identity, -you may now enroll the peer given the enrollment ID and secret -(i.e. the *password* from the previous section). - -First, create a CSR (Certificate Signing Request) JSON file similar to -the one described in the [Enrolling the bootstrap user](#EnrollBootstrap) section. -Name the file *csr.json* for the following example. - -This is similar to enrolling the bootstrap user except that -we also demonstrate how to use environment variables to place -the key and certificate files in a specific location. -The following example shows how to place them into a Hyperledger Fabric -MSP (Membership Service Provider) directory structure. -The *MSP_DIR* environment variable refers to the root -directory of MSP in Hyperledger Fabric and the $MSP_DIR/signcerts -and $MSP_DIR/keystore directories must exist. - -Also note that you must replace *\* with the secret which was -returned from the registration in the previous section. - -``` -# export FABRIC_CA_CERT_FILE=$MSP_DIR/signcerts/peer.pem -# export FABRIC_CA_KEY_FILE=$MSP_DIR/keystore/key.pem -# fabric-ca client enroll -config client-config.json peer1 https://localhost:7054 csr.json -``` - -The peer.pem and key.pem files should now exist at the locations specified -by the environment variables. - -#### Revoke a certificate or user - -In order to revoke a certificate or user, the calling identity must have the -`hf.Revoker` attribute. - -You may revoke a specific certificate by specifying its -AKI (Authority Key Identifier) and its serial number, as shown below. - -``` -fabric-ca client revoke -config client-config.json -aki xxx -serial yyy -reason "you're bad" https://localhost:7054 -``` - -The following command disables a user's identity and also -revokes all of the certificates associated with the identity. All -future requests received by the fabric-ca server from this identity -will be rejected. - -``` -fabric-ca client revoke -config client-config.json https://localhost:7054 ENROLLMENT-ID -reason "you're really bad" -``` - -#### Enabling TLS for a fabric-ca client - -This section describes in more detail how to configure TLS for a fabric-ca client. - -The following sections may be configured in the `client-config.json`. - -``` -{ -"ca_certfiles":["CA_root_cert.pem"], -"client":[{"keyfile":"client-key.pem","certfile":"client-cert.pem"}] -} -``` - -The **ca_certfiles** option is the set of root certificates trusted by the client. -This will typically just be the root fabric-ca server's certificate found in -the server's home directory in the **server-cert.pem** file. - -The **client** option is required only if mutual TLS is configured on the server. - -## Appendix - -### Postgres SSL Configuration - -**Basic instructions for configuring SSL on Postgres server:** -1. In postgresql.conf, uncomment SSL and set to "on" (SSL=on) -2. Place Certificate and Key files Postgress data directory. - -Instructions for generating self-signed certificates for: -https://www.postgresql.org/docs/9.1/static/ssl-tcp.html - -Note: Self-signed certificates are for testing purposes and should not be used -in a production environment - -**Postgres Server - Require Client Certificates** -1. Place certificates of the certificate authorities (CAs) you trust in the file - root.crt in the Postgres data directory -2. In postgresql.conf, set "ssl_ca_file" to point to the root cert of client (CA cert) -3. Set the clientcert parameter to 1 on the appropriate hostssl line(s) in pg_hba.conf. - -For more details on configuring SSL on the Postgres server, please refer to the -following Postgres documentation: https://www.postgresql.org/docs/9.4/static/libpq-ssl.html - - -### MySQL SSL Configuration -**Basic instructions for configuring SSL on MySQL server:** - -1. Open or create my.cnf file for the server. Add or un-comment the lines below -in [mysqld] section. These should point to the key and certificates for the -server, and the root CA cert. - - Instruction on creating server and client side certs: -http://dev.mysql.com/doc/refman/5.7/en/creating-ssl-files-using-openssl.html - - [mysqld] - ssl-ca=ca-cert.pem - ssl-cert=server-cert.pem - ssl-key=server-key.pem - - Can run the following query to confirm SSL has been enabled. - - mysql> SHOW GLOBAL VARIABLES LIKE 'have_%ssl'; - - Should see: - - ``` - +---------------+-------+ - | Variable_name | Value | - +---------------+-------+ - | have_openssl | YES | - | have_ssl | YES | - +---------------+-------+ - ``` - -2. After the server-side SSL configuration is finished, the next step is to -create a user who has a privilege to access the MySQL server over SSL. For that, -log in to the MySQL server, and type: - - mysql> GRANT ALL PRIVILEGES ON *.* TO 'ssluser'@'%' IDENTIFIED BY 'password' REQUIRE SSL; - mysql> FLUSH PRIVILEGES; - - If you want to give a specific ip address from which the user will access the - server change the '%' to the specific ip address. - - **MySQL Server - Require Client Certificates** - Options for secure connections are similar to those used on the server side. - - - ssl-ca identifies the Certificate Authority (CA) certificate. This option, - if used, must specify the same certificate used by the server. - - ssl-cert identifies the client public key certificate. - - ssl-key identifies the client private key. - - Suppose that you want to connect using an account that has no special encryption - requirements or was created using a GRANT statement that includes the REQUIRE SSL - option. As a recommended set of secure-connection options, start the MySQL - server with at least --ssl-cert and --ssl-key, and invoke the fabric-ca server with - **ca_certfiles** option set in the fabric-ca server file. - - To require that a client certificate also be specified, create the account using - the REQUIRE X509 option. Then the client must also specify the proper client key - and certificate files or the MySQL server will reject the connection. CA cert, - client cert, and client key are all required for the fabric-ca server. diff --git a/docs/Setup/logging-control.md b/docs/Setup/logging-control.md deleted file mode 100644 index 1bde4f51501..00000000000 --- a/docs/Setup/logging-control.md +++ /dev/null @@ -1,135 +0,0 @@ -# Logging Control - -## Overview - -Logging in the `peer` application and in the `shim` interface to chaincodes is programmed using facilities provided by the `github.com/op/go-logging` package. This package supports - -- Logging control based on the severity of the message -- Logging control based on the software _module_ generating the message -- Different pretty-printing options based on the severity of the message - -All logs are currently directed to `stderr`, and the pretty-printing is currently fixed. However global and module-level control of logging by severity is provided for both users and developers. There are currently no formalized rules for the types of information provided at each severity level, however when submitting bug reports the developers may want to see full logs down to the DEBUG level. - -In pretty-printed logs the logging level is indicated both by color and by a 4-character code, e.g, "ERRO" for ERROR, "DEBU" for DEBUG, etc. In the logging context a _module_ is an arbitrary name (string) given by developers to groups of related messages. In the pretty-printed example below, the logging modules "peer", "rest" and "main" are generating logs. - - 16:47:09.634 [peer] GetLocalAddress -> INFO 033 Auto detected peer address: 9.3.158.178:7051 - 16:47:09.635 [rest] StartOpenchainRESTServer -> INFO 035 Initializing the REST service... - 16:47:09.635 [main] serve -> INFO 036 Starting peer with id=name:"vp1" , network id=dev, address=9.3.158.178:7051, discovery.rootnode=, validator=true - -An arbitrary number of logging modules can be created at runtime, therefore -there is no "master list" of modules, and logging control constructs can not -check whether logging modules actually do or will exist. Also note that the -logging module system does not understand hierarchy or wildcarding: You may -see module names like "foo/bar" in the code, but the logging system only sees -a flat string. It doesn't understand that "foo/bar" is related to "foo" in any -way, or that "foo/\*" might indicate all "submodules" of foo. - -## peer - -The logging level of the `peer` command can be controlled from the command line for each invocation using the `--logging-level` flag, for example - - peer node start --logging-level=debug - -The default logging level for each individual `peer` subcommand can also be -set in the -[core.yaml](https://github.com/hyperledger/fabric/blob/master/peer/core.yaml) -file. For example the key `logging.node` sets the default level for the `node` -subcommmand. Comments in the file also explain how the logging level can be -overridden in various ways by using environment varaibles. - -Logging severity levels are specified using case-insensitive strings chosen from - - CRITICAL | ERROR | WARNING | NOTICE | INFO | DEBUG - -The full logging level specification for the `peer` is of the form - - [[,...]=][:[[,...]=]...] - -A logging level by itself is taken as the overall default. Otherwise, overrides for individual or groups of modules can be specified using the - - [,...]= - -syntax. Examples of specifications (valid for all of -`--logging-level`, environment variable and -[core.yaml](https://github.com/hyperledger/fabric/blob/master/peer/core.yaml) -settings): - - info - Set default to INFO - warning:main,db=debug:chaincode=info - Default WARNING; Override for main,db,chaincode - chaincode=info:main=debug:db=debug:warning - Same as above - -## Go chaincodes - -The standard mechanism to log within a chaincode application is to integrate with the logging transport exposed to each chaincode instance via the peer. The chaincode `shim` package provides APIs that allow a chaincode to create and manage logging objects whose logs will be formatted and interleaved consistently with the `shim` logs. - -As independently executed programs, user-provided chaincodes may technically also produce output on stdout/stderr. While naturally useful for "devmode", these channels are normally disabled on a production network to mitigate abuse from broken or malicious code. However, it is possible to enable this output even for peer-managed containers (e.g. "netmode") on a per-peer basis via the CORE_VM_DOCKER_ATTACHSTDOUT=true configuration option. - -Once enabled, each chaincode will receive its own logging channel keyed by its container-id. Any output written to either stdout or stderr will be integrated with the peer's log on a per-line basis. It is not recommended to enable this for production. - -### API - -`NewLogger(name string) *ChaincodeLogger` - Create a logging object for use by a chaincode - -`(c *ChaincodeLogger) SetLevel(level LoggingLevel)` - Set the logging level of the logger - -`(c *ChaincodeLogger) IsEnabledFor(level LoggingLevel) bool` - Return true if logs will be generated at the given level - -`LogLevel(levelString string) (LoggingLevel, error)` - Convert a string to a `LoggingLevel` - -A `LoggingLevel` is a member of the enumeration - -``` -LogDebug, LogInfo, LogNotice, LogWarning, LogError, LogCritical -``` - -which can be used directly, or generated by passing a case-insensitive version of the strings - -``` -DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL -``` - -to the `LogLevel` API. - -Formatted logging at various severity levels is provided by the functions - -``` -(c *ChaincodeLogger) Debug(args ...interface{}) -(c *ChaincodeLogger) Info(args ...interface{}) -(c *ChaincodeLogger) Notice(args ...interface{}) -(c *ChaincodeLogger) Warning(args ...interface{}) -(c *ChaincodeLogger) Error(args ...interface{}) -(c *ChaincodeLogger) Critical(args ...interface{}) - -(c *ChaincodeLogger) Debugf(format string, args ...interface{}) -(c *ChaincodeLogger) Infof(format string, args ...interface{}) -(c *ChaincodeLogger) Noticef(format string, args ...interface{}) -(c *ChaincodeLogger) Warningf(format string, args ...interface{}) -(c *ChaincodeLogger) Errorf(format string, args ...interface{}) -(c *ChaincodeLogger) Criticalf(format string, args ...interface{}) -``` - -The `f` forms of the logging APIs provide for precise control over the formatting of the logs. The non-`f` forms of the APIs currently insert a space between the printed representations of the arguments, and arbitrarily choose the formats to use. - -In the current implementation, the logs produced by the `shim` and a `ChaincodeLogger` are timestamped, marked with the logger *name* and severity level, and written to `stderr`. Note that logging level control is currently based on the *name* provided when the `ChaincodeLogger` is created. To avoid ambiguities, all `ChaincodeLogger` should be given unique names other than "shim". The logger *name* will appear in all log messages created by the logger. The `shim` logs as "shim". - - -Go language chaincodes can also control the logging level of the chaincode `shim` interface through the `SetLoggingLevel` API. - -`SetLoggingLevel(LoggingLevel level)` - Control the logging level of the shim - -The default logging level for the shim is `LogDebug`. - -Below is a simple example of how a chaincode might create a private logging object logging at the `LogInfo` level, and also control the amount of logging provided by the `shim` based on an environment variable. - -``` -var logger = shim.NewLogger("myChaincode") - -func main() { - - logger.SetLevel(shim.LogInfo) - - logLevel, _ := shim.LogLevel(os.Getenv("SHIM_LOGGING_LEVEL")) - shim.SetLoggingLevel(logLevel) - ... -} -``` diff --git a/docs/Style-guides/go-style.md b/docs/Style-guides/go-style.md deleted file mode 100644 index dc5f08902cb..00000000000 --- a/docs/Style-guides/go-style.md +++ /dev/null @@ -1,48 +0,0 @@ -## Coding guidelines - -### Coding Golang - -We code in Go™ and strictly follow the [best -practices](http://golang.org/doc/effective_go.html) and will not accept any -deviations. You must run the following tools against your Go code and fix all -errors and warnings: - - [golint](https://github.com/golang/lint) - - [go vet](https://golang.org/cmd/vet/) - - [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports) - -## Generating gRPC code - -If you modify any `.proto` files, run the following command to generate/update -the respective `.pb.go` files. - -``` -cd $GOPATH/src/github.com/hyperledger/fabric -make protos -``` - -## Adding or updating Go packages - -The Hyperledger Fabric Project uses Go 1.6 vendoring for package management. -This means that all required packages reside in the `vendor` folder within the -fabric project. Go will use packages in this folder instead of the GOPATH when -the `go install` or `go build` commands are executed. To manage the packages in -the `vendor` folder, we use [Govendor](https://github.com/kardianos/govendor), -which is installed in the Vagrant environment. The following commands can be -used for package management: - -``` - # Add external packages. - govendor add +external - - # Add a specific package. - govendor add github.com/kardianos/osext - - # Update vendor packages. - govendor update +vendor - - # Revert back to normal GOPATH packages. - govendor remove +vendor - - # List package. - govendor list -``` diff --git a/docs/SystemChaincode-noop.md b/docs/SystemChaincode-noop.md deleted file mode 100644 index d7320a69790..00000000000 --- a/docs/SystemChaincode-noop.md +++ /dev/null @@ -1,9 +0,0 @@ -### NO-OP system chaincode -NO-OP is a system chaincode that does nothing when invoked. The parameters of the invoke transaction are stored on the ledger so it is possible to encode arbitrary data into them. - -#### Functions and valid options -- Invoke transactions have to be called with *'execute'* as function name and at least one argument. Only the **first argument** is used. Note that it should be **encoded with BASE64**. -- Only one type of query is supported: *'getTran'* (passed as a function name). GetTran has to get a transaction ID as argument in hexadecimal format. The function looks up the corresponding transaction's (if any) **first argument** and tries to **decode it as a BASE64 encoded string**. - -#### Testing -NO-OP has unit tests checking invocation and queries using proper/improper arguments. The chaincode implementation provides a facility for mocking the ledger under the chaincode (*mockLedgerH* in struct *chaincode.SystemChaincode*). This should only be used for testing as it is dangerous to rely on global variables in memory that can hold state across invokes. diff --git a/docs/abstract_v1.md b/docs/abstract_v1.md deleted file mode 100644 index d082f7c8a46..00000000000 --- a/docs/abstract_v1.md +++ /dev/null @@ -1,74 +0,0 @@ -# HYPERLEDGER FABRIC v1.0 - -Hyperledger Fabric is a platform that enables the delivery of a secure, robust, -permissioned blockchain for the enterprise that incorporates a byzantine fault -tolerant consensus. We have learned much as we progressed through the v0.6-preview -release. In particular, that in order to provide for the scalability and confidentiality -needs of many use cases, a refactoring of the architecture was needed. The v0.6-preview -release will be the final (barring any bug fixes) release based upon the original architecture. - -Hyperledger Fabric's v1.0 architecture has been designed to address two vital -enterprise-grade requirements – **security** and **scalability**. Businesses and -organizations can leverage this new architecture to execute confidential transactions -on networks with shared or common assets – e.g. supply chain, FOREX market, healthcare, etc. -The progression to v1.0 will be incremental, with myriad windows for community -members to contribute code and start curating the fabric to fit specific business needs. - -## WHERE WE ARE: - -The current implementation involves every validating peer shouldering the responsibility -for the full gauntlet of network functionality. They execute transactions, perform -consensus, and maintain the shared ledger. Not only does this configuration lay a -huge computational burden on each peer, hindering scalability, but it also constricts -important facets of privacy and confidentiality. Namely, there is no mechanism to -“channel” or “silo” confidential transactions. Every peer can see the most minute, -and at times, sensitive details and logic of every transaction. This is untenable -for many enterprise businesses, who must abide by stringent regulatory statutes. - -## WHERE WE'RE GOING - -The new architecture introduces a clear functional separation of peer roles, and -allows a transaction to pass through the network in a structured and modularized fashion. -The peers are diverged into two distinct roles – Endorser & Committer. As an endorser, -the peer will simulate the transaction and ensure that the outcome is both deterministic -and stable. As a committer, the peer will validate the integrity of a transaction -and then append to the ledger. Now confidential transactions can be sent to specific -endorsers and their correlating committers, without the broader network being made cognizant of -the transaction. Additionally, policies can be set to determine what levels of -“endorsement” and “validation” are acceptable for a specific class of transactions. -A failure to meet these thresholds would simply result in a transaction being withdrawn -or labeled as "invalid", rather than imploding or stagnating the entire network. -This new model also introduces the possibility for more elaborate networks, such as a -foreign exchange market. For example, trade settlement might be contingent upon a -mandatory "endorsement" from a trusted third party (e.g. a clearing house). - -The consensus or "ordering" process (i.e. algorithmic computation) is entirely abstracted -from the peer. This modularity not only provides a powerful security layer – the -ordering nodes are agnostic to the transaction logic – but it also generates a framework -where ordering can become a pluggable implementation and scalability can truly occur. -There is no longer a parallel relationship between the number of peers in a network and -the number of orderers. Now networks can grow dynamically (i.e. add endorsers and committers) -without having to add corresponding orderers, all the while existing in a modular -infrastructure designed to support high transaction throughput. Moreover, networks -now have the capability to completely liberate themselves from the computational and -legal burden of ordering by tapping into a pre-existing or third party-hosted "ordering service." - -As v1.0 manifests, we will see the foundation for interoperable blockchain networks -that have the ability to scale and transact in a manner adherent with regulatory and -industry standards. Watch how fabric v1.0 and the Hyperledger Project are building a -true blockchain for business - - -[![HYPERLEDGERv1.0_ANIMATION](http://img.youtube.com/vi/EKa5Gh9whgU/0.jpg)](http://www.youtube.com/watch?v=EKa5Gh9whgU) - -## HOW TO CONTRIBUTE - -Use the following links to explore upcoming additions to the codebase that will spawn the capabilities in v1.0: - -* Familiarize yourself with the [guidelines for code contributions](CONTRIBUTING.md) to this project. **Note**: In order to participate in the development of the Hyperledger Fabric project, you will need an [LF account](Gerrit/lf-account.md). This will give you single sign-on to JIRA and Gerrit. -* Explore the design document for the new [architecture](https://github.com/hyperledger/fabric/blob/master/proposals/r1/Next-Consensus-Architecture-Proposal.md) -* Explore design docs for the various [Fabric components](https://wiki.hyperledger.org/community/fabric-design-docs) -* Explore [JIRA](https://jira.hyperledger.org/projects/FAB/issues/) for open Hyperledger Fabric issues. -* Explore the [JIRA](https://jira.hyperledger.org/projects/FAB/issues/) backlog for upcoming Hyperledger Fabric issues. -* Explore [JIRA](https://jira.hyperledger.org/issues/?filter=10147) for Hyperledger Fabric issues tagged with "help wanted." -* Explore the [source code](https://github.com/hyperledger/fabric) -* Explore the [documentation](http://hyperledger-fabric.readthedocs.io/en/latest/) diff --git a/docs/adminops.md b/docs/adminops.md deleted file mode 100644 index 985afb1c8c9..00000000000 --- a/docs/adminops.md +++ /dev/null @@ -1,4 +0,0 @@ -# Administration and operations - -[WIP] -...coming soon diff --git a/docs/arch-deep-dive.md b/docs/arch-deep-dive.md deleted file mode 100644 index 887dada7abc..00000000000 --- a/docs/arch-deep-dive.md +++ /dev/null @@ -1,369 +0,0 @@ -This page documents the architecture of a blockchain infrastructure with the roles of a blockchain node separated into roles of *peers* (who maintain state/ledger) and *orderers* (who consent on the order of transactions included in the ledger). In common blockchain architectures (including Hyperledger Fabric v0.6 and earlier) these roles are unified (cf. *validating peer* in Hyperledger Fabric v0.6). The architecture also introduces *endorsing peers* (endorsers), as special type of peers responsible for simulating execution and *endorsing* transactions (roughly corresponding to executing transactions in HL Fabric 0.6). - -The architecture has the following advantages compared to the design in which peers/orderers/endorsers are unified (e.g., HL Fabric v0.6). - -* **Chaincode trust flexibility.** The architecture separates *trust assumptions* for chaincodes (blockchain applications) from trust assumptions for ordering. In other words, the ordering service may be provided by one set of nodes (orderers) and tolerate some of them to fail or misbehave, and the endorsers may be different for each chaincode. - -* **Scalability.** As the endorser nodes responsible for particular chaincode are orthogonal to the orderers, the system may *scale* better than if these functions were done by the same nodes. In particular, this results when different chaincodes specify disjoint endorsers, which introduces a partitioning of chaincodes between endorsers and allows parallel chaincode execution (endorsement). Besides, chaincode execution, which can potentially be costly, is removed from the critical path of the ordering service. - -* **Confidentiality.** The architecture facilitates deployment of chaincodes that have *confidentiality* requirements with respect to the content and state updates of its transactions. - -* **Consensus modularity.** The architecture is *modular* and allows pluggable consensus (i.e., ordering service) implementations. - -This architecture drives the development of Hyperledger Fabric post-v0.6. As detailed below, some of its aspects are to be included in Hyperledger Fabric v1, whereas others are postponed to post-v1 versions of Hyperledger Fabric. - -## Table of contents - -**Part I: Elements of the architecture relevant to Hyperledger Fabric v1** - -1. System architecture -1. Basic workflow of transaction endorsement -1. Endorsement policies - - **Part II: Post-v1 elements of the architecture** - -1. Ledger checkpointing (pruning) - - ---- - -## 1. System architecture - -The blockchain is a distributed system consisting of many nodes that communicate with each other. The blockchain runs programs called chaincode, holds state and ledger data, and executes transactions. The chaincode is the central element as transactions are operations invoked on the chaincode. Transactions have to be "endorsed" and only endorsed transactions may be committed and have an effect on the state. There may exist one or more special chaincodes for management functions and parameters, collectively called *system chaincodes*. - - -### 1.1. Transactions - -Transactions may be of two types: - -* *Deploy transactions* create new chaincode and take a program as parameter. When a deploy transaction executes successfully, the chaincode has been installed "on" the blockchain. - -* *Invoke transactions* perform an operation in the context of previously deployed chaincode. An invoke transaction refers to a chaincode and to one of its provided functions. When successful, the chaincode executes the specified function - which may involve modifying the corresponding state, and returning an output. - -As described later, deploy transactions are special cases of invoke transactions, where a deploy transaction that creates new chaincode, corresponds to an invoke transaction on a system chaincode. - -**Remark:** *This document currently assumes that a transaction either creates new chaincode or invokes an operation provided by _one_ already deployed chaincode. This document does not yet describe: a) optimizations for query (read-only) transactions (included in v1), b) support for cross-chaincode transactions (post-v1 feature).* - -### 1.2. Blockchain datastructures - -#### 1.2.1. State - -The latest state of the blockchain (or, simply, *state*) is modeled as a versioned key/value store (KVS), where keys are names and values are arbitrary blobs. These entries are manipulated by the chaincodes (applications) running on the blockchain through `put` and `get` KVS-operations. The state is stored persistently and updates to the state are logged. Notice that versioned KVS is adopted as state model, an implementation may use actual KVSs, but also RDBMSs or any other solution. - -More formally, state `s` is modeled as an element of a mapping `K -> (V X N)`, where: - -* `K` is a set of keys -* `V` is a set of values -* `N` is an infinite ordered set of version numbers. Injective function `next: N -> N` takes an element of `N` and returns the next version number. - -Both `V` and `N` contain a special element `\bot`, which is in case of `N` the lowest element. Initially all keys are mapped to `(\bot,\bot)`. For `s(k)=(v,ver)` we denote `v` by `s(k).value`, and `ver` by `s(k).version`. - -KVS operations are modeled as follows: - -* `put(k,v)`, for `k\in K` and `v\in V`, takes the blockchain state `s` and changes it to `s'` such that `s'(k)=(v,next(s(k).version))` with `s'(k')=s(k')` for all `k'!=k`. -* `get(k)` returns `s(k)`. - -State is maintained by peers, but not by orderers and clients. - -**State partitioning.** Keys in the KVS can be recognized from their name to belong to a particular chaincode, in the sense that only transaction of a certain chaincode may modify the keys belonging to this chaincode. In principle, any chaincode can read the keys belonging to other chaincodes. *Support for cross-chaincode transactions, that modify the state belonging to two or more chaincodes is a post-v1 feature.* - - -#### 1.2.2 Ledger - -Ledger provides a verifiable history of all successful state changes (we talk about *valid* transactions) and unsuccessful attempts to change state (we talk about *invalid* transactions), occurring during the operation of the system. - -Ledger is constructed by the ordering service (see Sec 1.3.3) as a totally ordered hashchain of *blocks* of (valid or invalid) transactions. The hashchain imposes the total order of blocks in a ledger and each block contains an array of totally ordered transactions. This imposes total order across all transactions. - -Ledger is kept at all peers and, optionally, at a subset of orderers. In the context of an orderer we refer to the Ledger as to `OrdererLedger`, whereas in the context of a peer we refer to the ledger as to `PeerLedger`. `PeerLedger` differs from the `OrdererLedger` in that peers locally maintain a bitmask that tells apart valid transactions from invalid ones (see Section XX for more details). - -Peers may prune `PeerLedger` as described in Section XX (post-v1 feature). Orderers maintain `OrdererLedger` for fault-tolerance and availability (of the `PeerLedger`) and may decide to prune it at anytime, provided that properties of the ordering service (see Sec. 1.3.3) are maintained. - -The ledger allows peers to replay the history of all transactions and to reconstruct the state. Therefore, state as described in Sec 1.2.1 is an optional datastructure. - -### 1.3. Nodes - -Nodes are the communication entities of the blockchain. A "node" is only a logical function in the sense that multiple nodes of different types can run on the same physical server. What counts is how nodes are grouped in "trust domains" and associated to logical entities that control them. - -There are three types of nodes: - -1. **Client** or **submitting-client**: a client that submits an actual transaction-invocation to the endorsers, and broadcasts transaction-proposals to the ordering service. - -1. **Peer**: a node that commits transactions and maintains the state and a copy of the ledger (see Sec, 1.2). Besides, peers can have a special **endorser** role. - -1. **Ordering-service-node** or **orderer**: a node running the communication service that implements a delivery guarantee, such as atomic or total order broadcast. - -The types of nodes are explained next in more detail. - -#### 1.3.1. Client - -The client represents the entity that acts on behalf of an end-user. It must connect to a peer for communicating with the blockchain. The client may connect to any peer of its choice. Clients create and thereby invoke transactions. - -As detailed in Section 2, clients communicate with both peers and the ordering service. - -#### 1.3.2. Peer - -A peer receives ordered state updates in the form of *blocks* from the ordering service and maintain the state and the ledger. - -Peers can additionally take up a special role of an **endorsing peer**, or an **endorser**. The special function of an *endorsing peer* occurs with respect to a particular chaincode and consists in *endorsing* a transaction before it is committed. Every chaincode may specify an *endorsement policy* that may refer to a set of endorsing peers. The policy defines the necessary and sufficient conditions for a valid transaction endorsement (typically a set of endorsers' signatures), as described later in Sections 2 and 3. In the special case of deploy transactions that install new chaincode the (deployment) endorsement policy is specified as an endorsement policy of the system chaincode. - - -#### 1.3.3. Ordering service nodes (Orderers) - -The *orderers* form the *ordering service*, i.e., a communication fabric that provides delivery guarantees. The ordering service can be implemented in different ways: ranging from a centralized service (used e.g., in development and testing) to distributed protocols that target different network and node fault models. - -Ordering service provides a shared *communication channel* to clients and peers, offering a broadcast service for messages containing transactions. Clients connect to the channel and may broadcast messages on the channel which are then delivered to all peers. The channel supports *atomic* delivery of all messages, that is, message communication with total-order delivery and (implementation specific) reliability. In other words, the channel outputs the same messages to all connected peers and outputs them to all peers in the same logical order. This atomic communication guarantee is also called *total-order broadcast*, *atomic broadcast*, or *consensus* in the context of distributed systems. The communicated messages are the candidate transactions for inclusion in the blockchain state. - -**Partitioning (ordering service channels).** Ordering service may support multiple *channels* similar to the *topics* of a publish/subscribe (pub/sub) messaging system. Clients can connects to a given channel and can then send messages and obtain the messages that arrive. Channels can be thought of as partitions - clients connecting to one channel are unaware of the existence of other channels, but clients may connect to multiple channels. Even though some ordering service implementations included with Hyperledger Fabric v1 will support multiple channels, for simplicity of presentation, in the rest of this document, we assume ordering service consists of a single channel/topic. - -**Ordering service API.** Peers connect to the channel provided by the ordering service, via the interface provided by the ordering service. The ordering service API consists of two basic operations (more generally *asynchronous events*): - -**TODO** add the part of the API for fetching particular blocks under client/peer specified sequence numbers. - -* `broadcast(blob)`: a client calls this to broadcast an arbitrary message `blob` for dissemination over the channel. This is also called `request(blob)` in the BFT context, when sending a request to a service. - -* `deliver(seqno, prevhash, blob)`: the ordering service calls this on the peer to deliver the message `blob` with the specified non-negative integer sequence number (`seqno`) and hash of the most recently delivered blob (`prevhash`). In other words, it is an output event from the ordering service. `deliver()` is also sometimes called `notify()` in pub-sub systems or `commit()` in BFT systems. - -**Ledger and block formation.** The ledger (see also Sec. 1.2.2) contains all data output by the ordering service. In a nutshell, it is a sequence of `deliver(seqno, prevhash, blob)` events, which form a hash chain according to the computation of `prevhash` described before. - -Most of the time, for efficiency reasons, instead of outputting individual transactions (blobs), the ordering service will group (batch) the blobs and output *blocks* within a single `deliver` event. In this case, the ordering service must impose and convey a deterministic ordering of the blobs within each block. The number of blobs in a block may be chosen dynamically by an ordering service implementation. - -In the following, for ease of presentation, we define ordering service properties (rest of this subsection) and explain the workflow of transaction endorsement (Section 2) assuming one blob per `deliver` event. These are easily extended to blocks, assuming that a `deliver` event for a block corresponds to a sequence of individual `deliver` events for each blob within a block, according to the above mentioned deterministic ordering of blobs within a blocs. - -**Ordering service properties** - -The guarantees of the ordering service (or atomic-broadcast channel) stipulate what happens to a broadcasted message and what relations exist among delivered messages. These guarantees are as follows: - -1. **Safety (consistency guarantees)**: As long as peers are connected for sufficiently long periods of time to the channel (they can disconnect or crash, but will restart and reconnect), they will see an *identical* series of delivered `(seqno, prevhash, blob)` messages. This means the outputs (`deliver()` events) occur in the *same order* on all peers and according to sequence number and carry *identical content* (`blob` and `prevhash`) for the same sequence number. Note this is only a *logical order*, and a `deliver(seqno, prevhash, blob)` on one peer is not required to occur in any real-time relation to `deliver(seqno, prevhash, blob)` that outputs the same message at another peer. Put differently, given a particular `seqno`, *no* two correct peers deliver *different* `prevhash` or `blob` values. Moreover, no value `blob` is delivered unless some client (peer) actually called `broadcast(blob)` and, preferably, every broadcasted blob is only delivered *once*. - - Furthermore, the `deliver()` event contains the cryptographic hash of the data in the previous `deliver()` event (`prevhash`). When the ordering service implements atomic broadcast guarantees, `prevhash` is the cryptographic hash of the parameters from the `deliver()` event with sequence number `seqno-1`. This establishes a hash chain across `deliver()` events, which is used to help verify the integrity of the ordering service output, as discussed in Sections 4 and 5 later. In the special case of the first `deliver()` event, `prevhash` has a default value. - - -1. **Liveness (delivery guarantee)**: Liveness guarantees of the ordering service are specified by a ordering service implementation. The exact guarantees may depend on the network and node fault model. - - In principle, if the submitting client does not fail, the ordering service should guarantee that every correct peer that connects to the ordering service eventually delivers every submitted transaction. - - -To summarize, the ordering service ensures the following properties: - -* *Agreement.* For any two events at correct peers `deliver(seqno, prevhash0, blob0)` and `deliver(seqno, prevhash1, blob1)` with the same `seqno`, `prevhash0==prevhash1` and `blob0==blob1`; -* *Hashchain integrity.* For any two events at correct peers `deliver(seqno-1, prevhash0, blob0)` and `deliver(seqno, prevhash, blob)`, `prevhash = HASH(seqno-1||prevhash0||blob0)`. -* *No skipping*. If an ordering service outputs `deliver(seqno, prevhash, blob)` at a correct peer *p*, such that `seqno>0`, then *p* already delivered an event `deliver(seqno-1, prevhash0, blob0)`. -* *No creation*. Any event `deliver(seqno, prevhash, blob)` at a correct peer must be preceded by a `broadcast(blob)` event at some (possibly distinct) peer; -* *No duplication (optional, yet desirable)*. For any two events `broadcast(blob)` and `broadcast(blob')`, when two events `deliver(seqno0, prevhash0, blob)` and `deliver(seqno1, prevhash1, blob')` occur at correct peers and `blob == blob'`, then `seqno0==seqno1` and `prevhash0==prevhash1`. -* *Liveness*. If a correct client invokes an event `broadcast(blob)` then every correct peer "eventually" issues an event `deliver(*, *, blob)`, where `*` denotes an arbitrary value. - - -## 2. Basic workflow of transaction endorsement - -In the following we outline the high-level request flow for a transaction. - -**Remark:** *Notice that the following protocol _does not_ assume that all transactions are deterministic, i.e., it allows for non-deterministic transactions.* - -### 2.1. The client creates a transaction and sends it to endorsing peers of its choice - -To invoke a transaction, the client sends a `PROPOSE` message to a set of endorsing peers of its choice (possibly not at the same time - see Sections 2.1.2. and 2.3.). The set of endorsing peers for a given `chaincodeID` is made available to client via peer, which in turn knows the set of endorsing peers from endorsement policy (see Section 3). For example, the transaction could be sent to *all* endorsers of a given `chaincodeID`. That said, some endorsers could be offline, others may object and choose not to endorse the transaction. The submitting client tries to satisfy the policy expression with the endorsers available. - -In the following, we first detail `PROPOSE` message format and then discuss possible patterns of interaction between submitting client and endorsers. - -### 2.1.1. `PROPOSE` message format - -The format of a `PROPOSE` message is ``, where `tx` is a mandatory and `anchor` optional argument explained in the following. - -- `tx=`, where - - `clientID` is an ID of the submitting client, - - `chaincodeID` refers to the chaincode to which the transaction pertains, - - `txPayload` is the payload containing the submitted transaction itself, - - `timestamp` is a monotonically increasing (for every new transaction) integer maintained by the client, - - `clientSig` is signature of a client on other fields of `tx`. - - The details of `txPayload` will differ between invoke transactions and deploy transactions (i.e., invoke transactions referring to a deploy-specific system chaincode). For an **invoke transaction**, `txPayload` would consist of two fields - - - `txPayload = `, where - - `operation` denotes the chaincode operation (function) and arguments, - - `metadata` denotes attributes related to the invocation. - - For a **deploy transaction**, `txPayload` would consist of three fields - - - `txPayload = `, where - - `source` denotes the source code of the chaincode, - - `metadata` denotes attributes related to the chaincode and application, - - `policies` contains policies related to the chaincode that are accessible to all peers, such as the endorsement policy. Note that endorsement policies are not supplied with `txPayload` in a `deploy` transaction, but `txPayload of a `deploy` contains endorsement policy ID and its parameters (see Section 3). - -- `anchor` contains _read version dependencies_, or more specifically, key-version pairs (i.e., `anchor` is a subset of `KxN`), that binds or "anchors" the `PROPOSE` request to specified versions of keys in a KVS (see Section 1.2.). If the client specifies the `anchor` argument, an endorser endorses a transaction only upon _read_ version numbers of corresponding keys in its local KVS match `anchor` (see Section 2.2. for more details). - -Cryptographic hash of `tx` is used by all nodes as a unique transaction identifier `tid` (i.e., `tid=HASH(tx)`). -The client stores `tid` in memory and waits for responses from endorsing peers. - -#### 2.1.2. Message patterns - -The client decides on the sequence of interaction with endorsers. For example, a client would typically send `` (i.e., without the `anchor` argument) to a single endorser, which would then produce the version dependencies (`anchor`) which the client can later on use as an argument of its `PROPOSE` message to other endorsers. As another example, the client could directly send `` (without `anchor`) to all endorsers of its choice. Different patterns of communication are possible and client is free to decide on those (see also Section 2.3.). - -### 2.2. The endorsing peer simulates a transaction and produces an endorsement signature - -On reception of a `` message from a client, the endorsing peer `epID` first verifies the client's signature `clientSig` and then simulates a transaction. If the client specifies `anchor` then endorsing peer simulates the transactions only upon read version numbers (i.e., `readset` as defined below) of corresponding keys in its local KVS match those version numbers specified by `anchor`. - -Simulating a transaction involves endorsing peer tentatively *executing* a transaction (`txPayload`), by invoking the chaincode to which the transaction refers (`chaincodeID`) and the copy of the state that the endorsing peer locally holds. - -As a result of the execution, the endorsing peer computes _read version dependencies_ (`readset`) and _state updates_ (`writeset`), also called *MVCC+postimage info* in DB language. - -Recall that the state consists of key/value (k/v) pairs. All k/v entries are versioned, that is, every entry contains ordered version information, which is incremented every time when the value stored under a key is updated. The peer that interprets the transaction records all k/v pairs accessed by the chaincode, either for reading or for writing, but the peer does not yet update its state. More specifically: - -* Given state `s` before an endorsing peer executes a transaction, for every key `k` read by the transaction, pair `(k,s(k).version)` is added to `readset`. -* Additionally, for every key `k` modified by the transaction to the new value `v'`, pair `(k,v')` is added to `writeset`. Alternatively, `v'` could be the delta of the new value to previous value (`s(k).value`). - -If a client specifies `anchor` in the `PROPOSE` message then client specified `anchor` must equal `readset` produced by endorsing peer when simulating the transaction. - -Then, the peer forwards internally `tran-proposal` (and possibly `tx`) to the part of its (peer's) logic that endorses a transaction, referred to as **endorsing logic**. By default, endorsing logic at a peer accepts the `tran-proposal` and simply signs the `tran-proposal`. However, endorsing logic may interpret arbitrary functionality, to, e.g., interact with legacy systems with `tran-proposal` and `tx` as inputs to reach the decision whether to endorse a transaction or not. - -If endorsing logic decides to endorse a transaction, it sends `` message to the submitting client(`tx.clientID`), where: - -- `tran-proposal := (epID,tid,chaincodeID,txContentBlob,readset,writeset)`, - - where `txContentBlob` is chaincode/transaction specific information. The intention is to have `txContentBlob` used as some representation of `tx` (e.g., `txContentBlob=tx.txPayload`). - -- `epSig` is the endorsing peer's signature on `tran-proposal` - -Else, in case the endorsing logic refuses to endorse the transaction, an endorser *may* send a message `(TRANSACTION-INVALID, tid, REJECTED)` to the submitting client. - -Notice that an endorser does not change its state in this step, the updates produced by transaction simulation in the context of endorsement do not affect the state! - -### 2.3. The submitting client collects an endorsement for a transaction and broadcasts it through ordering service - -The submitting client waits until it receives "enough" messages and signatures on `(TRANSACTION-ENDORSED, tid, *, *)` statements to conclude that the transaction proposal is endorsed. As discussed in Section 2.1.2., this may involve one or more round-trips of interaction with endorsers. - -The exact number of "enough" depend on the chaincode endorsement policy (see also Section 3). If the endorsement policy is satisfied, the transaction has been *endorsed*; note that it is not yet committed. The collection of signed `TRANSACTION-ENDORSED` messages from endorsing peers which establish that a transaction is endorsed is called an *endorsement* and denoted by `endorsement`. - -If the submitting client does not manage to collect an endorsement for a transaction proposal, it abandons this transaction with an option to retry later. - -For transaction with a valid endorsement, we now start using the ordering service. The submitting client invokes ordering service using the `broadcast(blob)`, where `blob=endorsement`. If the client does not have capability of invoking ordering service directly, it may proxy its broadcast through some peer of its choice. Such a peer must be trusted by the client not to remove any message from the `endorsement` or otherwise the transaction may be deemed invalid. Notice that, however, a proxy peer may not fabricate a valid `endorsement`. - -### 2.4. The ordering service delivers a transactions to the peers - -When an event `deliver(seqno, prevhash, blob)` occurs and a peer has applied all state updates for blobs with sequence number lower than `seqno`, a peer does the following: - -* It checks that the `blob.endorsement` is valid according to the policy of the chaincode (`blob.tran-proposal.chaincodeID`) to which it refers. - -* In a typical case, it also verifies that the dependencies (`blob.endorsement.tran-proposal.readset`) have not been violated meanwhile. In more complex use cases, `tran-proposal` fields in endorsement may differ and in this case endorsement policy (Section 3) specifies how the state evolves. - -Verification of dependencies can be implemented in different ways, according to a consistency property or "isolation guarantee" that is chosen for the state updates. **Serializability** is a default isolation guarantee, unless chaincode endorsement policy specifies a different one. Serializability can be provided by requiring the version associated with *every* key in the `readset` to be equal to that key's version in the state, and rejecting transactions that do not satisfy this requirement. - -* If all these checks pass, the transaction is deemed *valid* or *committed*. In this case, the peer marks the transaction with 1 in the bitmask of the `PeerLedger`, applies `blob.endorsement.tran-proposal.writeset` to blockchain state (if `tran-proposals` are the same, otherwise endorsement policy logic defines the function that takes `blob.endorsement`). - -* If the endorsement policy verification of `blob.endorsement` fails, the transaction is invalid and the peer marks the transaction with 0 in the bitmask of the `PeerLedger`. It is important to note that invalid transactions do not change the state. - -Note that this is sufficient to have all (correct) peers have the same state after processing a deliver event (block) with a given sequence number. Namely, by the guarantees of the ordering service, all correct peers will receive an identical sequence of `deliver(seqno, prevhash, blob)` events. As the evaluation of the endorsement policy and evaluation of version dependencies in `readset` are deterministic, all correct peers will also come to the same conclusion whether a transaction contained in a blob is valid. Hence, all peers commit and apply the same sequence of transactions and update their state in the same way. - -![Illustration of the transaction flow (common-case path).](http://vukolic.com/hyperledger/flow-4.png) - -Figure 1. Illustration of one possible transaction flow (common-case path). - ---- - -## 3. Endorsement policies - -### 3.1. Endorsement policy specification - -An **endorsement policy**, is a condition on what _endorses_ a transaction. Blockchain peers have a pre-specified set of endorsement policies, which are referenced by a `deploy` transaction that installs specific chaincode. Endorsement policies can be parametrized, and these parameters can be specified by a `deploy` transaction. - -To guarantee blockchain and security properties, the set of endorsement policies **should be a set of proven policies** with limited set of functions in order to ensure bounded execution time (termination), determinism, performance and security guarantees. - -Dynamic addition of endorsement policies (e.g., by `deploy` transaction on chaincode deploy time) is very sensitive in terms of bounded policy evaluation time (termination), determinism, performance and security guarantees. Therefore, dynamic addition of endorsement policies is not allowed, but can be supported in future. - - -### 3.2. Transaction evaluation against endorsement policy - -A transaction is declared valid only if it has been endorsed according to the policy. An invoke transaction for a chaincode will first have to obtain an *endorsement* that satisfies the chaincode's policy or it will not be committed. This takes place through the interaction between the submitting client and endorsing peers as explained in Section 2. - -Formally the endorsement policy is a predicate on the endorsement, and potentially further state that evaluates to TRUE or FALSE. For deploy transactions the endorsement is obtained according to a system-wide policy (for example, from the system chaincode). - -An endorsement policy predicate refers to certain variables. Potentially it may refer to: - -1. keys or identities relating to the chaincode (found in the metadata of the chaincode), for example, a set of endorsers; -2. further metadata of the chaincode; -3. elements of the `endorsement` and `endorsement.tran-proposal`; -4. and potentially more. - -The above list is ordered by increasing expressiveness and complexity, that is, it will be relatively simple to support policies that only refer to keys and identities of nodes. - -**The evaluation of an endorsement policy predicate must be deterministic.** An endorsement shall be evaluated locally by every peer such that a peer does *not* need to interact with other peers, yet all correct peers evaluate the endorsement policy in the same way. - -### 3.3. Example endorsement policies - -The predicate may contain logical expressions and evaluates to TRUE or FALSE. Typically the condition will use digital signatures on the transaction invocation issued by endorsing peers for the chaincode. - -Suppose the chaincode specifies the endorser set `E = {Alice, Bob, Charlie, Dave, Eve, Frank, George}`. Some example policies: - -- A valid signature from on the same `tran-proposal` from all members of E. - -- A valid signature from any single member of E. - -- Valid signatures on the same `tran-proposal` from endorsing peers according to the condition - `(Alice OR Bob) AND (any two of: Charlie, Dave, Eve, Frank, George)`. - -- Valid signatures on the same `tran-proposal` by any 5 out of the 7 endorsers. (More generally, for chaincode with `n > 3f` endorsers, valid signatures by any `2f+1` out of the `n` endorsers, or by any group of *more* than `(n+f)/2` endorsers.) - -- Suppose there is an assignment of "stake" or "weights" to the endorsers, - like `{Alice=49, Bob=15, Charlie=15, Dave=10, Eve=7, Frank=3, George=1}`, - where the total stake is 100: The policy requires valid signatures from a - set that has a majority of the stake (i.e., a group with combined stake - strictly more than 50), such as `{Alice, X}` with any `X` different from - George, or `{everyone together except Alice}`. And so on. - -- The assignment of stake in the previous example condition could be static (fixed in the metadata of the chaincode) or dynamic (e.g., dependent on the state of the chaincode and be modified during the execution). - -- Valid signatures from (Alice OR Bob) on `tran-proposal1` and valid signatures from `(any two of: Charlie, Dave, Eve, Frank, George)` on `tran-proposal2`, where `tran-proposal1` and `tran-proposal2` differ only in their endorsing peers and state updates. - -How useful these policies are will depend on the application, on the desired resilience of the solution against failures or misbehavior of endorsers, and on various other properties. - -## 4 (post-v1). Validated ledger and `PeerLedger` checkpointing (pruning) - -### 4.1. Validated ledger (VLedger) - -To maintain the abstraction of a ledger that contains only valid and committed transactions (that appears in Bitcoin, for example), peers may, in addition to state and Ledger, maintain the *Validated Ledger (or VLedger)*. This is a hash chain derived from the ledger by filtering out invalid transactions. - -The construction of the VLedger blocks (called here *vBlocks*) proceeds as follows. As the `PeerLedger` blocks may contain invalid transactions (i.e., transactions with invalid endorsement or with invalid version dependencies), such transactions are filtered out by peers before a transaction from a block becomes added to a vBlock. Every peer does this by itself (e.g., by using the bitmask associated with `PeerLedger`). A vBlock is defined as a block without the invalid transactions, that have been filtered out. Such vBlocks are inherently dynamic in size and may be empty. An illustration of vBlock construction is given in the figure below. - ![Illustration of the transaction flow (common-case path).](http://vukolic.com/hyperledger/blocks-3.png) - -Figure 2. Illustration of validated ledger block (vBlock) formation from ledger (`PeerLedger`) blocks. - -vBlocks are chained together to a hash chain by every peer. More specifically, every block of a validated ledger contains: - -* The hash of the previous vBlock. - -* vBlock number. - -* An ordered list of all valid transactions committed by the peers since the last vBlock was computed (i.e., list of valid transactions in a corresponding block). - -* The hash of the corresponding block (in `PeerLedger`) from which the current vBlock is derived. - -All this information is concatenated and hashed by a peer, producing the hash of the vBlock in the validated ledger. - - -###4.2. `PeerLedger` Checkpointing - -The ledger contains invalid transactions, which may not necessarily be recorded forever. However, peers cannot simply discard `PeerLedger` blocks and thereby prune `PeerLedger` once they establish the corresponding vBlocks. Namely, in this case, if a new peer joins the network, other peers could not transfer the discarded blocks (pertaining to `PeerLedger`) to the joining peer, nor convince the joining peer of the validity of their vBlocks. - -To facilitate pruning of the `PeerLedger`, this document describes a *checkpointing* mechanism. This mechanism establishes the validity of the vBlocks across the peer network and allows checkpointed vBlocks to replace the discarded `PeerLedger` blocks. This, in turn, reduces storage space, as there is no need to store invalid transactions. It also reduces the work to reconstruct the state for new peers that join the network (as they do not need to establish validity of individual transactions when reconstructing the state by replaying `PeerLedger`, but may simply replay the state updates contained in the validated ledger). - -####4.2.1. Checkpointing protocol - -Checkpointing is performed periodically by the peers every *CHK* blocks, where *CHK* is a configurable parameter. To initiate a checkpoint, the peers broadcast (e.g., gossip) to other peers message ``, where `blockno` is the current blocknumber and `blocknohash` is its respective hash, `stateHash` is the hash of the latest state (produced by e.g., a Merkle hash) upon validation of block `blockno` and `peerSig` is peer's signature on `(CHECKPOINT,blocknohash,blockno,stateHash)`, referring to the validated ledger. - -A peer collects `CHECKPOINT` messages until it obtains enough correctly signed messages with matching `blockno`, `blocknohash` and `stateHash` to establish a *valid checkpoint* (see Section 4.2.2.). - -Upon establishing a valid checkpoint for block number `blockno` with `blocknohash`, a peer: - -* if `blockno>latestValidCheckpoint.blockno`, then a peer assigns `latestValidCheckpoint=(blocknohash,blockno)`, -* stores the set of respective peer signatures that constitute a valid checkpoint into the set `latestValidCheckpointProof`, -* stores the state corresponding to `stateHash` to `latestValidCheckpointedState`, -* (optionally) prunes its `PeerLedger` up to block number `blockno` (inclusive). - -####4.2.2. Valid checkpoints - -Clearly, the checkpointing protocol raises the following questions: *When can a peer prune its `PeerLedger`? How many `CHECKPOINT` messages are "sufficiently many"?*. This is defined by a *checkpoint validity policy*, with (at least) two possible approaches, which may also be combined: - -* *Local (peer-specific) checkpoint validity policy (LCVP).* A local policy at a given peer *p* may specify a set of peers which peer *p* trusts and whose `CHECKPOINT` messages are sufficient to establish a valid checkpoint. For example, LCVP at peer *Alice* may define that *Alice* needs to receive `CHECKPOINT` message from Bob, or from *both* *Charlie* and *Dave*. - -* *Global checkpoint validity policy (GCVP).* A checkpoint validity policy may be specified globally. This is similar to a local peer policy, except that it is stipulated at the system (blockchain) granularity, rather than peer granularity. For instance, GCVP may specify that: - * each peer may trust a checkpoint if confirmed by *11* different peers. - * in a specific deployment in which every orderer is collocated with a peer in the same machine (i.e., trust domain) and where up to *f* orderers may be (Byzantine) faulty, each peer may trust a checkpoint if confirmed by *f+1* different peers collocated with orderers. diff --git a/docs/architecture.md b/docs/architecture.md deleted file mode 100644 index b917907e411..00000000000 --- a/docs/architecture.md +++ /dev/null @@ -1,99 +0,0 @@ -Hyperledger Fabric is a unique implementation of distributed ledger technology -(DLT) that ensures data integrity and consistency while delivering -accountability, transparency, and efficiencies unmatched by other blockchain -or DLT technology. - -Hyperledger Fabric implements a specific type of -[permissioned](glossary.md#permissioned-network) -[blockchain network](glossary.md#blockchain-network) on which members can -track, exchange and interact with digitized assets using -[transactions](glossary.md#transactions) that are governed by smart -contracts - what we call [chaincode](glossary.md#chaincode) - in a secure and -robust manner while enabling [participants](glossary.md#participants) in the -network to interact in a manner that ensures that their transactions and data -can be restricted to an identified subset of network participants - something -we call a [channel](glossary.md#channel). - -The blockchain network supports the ability for members to establish -shared ledgers that contain the source of truth about those digitized -assets, and recorded transactions, that is replicated in a secure manner only -to the set of nodes participating in that channel. - -The Hyperledger Fabric architecture is comprised of the following components: -peer nodes, ordering nodes and the clients applications that are likely -leveraging one of the language-specific Fabric SDKs. These components have -identities derived from certificate authorities. Hyperledger Fabric also -offers a certificate authority service, *fabric-ca* but, you may substitute -that with your own. - -All peer nodes maintain the ledger/state by committing -transactions. In that role, the peer is called a -[committer](glossary.md#committer). Some peers are also responsible for -simulating transactions by executing chaincodes (smart contracts) and endorsing -the result. In that role the peer is called an [endorser](glossary.md#endorser). -A peer may be an endorser for certain types of transactions and just a ledger -maintainer (committer) for others. - -The [orderers](glossary.md#orderer) consent on the order of transactions in a -block to be committed to the ledger. In common blockchain architectures -(including earlier versions of the Hyperledger Fabric) the roles played by -the peer and orderer nodes were unified (cf. validating peer in Hyperledger -Fabric v0.6). The orderers also play a fundamental role in the creation and -management of channels. - -Two or more [participants](glossary.md#participant) may create and join a -channel, and begin to interact. Among other things, the policies governing the -channel membership and chaincode lifecycle are specified at the time of -channel creation. Initially, the members in a channel agree on -the terms of the chaincode that will govern the transactions. When consensus -is reached on the [proposal](glossary.md#proposal) to deploy a given chaincode -(as governed by the life cycle policy for the channel), it is committed to -the ledger. - -Once the chaincode is deployed to the peer nodes in the channel, -[end users](glossary.md#end-users) with the right privileges can propose -transactions on the channel by using one of the language-specific client SDKs -to invoke functions on the deployed chaincode. - -The proposed transactions are sent to endorsers that execute the chaincode -(also called "simulated the transaction"). On successful execution, endorse -the result using the peer's identity and return the result to the client that -initiated the proposal. - -The client application ensures that the results from the endorsers are -consistent and signed by the appropriate endorsers, according to the endorsement -policy for that chaincode and, if so, the application then sends the transaction, -comprised of the result and endorsements, to the ordering service. - -Ordering nodes order the transactions - the result and endorsements received -from the clients - into a block which is then sent to the peer nodes to be -committed to the ledger. The peers then validate the transaction using the -endorsement policy for the transaction's chaincode and against the ledger for -consistency of result. - -Some key capabilities of Hyperledger Fabric include: - -- Allows for complex query for applications that need ability to handle complex -data structures. - -- Implements a permissioned network, also known as a consortia network, where -all members are known to each other. - -- Incorporates a modular approach to various capabilities, enabling network -designers to plug in their preferred implementations for various capabilities -such as consensus (ordering), identity management, and encryption. - -- Provides a flexible approach for specifying policies and pluggable mechanisms -to enforce them. - -- Ability to have multiple channels, isolated from one another, that -allows for multi-lateral transactions amongst select peer nodes, thereby -ensuring high degrees of privacy and confidentiality required by competing -businesses and highly regulated industries on a common network. - -- Network scalability and performance are achieved through separation of -chaincode execution from transaction ordering, which limits the required levels -of trust and verification across nodes for optimization. - -For a deeper dive into the details, please visit -[this document](arch-deep-dive.md). diff --git a/docs/asset_cli.md b/docs/asset_cli.md deleted file mode 100644 index ce13225262f..00000000000 --- a/docs/asset_cli.md +++ /dev/null @@ -1,94 +0,0 @@ -## Manually create and join peers to a new channel - -Use the cli container to manually exercise the create channel and join channel APIs. - -Channel - `myc1` already exists, so let's create a new channel named `myc2`. - -Exec into the cli container: -```bash -docker exec -it cli bash -``` -If successful, you should see the following in your terminal: -```bash -/opt/gopath/src/github.com/hyperledger/fabric/peer # -``` -Send createChannel API to Ordering Service: -``` -peer channel create -c myc2 -o orderer:7050 -``` -This will return a genesis block - `myc2.block` - that you can issue join commands with. -Next, send a joinChannel API to `peer0` and pass in the genesis block as an argument. -The channel is defined within the genesis block: -``` -CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc2.block -``` -To join the other peers to the channel, simply reissue the above command with `peer1` -or `peer2` specified. For example: -``` -CORE_PEER_ADDRESS=peer1:7051 peer channel join -b myc2.block -``` -Once the peers have all joined the channel, you are able to issues queries against -any peer without having to deploy chaincode to each of them. - -## Use cli to install, instantiate, invoke and query - -Run the install command. This command is installing a chaincode named `mycc` to -`peer0` on the Channel ID `myc2` and the chaincode version is v0. -``` -CORE_PEER_ADDRESS=peer0:7051 peer chaincode deploy \ - -o orderer:7050 \ - -C myc2 \ - -n mycc \ - -p github.com/hyperledger/fabric/examples \ - -v v0 -``` - -Next we need to instantiate the chaincode by running the instatiate command on peer cli tool. -The constructor message is initializing `a` and `b` with values of 100 and 200 respectively. - -```bash -CORE_PEER_ADDRESS=peer0:7051 peer chaincode instantiate \ - -o orderer:7050 \ - -C myc2 \ - -n mycc \ - -p github.com/hyperledger/fabric/examples \ - -v v0 \ - -c '{"Args":["init","a","100","b","200"]}' -``` - -Run the invoke command. This invocation is moving 10 units from `a` to `b`. -``` -CORE_PEER_ADDRESS=peer0:7051 peer chaincode invoke \ - -C myc2 \ - -n mycc \ - -c '{"Args":["invoke","a", "b", 10]}' \ - -v v0 -``` -Run the query command. The invocation transferred 10 units from `a` to `b`, therefore -a query against `a` should return the value 90. -``` -CORE_PEER_ADDRESS=peer0:7051 peer chaincode query \ - -C myc2 \ - -n mycc \ - -c '{"function":"invoke","Args":["query","a"]}' \ - -v v0 -``` -You can issue an `exit` command at any time to exit the cli container. - -## Creating your initial channel through the cli - -If you want to manually create the initial channel through the cli container, you will -need to edit the Docker Compose file. Use an editor to open `docker-compose-gettingstarted.yml` and -comment out the `channel_test.sh` command in your cli image. Simply place a `#` to the left -of the command. (Recall that this script is executing the create and join channel -APIs when you run `docker-compose up`) For example: -```bash -cli: - container_name: cli - - working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer -# command: sh -c './channel_test.sh; sleep 1000' -# command: /bin/sh -``` - -Then use the cli commands from above. diff --git a/docs/asset_sdk.md b/docs/asset_sdk.md deleted file mode 100644 index d966a026744..00000000000 --- a/docs/asset_sdk.md +++ /dev/null @@ -1,31 +0,0 @@ -## Use node SDK to register/enroll user, followed by deploy/invoke - -The individual javascript programs will exercise the SDK APIs to register and enroll the client with -the provisioned Certificate Authority. Once the client is properly authenticated, -the programs will demonstrate basic chaincode functionalities - deploy, invoke, and query. Make -sure you are in the working directory where you pulled the source code before proceeding. - -Upon success of each node program, you will receive a "200" response in the terminal. - -Register/enroll & deploy chaincode (Linux or OSX): -```bash -# Deploy initializes key value pairs of "a","100" & "b","200". -GOPATH=$PWD node deploy.js -``` -Register/enroll & deploy chaincode (Windows): -```bash -# Deploy initializes key value pairs of "a","100" & "b","200". -SET GOPATH=%cd% -node deploy.js -``` -Issue an invoke. Move units 100 from "a" to "b": -```bash -node invoke.js -``` -Query against key value "b": -```bash -# this should return a value of 300 -node query.js -``` -Explore the various node.js programs, along with `example_cc.go` to better understand -the SDK and APIs. diff --git a/docs/asset_setup.md b/docs/asset_setup.md deleted file mode 100644 index 3a6c3bddf81..00000000000 --- a/docs/asset_setup.md +++ /dev/null @@ -1,134 +0,0 @@ -## Prerequisites and setup - -* [Go](https://golang.org/) - most recent version -* [Docker](https://www.docker.com/products/overview) - v1.13 or higher -* [Docker Compose](https://docs.docker.com/compose/overview/) - v1.8 or higher -* [Node.js & npm](https://nodejs.org/en/download/) - node v6.9.5 and npm v3.10.10 -* [xcode](https://developer.apple.com/xcode/) - only required for OS X users -* [nvm](https://github.com/creationix/nvm/blob/master/README.markdown) - if you want to use `nvm install` command -If you already have node on your machine, use the node website to install v6.9.5 or -issue the following command in your terminal: -```bash -nvm install v6.9.5 -``` -then execute the following to see your versions: -```bash -# should be 6.9.5 -node -v -``` -AND -```bash -# should be 3.10.10 -npm -v -``` - -## Curl the source code to create network entities - -* Download the [cURL](https://curl.haxx.se/download.html) tool if not already installed. -* Determine a location on your local machine where you want to place the Fabric artifacts and application code. -```bash -mkdir -p /hackfest -cd /hackfest -``` -Next, execute the following command: -```bash -curl -L https://raw.githubusercontent.com/hyperledger/fabric/master/examples/sfhackfest/sfhackfest.tar.gz -o sfhackfest.tar.gz 2> /dev/null; tar -xvf sfhackfest.tar.gz -``` -This command pulls and extracts all of the necessary artifacts to set up your -network - Docker Compose script, channel generate/join script, crypto material -for identity attestation, etc. In the `/src/github.com/example_cc` directory you -will find the chaincode that will be deployed. - -Your directory should contain the following: -```bash -JDoe-mbp: JohnDoe$ pwd -/Users/JohnDoe -JDoe-mbp: JohnDoe$ ls -sfhackfest.tar.gz channel_test.sh src -ccenv docker-compose-gettingstarted.yml tmp -``` - -## Using Docker - -You do not need to manually pull any images. The images for - `fabric-peer`, -`fabric-orderer`, `fabric-ca`, and `cli` are specified in the .yml file and will -automatically download, extract, and run when you execute the `docker-compose` command. - -## Commands - -The channel commands are: - -* `create` - create and name a channel in the `orderer` and get back a genesis -block for the channel. The genesis block is named in accordance with the channel name. -* `join` - use the genesis block from the `create` command to issue a join -request to a peer. - -## Use Docker to spawn network entities & create/join a channel - -Ensure the hyperledger/fabric-ccenv image is tagged as latest: -```bash -docker-compose -f docker-compose-gettingstarted.yml build -``` -Create network entities, create channel, join peers to channel: -```bash -docker-compose -f docker-compose-gettingstarted.yml up -d -``` -Behind the scenes this started six containers (3 peers, a "solo" orderer, cli and CA) -in detached mode. A script - `channel_test.sh` - embedded within the -`docker-compose-gettingstarted.yml` issued the create channel and join channel -commands within the CLI container. In the end, you are left with a network and -a channel containing three peers - peer0, peer1, peer2. - -View your containers: -```bash -# if you have no other containers running, you will see six -docker ps -``` -Ensure the channel has been created and peers have successfully joined: -```bash -docker exec -it cli bash -``` -You should see the following in your terminal: -```bash -/opt/gopath/src/github.com/hyperledger/fabric/peer # -``` -To view results for channel creation/join: -```bash -more results.txt -``` -You're looking for: -```bash -SUCCESSFUL CHANNEL CREATION -SUCCESSFUL JOIN CHANNEL on PEER0 -SUCCESSFUL JOIN CHANNEL on PEER1 -SUCCESSFUL JOIN CHANNEL on PEER2 -``` - -To view genesis block: -```bash -more myc1.block -``` - -Exit the cli container: -```bash -exit -``` - -## Curl the application source code and SDK modules - -* Prior to issuing the command, make sure you are in the same working directory -where you curled the network code. AND make sure you have exited the cli container. -* Execute the following command: -```bash -curl -OOOOOO https://raw.githubusercontent.com/hyperledger/fabric-sdk-node/v1.0-alpha/examples/balance-transfer/{config.json,deploy.js,helper.js,invoke.js,query.js,package.json} -``` - -This command pulls the javascript code for issuing your deploy, invoke and query calls. -It also retrieves dependencies for the node SDK modules. - -* Install the node modules: -```bash -# You may be prompted for your root password at one or more times during this process. -npm install -``` -You now have all of the necessary prerequisites and Fabric artifacts. diff --git a/docs/asset_trouble.md b/docs/asset_trouble.md deleted file mode 100644 index adc921ad9d8..00000000000 --- a/docs/asset_trouble.md +++ /dev/null @@ -1,124 +0,0 @@ -## Troubleshooting - -If you have existing containers running, you may receive an error indicating that a port is -already occupied. If this occurs, you will need to kill the container that is using said port. - -If a file cannot be located, make sure your curl commands executed successfully and make -sure you are in the directory where you pulled the source code. - -If you are receiving timeout or GRPC communication errors, make sure you have the -correct version of Docker installed - v1.13.0. Then try restarting your failing -docker process. For example: -```bash -docker stop peer0 -``` -Then: -```bash -docker start peer0 -``` - -Another approach to GRPC and DNS errors (peer failing to resolve with orderer and vice -versa) is to hardcode the IP addresses for each. You will know if there is a DNS -issue, because a `more results.txt` command within the cli container will display -something similar to: -```bash -ERROR CREATING CHANNEL -PEER0 ERROR JOINING CHANNEL -``` - -Issue a `docker inspect ` to ascertain the IP address. For example: -```bash -docker inspect peer0 | grep IPAddress -``` -AND -```bash -docker inspect orderer | grep IPAddress -``` -Take these values and hard code them into your cli commands. For example: -```bash -CORE_PEER_COMMITTER_LEDGER_ORDERER=172.21.0.2:7050 peer channel create -c myc1 -``` -AND THEN -```bash -CORE_PEER_COMMITTER_LEDGER_ORDERER= CORE_PEER_ADDRESS= peer channel join -b myc1.block -``` - -If you are seeing errors while using the node SDK, make sure you have the correct versions -of node.js and npm installed on your machine. You want node v6.9.5 and npm v3.10.10. - -If you ran through the automated channel create/join process (i.e. did not comment out -`channel_test.sh` in the `docker-compose-gettingstarted.yml`), then channel - `myc1` - and -genesis block - `myc1.block` - have already been created and exist on your machine. -As a result, if you proceed to execute the manual steps in your cli container: -``` -CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc1 -``` -Then you will run into an error similar to: -``` - UTC [msp] Sign -> DEBU 064 Sign: digest: 5ABA6805B3CDBAF16C6D0DCD6DC439F92793D55C82DB130206E35791BCF18E5F -Error: Got unexpected status: BAD_REQUEST -Usage: - peer channel create [flags] -``` -This occurs because you are attempting to create a channel named `myc1`, and this channel -already exists! There are two options. Try issuing the peer channel create command -with a different channel name - `myc2`. For example: -``` -CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc2 -``` -Then join: -``` -CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc2.block -``` - -If you do choose to create a new channel, and want to run deploy/invoke/query with -the node.js programs, you also need to edit the "channelID" parameter in the -`config.json` file to match the new channel's name. For example: -``` -{ - "chainName":"fabric-client1", - "chaincodeID":"mycc", - "channelID":"myc2", - "goPath":"../../test/fixtures", - "chaincodePath":"github.com/example_cc", -``` - -OR, if you want your channel called - `myc1` -, remove your docker containers and -then follow the same commands in the __Manually create and join peers to a new channel__ -topic. - -## Clean up - -Shut down your containers: -```bash -docker-compose -f docker-compose-gettingstarted.yml down -``` - -## Helpful Docker tips - -Remove a specific docker container: -```bash -docker rm -``` -Force removal: -```bash -docker rm -f -``` -Remove all docker containers: -```bash -docker rm -f $(docker ps -aq) -``` -This will merely kill docker containers (i.e. stop the process). You will not lose any images. - -Remove an image: -```bash -docker rmi -``` -Forcibly remove: -```bash -docker rmi -f -``` -Remove all images: -```bash -docker rmi -f $(docker images -q) -``` diff --git a/docs/auction.md b/docs/auction.md deleted file mode 100644 index 1c743ab2f20..00000000000 --- a/docs/auction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Art Auction - -[WIP] -...coming soon - -Shows the provenance, attestation, and ownership of a piece of artwork and the -ensuing interaction of the various stakeholders. Not yet stable with v1 codebase. - -Learn more about the components [here](https://github.com/ITPeople-Blockchain/auction) - -Learn more about the client-side application [here](https://github.com/ITPeople-Blockchain/auction-app) diff --git a/docs/biz/usecases.md b/docs/biz/usecases.md deleted file mode 100644 index 78260a6b0c6..00000000000 --- a/docs/biz/usecases.md +++ /dev/null @@ -1,144 +0,0 @@ -# Canonical Use Cases - -  - -### B2B Contract - -Business contracts can be codified to allow two or more parties to automate contractual agreements in a trusted way. Although information on blockchain is naturally “public”, B2B contracts may require privacy control to protect sensitive business information from being disclosed to outside parties that also have access to the ledger. - - - - -While confidential agreements are a key business case, there are many scenarios where contracts can and should be easily discoverable by all parties on a ledger. For example, a ledger used to create offers (asks) seeking bids, by definition, requires access without restriction. This type of contract may need to be standardized so that bidders can easily find them, effectively creating an electronic trading platform with smart contracts (aka chaincode). - -#### Persona - -* Contract participant – Contract counter parties - -* Third party participant – A third party stakeholder guaranteeing the integrity of the contract. - -#### Key Components - -* Multi-sig contract activation - When a contract is first deployed by one of the counter parties, it will be in the pending activation state. To activate a contract, signatures from other counterparties and/or third party participants are required. - -* Multi-sig contract execution - Some contracts will require one of many signatures to execute. For example, in trade finance, a payment instruction can only be executed if either the recipient or an authorized third party (e.g. UPS) confirms the shipment of the good. - -* Discoverability - If a contract is a business offer seeking bids, it must be easily searchable. In addition, such contracts must have the built-in intelligence to evaluate, select and honor bids. - -* Atomicity of contract execution - Atomicity of the contract is needed to guarantee that asset transfers can only occur when payment is received (Delivery vs. Payment). If any step in the execution process fails, the entire transaction must be rolled back. - -* Contract to chain-code communication - Contracts must be able to communicate with chaincodes that are deployed on the same ledger. - -* Longer Duration contract - Timer is required to support B2B contracts that have long execution windows. - -* Reuseable contracts - Often-used contracts can be standardized for reuse. - -* Auditable contractual agreement - Any contract can be made auditable to third parties. - -* Contract life-cycle management - B2B contracts are unique and cannot always be standardized. An efficient contract management system is needed to enhance the scalability of the ledger network. - -* Validation access – Only nodes with validation rights are allowed to validate transactions of a B2B contract. - -* View access – B2B contracts may include confidential information, so only accounts with predefined access rights are allowed to view and interrogate them. - -  - - -### Manufacturing Supply Chain - -Final assemblers, such as automobile manufacturers, can create a supply chain network managed by its peers and suppliers so that a final assembler can better manage its suppliers and be more responsive to events that would require vehicle recalls (possibly triggered by faulty parts provided by a supplier). The blockchain fabric must provide a standard protocol to allow every participant on a supply chain network to input and track numbered parts that are produced and used on a specific vehicle. - -Why is this specific example an abstract use case? Because while all blockchain cases store immutable information, and some add the need for transfer of assets between parties, this case emphasizes the need to provide deep searchability backwards through as many as 5-10 transaction layers. This backwards search capability is the core of establishing provenance of any manufactured good that is made up of other component goods and supplies. - - - -#### Persona - -* Final Assembler – The business entity that performs the final assembly of a product. - -* Part supplier – Supplier of parts. Suppliers can also be assemblers by assembling parts that they receive from their sub-suppliers, and then sending their finished product to the final (root) assembler. - -#### Key Components - -* Payment upon delivery of goods - Integration with off-chain payment systems is required, so that payment instructions can be sent when parts are received. - -* Third party Audit - All supplied parts must be auditable by third parties. For example, regulators might need to track the total number of parts supplied by a specific supplier, for tax accounting purposes. - -* Obfuscation of shipments - Balances must be obfuscated so that no supplier can deduce the business activities of any other supplier. - -* Obfuscation of market size - Total balances must be obfuscated so that part suppliers cannot deduce their own market share to use as leverage when negotiating contractual terms. - -* Validation Access – Only nodes with validation rights are allowed to validate transactions (shipment of parts). - -* View access – Only accounts with view access rights are allowed to interrogate balances of shipped parts and available parts. - -  - - -### Asset Depository - -Assets such as financial securities must be able to be dematerialized on a blockchain network so that all stakeholders of an asset type will have direct access to that asset, allowing them to initiate trades and acquire information on an asset without going through layers of intermediaries. Trades should be settled in near real time and all stakeholders must be able to access asset information in near real time. A stakeholder should be able to add business rules on any given asset type, as one example of using automation logic to further reduce operating costs. - - -#### Persona - -* Investor – Beneficial and legal owner of an asset. - -* Issuer – Business entity that issued the asset which is now dematerialized on the ledger network. - -* Custodian – Hired by investors to manage their assets, and offer other value-add services on top of the assets being managed. - -* Securities Depository – Depository of dematerialized assets. - -#### Key Components - -* Asset to cash - Integration with off-chain payment systems is necessary so that issuers can make payments to and receive payments from investors. - -* Reference Rate - Some types of assets (such as floating rate notes) may have attributes linked to external data (such as reference rate), and such information must be fed into the ledger network. - -* Asset Timer - Many types of financial assets have predefined life spans and are required to make periodic payments to their owners, so a timer is required to automate the operation management of these assets. - -* Asset Auditor - Asset transactions must be made auditable to third parties. For example, regulators may want to audit transactions and movements of assets to measure market risks. - -* Obfuscation of account balances - Individual account balances must be obfuscated so that no one can deduce the exact amount that an investor owns. - -* Validation Access – Only nodes with validation rights are allowed to validate transactions that update the balances of an asset type (this could be restricted to CSD and/or the issuer). - -* View access – Only accounts with view access rights are allowed to interrogate the chaincode that defines an asset type. If an asset represents shares of publicly traded companies, then the view access right must be granted to every entity on the network. - -  - - -# Extended Use Cases - -The following extended use cases examine additional requirements and scenarios. - -### One Trade, One Contract - -From the time that a trade is captured by the front office until the trade is finally settled, only one contract that specifies the trade will be created and used by all participants. The middle office will enrich the same electronic contract submitted by the front office, and that same contract will then be used by counter parties to confirm and affirm the trade. Finally, securities depository will settle the trade by executing the trading instructions specified on the contract. When dealing with bulk trades, the original contract can be broken down into sub-contracts that are always linked to the original parent contract. - - - -  - -### Direct Communication - -Company A announces its intention to raise 2 Billion USD by way of rights issue. Because this is a voluntary action, Company A needs to ensure that complete details of the offer are sent to shareholders in real time, regardless of how many intermediaries are involved in the process (such as receiving/paying agents, CSD, ICSD, local/global custodian banks, asset management firms, etc). Once a shareholder has made a decision, that decision will also be processed and settled (including the new issuance of shares) in real time. If a shareholder sold its rights to a third party, the securities depository must be able to record the new shares under the name of their new rightful owner. - - - -  - -### Separation of Asset Ownership and Custodian’s Duties - -Assets should always be owned by their actual owners, and asset owners must be able to allow third-party professionals to manage their assets without having to pass legal ownership of assets to third parties (such as nominee or street name entities). If issuers need to send messages or payments to asset owners (for example, listed share holders), issuers send them directly to asset owners. Third-party asset managers and/or custodians can always buy, sell, and lend assets on behalf of their owners. Under this arrangement, asset custodians can focus on providing value-add services to shareowners, without worrying about asset ownership duties such as managing and redirecting payments from issuers to shareowners. - - - -  - -### Interoperability of Assets - -If an organization requires 20,000 units of asset B, but instead owns 10,000 units of asset A, it needs a way to exchange asset A for asset B. Though the current market might not offer enough liquidity to fulfill this trade quickly, there might be plenty of liquidity available between asset A and asset C, and also between asset C and asset B. Instead of settling for market limits on direct trading (A for B) in this case, a chain network connects buyers with "buried" sellers, finds the best match (which could be buried under several layers of assets), and executes the transaction. - - diff --git a/docs/blockchain.md b/docs/blockchain.md deleted file mode 100644 index 2f1515d5a79..00000000000 --- a/docs/blockchain.md +++ /dev/null @@ -1,3 +0,0 @@ -# Why blockchain? - -...coming soon diff --git a/docs/bootstrap.md b/docs/bootstrap.md deleted file mode 100644 index 9c62d74fe2a..00000000000 --- a/docs/bootstrap.md +++ /dev/null @@ -1,9 +0,0 @@ -# Starting a network - -[WIP] -...coming soon - -Intended to contain the recommended steps for generating prerequisite cryptographic -material and then bootstrapping an ordering service (i.e. overall network) with -participating organizations, ordering node certificates, load balancing, configuration, -policies, etc... diff --git a/docs/carlease.md b/docs/carlease.md deleted file mode 100644 index 4146668448b..00000000000 --- a/docs/carlease.md +++ /dev/null @@ -1,9 +0,0 @@ -# Car Lease - -[WIP] -...coming soon - -Uses the blockchain to record the lifecycle of a vehicle from materials provenance, -manufacture, buyer, all the way to scrap yard. Not yet stable with v1 codebase. - -Learn more about the application and underlying chaincode [here](https://github.com/IBM-Blockchain/car-lease-demo) diff --git a/docs/chaincode.md b/docs/chaincode.md deleted file mode 100644 index 5b1b69cee6b..00000000000 --- a/docs/chaincode.md +++ /dev/null @@ -1,343 +0,0 @@ -# What is chaincode? - -[WIP] - -coming soon ... end-to-end examples of chaincode demonstrating the available -APIs. - -Chaincode is a piece of code that is written in one of the supported languages -such as Go or Java. It is installed and instantiated through an SDK or CLI -onto a network of Hyperledger Fabric peer nodes, enabling interaction with that -network's shared ledger. - -There are three aspects to chaincode development: -* The interfaces that the chaincode should implement -* APIs the chaincode can use to interact with the Fabric -* A chaincode response - -## Chaincode interfaces - -A chaincode implements the Chaincode Interface that supports two methods: -* `Init` -* `Invoke` - -#### Init() - -Init is called when you first deploy your chaincode. As the name implies, this -function is used to do any initialization your chaincode needs. - -#### Invoke() - -Invoke is called when you want to call chaincode functions to do real work (i.e. read -and write to the ledger). Invocations are captured as transactions, which get -grouped into blocks on the chain. When you need to update or query the ledger, -you do so by invoking your chaincode. - -## Dependencies - -The import statement lists a few dependencies for the chaincode to compile successfully. -* fmt – contains Println for debugging/logging. -* errors – standard go error format. -* [shim](https://github.com/hyperledger/fabric/tree/master/core/chaincode/shim) – -contains the definitions for the chaincode interface and the chaincode stub, -which you are required to interact with the ledger. - -## Chaincode APIs - -When the Init or Invoke function of a chaincode is called, the fabric passes the -`stub shim.ChaincodeStubInterface` parameter and the chaincode returns a `pb.Response`. -This stub can be used to call APIs to access to the ledger services, transaction -context, or to invoke other chaincodes. - -The current APIs are defined in the shim package, and can be generated with the -following command: -```bash -godoc github.com/hyperledger/fabric/core/chaincode/shim -``` -However, it also includes functions from chaincode.pb.go (protobuffer functions) -that are not intended as public APIs. The best practice is to look at the function -definitions in chaincode.go and and the -[examples](https://github.com/hyperledger/fabric/tree/master/examples/chaincode/go) -directory. - -## Response - -The chaincode response comes in the form of a protobuffer. - -```go -message Response { - - // A status code that should follow the HTTP status codes. - int32 status = 1; - - // A message associated with the response code. - string message = 2; - - // A payload that can be used to include metadata with this response. - bytes payload = 3; - -} -``` -The chaincode will also return events. Message events and chaincode events. -```go -messageEvent { - - oneof Event { - - //Register consumer sent event - Register register = 1; - - //producer events common. - Block block = 2; - ChaincodeEvent chaincodeEvent = 3; - Rejection rejection = 4; - - //Unregister consumer sent events - Unregister unregister = 5; - - } - -} -``` - -```go -messageChaincodeEvent { - - string chaincodeID = 1; - string txID = 2; - string eventName = 3; - bytes payload = 4; - -} -``` - -Once developed and deployed, there are two ways to interact with the chaincode - -through an SDK or the CLI. The steps for CLI are described below. For SDK interaction, -refer to the [balance transfer](https://github.com/hyperledger/fabric-sdk-node/tree/master/examples/balance-transfer) -samples. __Note__: This SDK interaction is covered in the __Getting Started__ section. - -## Command Line Interfaces - -To view the currently available CLI commands, execute the following: -```bash -# this assumes that you have correctly set the GOPATH variable and cloned the Fabric codebase into that path -cd /opt/gopath/src/github.com/hyperledger/fabric -build /bin/peer -``` -You will see output similar to the example below. (__NOTE__: rootcommand below is -hardcoded in main.go. Currently, the build will create a _peer_ executable file). -```bash -Usage: - peer [flags] - peer [command] - - Available Commands: - version Print fabric peer version. - node node specific commands. - channel channel specific commands. - chaincode chaincode specific commands. - logging logging specific commands - - - Flags: - --logging-level string: Default logging level and overrides, see core.yaml for full syntax - --test.coverprofile string: Done (default “coverage.cov) - -v, --version: Display current version of fabric peer server - Use "peer [command] --help" for more information about a command. -``` -The `peer` command supports several subcommands and flags, as shown above. To -facilitate its use in scripted applications, the `peer` command always produces a -non-zero return code in the event of command failure. Upon success, many of the -subcommands produce a result on stdout as shown in the table below: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -Command - - - -stdout result in the event of success - -
- -version - - - -String form of peer.version defined in core.yaml - -
- -node start - - - -N/A - -
- -node status - - - -String form of StatusCode - -
- -node stop - - - -String form of StatusCode - -
- -chaincode deploy - - - -The chaincode container name (hash) required for subsequent chaincode invoke and chaincode query commands - -
- -chaincode invoke - - - -The transaction ID (UUID) - -
- -chaincode query - - - -By default, the query result is formatted as a printable - -
- -channel create - - - -Create a chain - -
- -channel join - - - -Adds a peer to the chain - -
- -
--peer-defaultchain=true
- -
- - Allows users to continue to work with the default TEST_CHAINID string. Command line options support writing this value as raw bytes (-r, –raw) or formatted as the hexadecimal representation of the raw bytes (-x, –hex). If the query response is empty then nothing is output. - -
- -## Deploy a chaincode - -[WIP] - the CLI commands need to be refactored based on the new deployment model. -Channel Create and Channel Join will remain the same. diff --git a/docs/channel-setup.md b/docs/channel-setup.md deleted file mode 100644 index ed78ce55c11..00000000000 --- a/docs/channel-setup.md +++ /dev/null @@ -1,137 +0,0 @@ -# Multichannel Setup - -This document describe the CLI for creating channels and directing peers to join channels. The CLI uses channel APIs that are also available in the SDK. - -The channel commands are -* create - create a channel in the `orderer` and get back a genesis block for the channel -* join - use genesis block from create command to issue a join request to a Peer - -``` -NOTE - The main JIRA items for the work are - https://jira.hyperledger.org/browse/FAB-1022 - https://jira.hyperledger.org/browse/FAB-1547 - -The commands are work in progress. In particular, there will be more configuration parameters to the commands. Some relevant JIRA items - https://jira.hyperledger.org/browse/FAB-1642 - https://jira.hyperledger.org/browse/FAB-1639 - https://jira.hyperledger.org/browse/FAB-1580 -``` - -## Using docker -Pull the latest images from https://github.com/rameshthoomu/ - -### Create a channel -Copy [`docker-compose-channel.yml`](docker-compose-channel.yml) to your current directory. - -_Bring up peer and orderer_ -``` -cd docs -docker-compose -f docker-compose-channel.yml up -``` - -`docker ps` should show containers `orderer` and `peer0` running. - -_Ask orderer to create a channel_ -Start the CLI container. -``` -docker-compose -f docker-compose-channel.yml run cli -``` -In the above shell execute the create command -``` -CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:5005 peer channel create -c myc1 -``` - -This will create a channel genesis block file `myc1.block` to issue join commands with. - - -### Join a channel -Execute the join command to peer0 in the CLI container. - -``` -CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:5005 CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc1.block -``` - -### Use the channel to deploy and invoke chaincodes -Run the deploy command -``` -CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:5005 peer chaincode deploy -C myc1 -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a","100","b","200"]}' -``` - -Run the invoke command -``` -CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:5005 peer chaincode invoke -C myc1 -n mycc -c '{"Args":["invoke","a","b","10"]}' -``` - -Run the query command -``` -CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:5005 peer chaincode query -C myc1 -n mycc -c '{"Args":["query","a"]}' -``` - -## Using Vagrant -Build the executables with `make orderer` and `make peer` commands. Switch to build/bin directory. - -### Create a channel -_Vagrant window 1 - start orderer_ - -``` -ORDERER_GENERAL_LOGLEVEL=debug ./orderer -``` -_Vagrant window 2 - ask orderer to create a chain_ - -``` -peer channel create -c myc1 -``` - -On successful creation, a genesis block myc1.block is saved in build/bin directory. - -### Join a channel -_Vagrant window 3 - start the peer in a "chainless" mode_ - -``` -#NOTE - clear the environment with rm -rf /var/hyperledger/* after updating fabric to get channel support. - -peer node start --peer-defaultchain=false -``` - -``` -"--peer-defaultchain=true" is the default. It allow users continue to work with the default "testchainid" without having to join a chain. - -"--peer-defaultchain=false" starts the peer with only the channels that were joined by the peer. If the peer never joined a channel it would start up without any channels. In particular, it does not have the default "testchainid" support. - -To join channels, a peer MUST be started with the "--peer-defaultchain=false" option. -``` -_Vagrant window 2 - peer to join a channel_ - -``` -peer channel join -b myc1.block -``` - -where myc1.block is the block that was received from the `orderer` from the create channel command. - -At this point we can issue transactions. -### Use the channel to deploy and invoke chaincodes -_Vagrant window 2 - deploy a chaincode to myc1_ - -``` -peer chaincode deploy -C myc1 -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a","100","b","200"]}' -``` - -Note the use of `-C myc1` to target the chaincode deployment against the `myc1` channel. - -Wait for the deploy to get committed (e.g., by default the `solo orderer` can take upto 10 seconds to sends a batch of transactions to be committed.) - -_Vagrant window 2 - invoke chaincode_ - -``` -peer chaincode invoke -C myc1 -n mycc -c '{"Args":["invoke","a","b","10"]}' -``` - -Wait for upto 10 seconds for the invoke to get committed. - -_Vagrant window 2 - query chaincode_ - -``` -peer chaincode query -C myc1 -n mycc -c '{"Args":["query","a"]}' -``` - -To reset, clear out the `fileSystemPath` directory (defined in core.yaml) and myc1.block. diff --git a/docs/channels.md b/docs/channels.md deleted file mode 100644 index b61e3e8847a..00000000000 --- a/docs/channels.md +++ /dev/null @@ -1,3 +0,0 @@ -## Channels - -...coming soon diff --git a/docs/committer.md b/docs/committer.md deleted file mode 100644 index acd713a9fc9..00000000000 --- a/docs/committer.md +++ /dev/null @@ -1,7 +0,0 @@ -# Committing Peer - -[WIP] -...coming soon - -This topic will explain the peer's runtime and role as a committer for transactions -on a channel. In the meantime, refer to the [high-level data flow](https://jira.hyperledger.org/browse/FAB-37). diff --git a/docs/components.md b/docs/components.md deleted file mode 100644 index e8b6c0ac4f3..00000000000 --- a/docs/components.md +++ /dev/null @@ -1,7 +0,0 @@ -# Components - -[WIP] -...coming soon - -This topic will contain a diagram explaining the various components of a blockchain -network and their corresponding roles. diff --git a/docs/configtxgen.md b/docs/configtxgen.md deleted file mode 100644 index 71aa4f40ed4..00000000000 --- a/docs/configtxgen.md +++ /dev/null @@ -1,40 +0,0 @@ -# Configuring using the configtxgen tool - -This document describe the usage for the `configtxgen` utility for manipulating fabric channel configuration. - -For now, the tool is primarily focused on generating the genesis block for bootstrapping the orderer, but it is intended to be enhanced in the future for generating new channel configurations as well as reconfiguring existing channels. - -## Building the tool - -Building the tool is as simple as `make configtxgen`. This will create a `configtxgen` binary at `build/bin/configtxgen` which is included in the Vagrant development environment path by default. - -## Configuration Profiles - -The configuration parameters supplied to the `configtxgen` tool are primarily provided by the `configtx.yaml` file. This file is located at `fabric/common/configtx/tool/configtx.yaml` in the fabric.git repository. - -This configuration file is split primarily into three pieces. - -1. The `Profiles` section. By default, this section includes some sample configurations which can be used for development or testing scenarios, and refer to crypto material present in the fabric.git tree. These profiles can make a good starting point for construction a real deployment profile. The `configtxgen` tool allows you to specify the profile it is operating under by passing the `-profile` flag. Profiles may explicitly declare all configuration, but usually inherit configuration from the defaults in (3) below. -2. The `Organizations` section. By default, this section includes a single reference to the sampleconfig MSP definition. For production deployments, the sample organization should be removed, and the MSP definitions of the network members should be referenced and defined instead. Each element in the `Organizations` section should be tagged with an anchor label such as `&orgName` which will allow the definition to be referenced in the `Profiles` sections. -3. The default sections. There are default sections for `Orderer` and `Application` configuration, these include attributes like `BatchTimeout` and are generally used as the base inherited values for the profiles. - -This configuration file may be edited, or, individual properties may be overridden by setting environment variables, such as `CONFIGTX_ORDERER_ORDERERTYPE=kafka`. Note that the `Profiles` element and profile name do not need to be specified. - -## Bootstrapping the orderer -After creating a configuration profile as desired, simply invoke -``` -configtxgen -profile -outputBlock ; -``` -This will produce a `genesis.block` file in the current directory. If you wish to skip writing the file simply do not pass `outputBlock` - -Then, to utilize this genesis block, before starting the orderer, simply specify `ORDERER_GENERAL_GENESISMETHOD=file` and `ORDERER_GENERAL_GENESISFILE=$PWD/genesis.block` or modify the `orderer.yaml` file to encode these values. - -## Creating a channel - -The tool can also output a channel creation tx by executing - -``` -configtxgen -profile -outputCreateChannelTx -``` - -This will output a marshaled `Envelope` message which may be sent to broadcast to create a channel. diff --git a/docs/consensus.md b/docs/consensus.md deleted file mode 100644 index 8aee49ecece..00000000000 --- a/docs/consensus.md +++ /dev/null @@ -1,12 +0,0 @@ -# Consensus - -[WIP] - -Not to be conflated with the ordering process. Consensus in v1 architecture is a -broader term overarching the entire transactional flow, which -serves to generate an agreement on the order and to confirm the correctness of -the set of transactions constituting a block. - -It is achieved as a byproduct of the various steps and verifications that occur during -a transaction's lifecycle from proposal to commitment. More information on the -high-level data flows is available [here](https://jira.hyperledger.org/browse/FAB-37). diff --git a/docs/data_model.md b/docs/data_model.md deleted file mode 100644 index c0e8555fcb3..00000000000 --- a/docs/data_model.md +++ /dev/null @@ -1,36 +0,0 @@ -# Transaction Model - -[WIP] - -The Fabric transaction model is a complete, self-encapsulated immutable record -of the state transition on the ledger of the participating parties. It contains -a chaincode function call, versioned inputs (referred to as the read set), and -outputs (referred to as the write set). The read-write-sets are the actual states -making up the multi-version concurrency control, which serves to grant an -appropriate version to each read request. Transactions issuing write requests -which might destroy database integrity are aborted at the "validation" phase to -counter against malicious threats such as double-spending. - -Transactions are appended in order of processing to an append-only log with -cryptographic links to prevent any modification to the records. There is no -limit on the log size except available physical storage space. - -States are data variables of any type represented by binary or text (JSON) format; -they are scoped and manipulated by chaincodes running on a ledger. A chaincode -function reads and writes states (read-write set) in the context of a transaction -proposal, which is endorsed by the counter-parties specified for the chaincode. -The endorsed proposal is submitted to the network as a transaction for ordering, -validation, and then committal to the ledger within a block. - -Before committal, peers will make sure that the transaction has been both adequately, -and properly endorsed (i.e. the correct allotment of the specified peers have -signed the proposal, and these signatures have been authenticated) - this is -referred to as validation. Secondly, a versioning check will occur to ensure -that the key value pairs affected by this transaction have not been altered -since simulation of the proposal. Or put another way, the world state for this -chaincode still mirrors the world state used for the inputs. If these conditions -are met, then this transaction is written to the ledger and the versions of the -keys, along with their new values, are updated in the world state. - -See the [Read Write Set](readwrite.md) topic for a deeper dive on transaction -structure, MVCC and the state DB. diff --git a/docs/debug.md b/docs/debug.md deleted file mode 100644 index 0ee777b477d..00000000000 --- a/docs/debug.md +++ /dev/null @@ -1,4 +0,0 @@ -# Debugging & Logging - -[WIP] -...coming soon diff --git a/docs/dev-setup/build.md b/docs/dev-setup/build.md deleted file mode 100644 index 8e59888248e..00000000000 --- a/docs/dev-setup/build.md +++ /dev/null @@ -1,103 +0,0 @@ -## Building the fabric - -The following instructions assume that you have already set up your [development environment](devenv.md). - -To build the Fabric: - -``` -cd $GOPATH/src/github.com/hyperledger/fabric -make dist-clean all -``` - -### Running the unit tests - -Use the following sequence to run all unit tests - -``` -cd $GOPATH/src/github.com/hyperledger/fabric -make unit-test -``` - -To run a specific test use the `-run RE` flag where RE is a regular expression that matches the test case name. To run tests with verbose output use the `-v` flag. For example, to run the `TestGetFoo` test case, change to the directory containing the `foo_test.go` and call/excecute - -``` -go test -v -run=TestGetFoo -``` - -### Running Node.js Unit Tests - -You must also run the Node.js unit tests to insure that the Node.js client SDK is not broken by your changes. To run the Node.js unit tests, follow the instructions [here](https://github.com/hyperledger/fabric-sdk-node/README.md). - -### Running Behave BDD Tests - -**Note:** currently, the behave tests must be run from within in the Vagrant -environment. See the devenv setup instructions if you have not already set up -your [Vagrant environment](devenv.md#Boostrapping-the-VM-using-Vagrant). - -[Behave](http://pythonhosted.org/behave/) tests will setup networks of peers with different security and consensus configurations and verify that transactions run properly. To run these tests - -``` -cd $GOPATH/src/github.com/hyperledger/fabric -make behave -``` -Some of the Behave tests run inside Docker containers. If a test fails and you want to have the logs from the Docker containers, run the tests with this option: - -``` -cd $GOPATH/src/github.com/hyperledger/fabric/bddtests -behave -D logs=Y -``` - -## Building outside of Vagrant -It is possible to build the project and run peers outside of Vagrant. Generally -speaking, one has to 'translate' the vagrant [setup file](https://github.com/hyperledger/fabric/blob/master/devenv/setup.sh) -to the platform of your choice. - -### Building on Z -To make building on Z easier and faster, [this script](https://github.com/hyperledger/fabric/tree/master/devenv/setupRHELonZ.sh) is provided (which is similar to the [setup file](https://github.com/hyperledger/fabric/blob/master/devenv/setup.sh) provided for vagrant). This script has been tested only on RHEL 7.2 and has some assumptions one might want to re-visit (firewall settings, development as root user, etc.). It is however sufficient for development in a personally-assigned VM instance. - -To get started, from a freshly installed OS: -``` -sudo su -yum install git -mkdir -p $HOME/git/src/github.com/hyperledger -cd $HOME/git/src/github.com/hyperledger -git clone http://gerrit.hyperledger.org/r/fabric -source fabric/devenv/setupRHELonZ.sh -``` -From this point, you can proceed as described above for the Vagrant development environment. - -``` -cd $GOPATH/src/github.com/hyperledger/fabric -make peer unit-test behave -``` - -### Building on Power Platform - -Development and build on Power (ppc64le) systems is done outside of vagrant as outlined [here](#building-outside-of-vagrant-). For ease of setting up the dev environment on Ubuntu, invoke [this script](https://github.com/hyperledger/fabric/tree/master/devenv/setupUbuntuOnPPC64le.sh) as root. This script has been validated on Ubuntu 16.04 and assumes certain things (like, development system has OS repositories in place, firewall setting etc) and in general can be improvised further. - -To get started on Power server installed with Ubuntu, first ensure you have properly setup your Host's [GOPATH environment variable](https://github.com/golang/go/wiki/GOPATH). Then, execute the following commands to build the fabric code: - -``` -mkdir -p $GOPATH/src/github.com/hyperledger -cd $GOPATH/src/github.com/hyperledger -git clone http://gerrit.hyperledger.org/r/fabric -sudo ./fabric/devenv/setupUbuntuOnPPC64le.sh -cd $GOPATH/src/github.com/hyperledger/fabric -make dist-clean all -``` - -## Configuration - -Configuration utilizes the [viper](https://github.com/spf13/viper) and [cobra](https://github.com/spf13/cobra) libraries. - -There is a **core.yaml** file that contains the configuration for the peer process. Many of the configuration settings can be overridden on the command line by setting ENV variables that match the configuration setting, but by prefixing with *'CORE_'*. For example, logging level manipulation through the environment is shown below: - - CORE_PEER_LOGGING_LEVEL=CRITICAL peer - -## Logging - -Logging utilizes the [go-logging](https://github.com/op/go-logging) library. - -The available log levels in order of increasing verbosity are: *CRITICAL | ERROR | WARNING | NOTICE | INFO | DEBUG* - -See [specific logging control](https://github.com/hyperledger/fabric/blob/master/docs/Setup/logging-control.md) instructions when running the peer process. diff --git a/docs/dev-setup/devenv.md b/docs/dev-setup/devenv.md deleted file mode 100644 index 82bcea834de..00000000000 --- a/docs/dev-setup/devenv.md +++ /dev/null @@ -1,146 +0,0 @@ -## Setting up the development environment - -### Overview - -Through the v0.6 release, the development environment utilized Vagrant running -an Ubuntu image, which in turn launched Docker containers as a means of -ensuring a consistent experience for developers who might be working with -varying platforms, such as MacOSX, Windows, Linux, or whatever. Advances in -Docker have enabled native support on the most popular development platforms: -MacOSX and Windows. Hence, we have reworked our build to take full advantage -of these advances. While we still maintain a Vagrant based approach that can -be used for older versions of MacOSX and Windows that Docker does not support, -we strongly encourage that the non-Vagrant development setup be used. - -Note that while the Vagrant-based development setup could not be used in a -cloud context, the Docker-based build does support cloud platforms such as AWS, -Azure, Google and IBM to name a few. Please follow the instructions for Ubuntu -builds, below. - -### Prerequisites -* [Git client](https://git-scm.com/downloads) -* [Go](https://golang.org/) - 1.7 or later (for releases before v1.0, 1.6 or later) -* For MacOSX, [Xcode](https://itunes.apple.com/us/app/xcode/id497799835?mt=12) -must be installed -* [Docker](https://www.docker.com/products/overview) - 1.12 or later -* [Pip](https://pip.pypa.io/en/stable/installing/) -* (MacOSX) you may need to install gnutar, as MacOSX comes with bsdtar as the -default, but the build uses some gnutar flags. You can use Homebrew to install -it as follows: - -``` -brew install gnu-tar --with-default-names -``` - -* (only if using Vagrant) - [Vagrant](https://www.vagrantup.com/) - 1.7.4 or -later -* (only if using Vagrant) - [VirtualBox](https://www.virtualbox.org/) - 5.0 or -later -* BIOS Enabled Virtualization - Varies based on hardware - -- Note: The BIOS Enabled Virtualization may be within the CPU or Security -settings of the BIOS - -### `pip`, `behave` and `docker-compose` - -``` -pip install --upgrade pip -pip install behave nose docker-compose -pip install -I flask==0.10.1 python-dateutil==2.2 pytz==2014.3 pyyaml==3.10 couchdb==1.0 flask-cors==2.0.1 requests==2.4.3 pyOpenSSL==16.2.0 sha3==0.2.1 -``` - -### Steps - -#### Set your GOPATH -Make sure you have properly setup your Host's [GOPATH environment variable](https://github.com/golang/go/wiki/GOPATH). This allows for both -building within the Host and the VM. - -#### Note to Windows users - -If you are running Windows, before running any `git clone` commands, run the -following command. -``` -git config --get core.autocrlf -``` -If `core.autocrlf` is set to `true`, you must set it to `false` by running -``` -git config --global core.autocrlf false -``` -If you continue with `core.autocrlf` set to `true`, the `vagrant up` command -will fail with the error: - -`./setup.sh: /bin/bash^M: bad interpreter: No such file or directory` - -#### Cloning the Fabric project - -Since the Fabric project is a `Go` project, you'll need to clone the Fabric -repo to your $GOPATH/src directory. If your $GOPATH has multiple path -components, then you will want to use the first one. There's a little bit of -setup needed: - -``` -cd $GOPATH/src -mkdir -p github.com/hyperledger -cd github.com/hyperledger -``` - -Recall that we are using `Gerrit` for source control, which has its own internal -git repositories. Hence, we will need to clone from [Gerrit](../Gerrit/gerrit.md#Working-with-a-local-clone-of-the-repository). For -brevity, the command is as follows: -``` -git clone ssh://LFID@gerrit.hyperledger.org:29418/fabric && scp -p -P 29418 LFID@gerrit.hyperledger.org:hooks/commit-msg fabric/.git/hooks/ -``` -**Note:** Of course, you would want to replace `LFID` with your own -[Linux Foundation ID](../Gerrit/lf-account.md). - -#### Boostrapping the VM using Vagrant - -If you are planning on using the Vagrant developer environment, the following -steps apply. **Again, we recommend against its use except for developers that -are limited to older versions of MacOSX and Windows that are not supported by -Docker for Mac or Windows.** - -``` -cd $GOPATH/src/github.com/hyperledger/fabric/devenv -vagrant up -``` - -Go get coffee... this will take a few minutes. Once complete, you should be able -to `ssh` into the Vagrant VM just created. - -``` -vagrant ssh -``` - -Once inside the VM, you can find the peer project under -`$GOPATH/src/github.com/hyperledger/fabric`. It is also mounted as -`/hyperledger`. - -### Building the fabric - -Once you have all the dependencies installed, and have cloned the repository, -you can proceed to [build and test](build.md) the fabric. - -### Notes - -**NOTE:** Any time you change any of the files in your local fabric directory -(under `$GOPATH/src/github.com/hyperledger/fabric`), the update will be -instantly available within the VM fabric directory. - -**NOTE:** If you intend to run the development environment behind an HTTP Proxy, -you need to configure the guest so that the provisioning process may complete. -You can achieve this via the *vagrant-proxyconf* plugin. Install with -`vagrant plugin install vagrant-proxyconf` and then set the VAGRANT_HTTP_PROXY -and VAGRANT_HTTPS_PROXY environment variables *before* you execute `vagrant up`. -More details are available here: https://github.com/tmatilai/vagrant-proxyconf/ - -**NOTE:** The first time you run this command it may take quite a while to -complete (it could take 30 minutes or more depending on your environment) and -at times it may look like it's not doing anything. As long you don't get any -error messages just leave it alone, it's all good, it's just cranking. - -**NOTE to Windows 10 Users:** There is a known problem with vagrant on Windows -10 (see [mitchellh/vagrant#6754](https://github.com/mitchellh/vagrant/issues/6754)). -If the `vagrant up` command fails it may be because you do not have the Microsoft -Visual C++ Redistributable package installed. You can download the missing package at -the following address: http://www.microsoft.com/en-us/download/details.aspx?id=8328 diff --git a/docs/dockercompose.md b/docs/dockercompose.md deleted file mode 100644 index 8a92ed31ae7..00000000000 --- a/docs/dockercompose.md +++ /dev/null @@ -1,9 +0,0 @@ -# Docker Compose - -[WIP] -...coming soon - -This section will explain how to use Docker Compose to stand up the necessary -components for a blockchain network. The various environment variables -correlated to each image will be explained, and different configurations will -be outlined. diff --git a/docs/endorsement-policies.md b/docs/endorsement-policies.md deleted file mode 100644 index 1eecf359c12..00000000000 --- a/docs/endorsement-policies.md +++ /dev/null @@ -1,83 +0,0 @@ -# Endorsement policies - -Endorsement policies are used to instruct a peer on how to decide whether a transaction -is properly endorsed. When a peer receives a transaction, it invokes the VSCC (Validation -System Chaincode) associated with the transaction's Chaincode as part of the -transaction validation flow to determine the validity of the transaction. Recall that a -transaction contains one or more endorsement from as many endorsing peers. VSCC is tasked -to make the following determinations: - - all endorsements are valid (i.e. they are valid signatures from valid certificates over the expected message) - - there is an appropriate number of endorsements - - endorsements come from the expected source(s) - -Endorsement policies are a way of specifying the second and third points. - -## Endorsement policy design - -Endorsement policies have two main components: - - a principal - - a threshold gate - -A principal `P` identifies the entity whose signature is expected. - -A threshold gate `T` takes two inputs: an integer `t` (the threshold) and a list of `n` -principals or gates; this gate essentially captures the expectation that out of those -`n` principals or gates, `t` are requested to be satisfied. - -For example: - - `T(2, 'A', 'B', 'C')` requests a signature from any 2 principals out of 'A', 'B' or 'C'; - - `T(1, 'A', T(2, 'B', 'C'))` requests either one signature from principal `A` or 1 signature - from `B` and `C` each. - -## Endorsement policy syntax in the CLI - -In the CLI, a simple language is used to express policies in terms of boolean expressions -over principals. - -A principal is described in terms of the MSP that is tasked to validate the identity of -the signer and of the role that the signer has within that MSP. Currently, two roles are -supported: **member** and **admin**. Principals are described as `MSP`.`ROLE`, where `MSP` -is the MSP ID that is required, and `ROLE` is either one of the two strings `member` and -`admin`. Examples of valid principals are `'Org0.admin'` (any administrator of the `Org0` -MSP) or `'Org1.member'` (any member of the `Org1` MSP). - -The syntax of the language is: - -`EXPR(E[, E...])` - -where `EXPR` is either `AND` or `OR`, representing the two boolean expressions and `E` is -either a principal (with the syntax described above) or another nested call to `EXPR`. - -For example: - - `AND('Org1.member', 'Org2.member', 'Org3.member')` requests 1 signature from each of the three principals - - `OR('Org1.member', 'Org2.member')` requests 1 signature from either one of the two principals - - `OR('Org1.member', AND('Org2.member', 'Org3.member'))` requests either one signature from - a member of the `Org1` MSP or 1 signature from a member of the `Org2` MSP and 1 signature - from a member of the `Org3` MSP. - -## Specifying endorsement policies for a chaincode - -Using this language, a chaincode deployer can request that the endorsements for a chaincode be -validated against the specified policy. NOTE - the default policy requires one signature -from a member of the `DEFAULT` MSP). This is used if a policy is not specified in the CLI. - -The policy can be specified at deploy time using the `-P` switch, followed by the policy. - -For example: - -``` -peer chaincode deploy -C testchainid -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a","100","b","200"]}' -P "AND('Org1.member', 'Org2.member')" -``` - -This command deploys chaincode `mycc` on chain `testchainid` with the policy `AND('Org1.member', 'Org2.member')`. - -## Future enhancements - -In this section we list future enhancements for endorsement policies: - - alongside the existing way of identifying principals by their relationship with an MSP, we plan - to identify principals in terms of the _Organization Unit (OU)_ expected in their certificates; - this is useful to express policies where we request signatures from any identity displaying a - valid certificate with an OU matching the one requested in the definition of the principal. - - instead of the syntax `AND(., .)` we plan to move to a more intuitive syntax `. AND .` - - we plan to expose generalized threshold gates in the language as well alongside `AND` (which is - the special `n`-out-of-`n` gate) and `OR` (which is the special `1`-out-of-`n` gate) \ No newline at end of file diff --git a/docs/endorser.md b/docs/endorser.md deleted file mode 100644 index a03ab3e9445..00000000000 --- a/docs/endorser.md +++ /dev/null @@ -1,7 +0,0 @@ -# Endorsing Peer - -[WIP] -...coming soon - -This topic will explain the peer's runtime and role as an endorser for a certain -piece of chaincode. In the meantime, refer to the [high-level data flow](https://jira.hyperledger.org/browse/FAB-37). diff --git a/docs/glossary.md b/docs/glossary.md deleted file mode 100644 index 3400ee67bfa..00000000000 --- a/docs/glossary.md +++ /dev/null @@ -1,291 +0,0 @@ -# Hyperledger Fabric Glossary - -*Note: This glossary is structured to prioritize new terms and features specific -to architecture.  It makes the assumption that one already possesses a -working familiarity with the basic tenets of blockchain.* - -## Blockchain Network -A blockchain network consists of, at minimum, one peer -(responsible for endorsing and committing transactions) leveraging an ordering -service, and a membership services component (certificate authority) that -distributes and revokes cryptographic certificates representative of user -identities and permissions. - -## Permissioned Network -A blockchain network where any entity (node) is -required to maintain a member identity on the network. End users must be -authorized and authenticated in order to use the network. - -## Peer -Peer is a component that executes, and maintains a ledger of, transactions.   -There are two roles for a peer – endorser and committer.  The architecture has -been designed such that a peer is always a committer, but not necessarily always -an endorser. Peers play no role in the ordering of transactions. - -## Member -A Member is a participant (such as a company or organization) that -operates components - Peers, Orderers, and applications - in the blockchain -network.  A member is identified by its CA certificate (i.e. a unique enrollment).   -A Member’s peer will be leveraged by end users in order to perform transaction -operations on specific channels. - -## Transaction -Refers to an operation in which an authorized end user -performs read/write operations against the ledger. There are three unique types -of transactions - deploy, invoke, and query. - -## End User -An end user is someone who would interact with the blockchain -through a set of published APIs (i.e. the hfc SDK).  You can have an admin user -who will typically grant permissions to the Member’s components, and a client -user, who, upon proper authentication through the admin user, will drive -chaincode applications (deploy, invoke, query) on various channels.  In the case -of self-executing transactions, the application itself can also be thought of -as the end user. - -## Ordering Service -A centralized or decentralized service that orders -transactions in a block.  You can select different implementations of the -"ordering" function - e.g "solo" for simplicity and testing, Kafka for crash -fault tolerance, or sBFT/PBFT for byzantine fault tolerance. You can also -develop your own protocol to plug into the service. - -## Consensus -A broader term overarching the entire transactional flow, which -serves to generate an agreement on the order and to confirm the correctness of -the set of transactions constituting a block. - -## Orderer -One of the network entities that form the ordering service. A -collection of ordering service nodes (OSNs) will order transactions into blocks -according to the network's chosen ordering implementation. In the case of -"solo", only one OSN is required. Transactions are "broadcast" to orderers, and -then "delivered" as blocks to the appropriate channel. - -## Endorser -A specific peer role, where the Endorser peer is responsible for -simulating transactions, and in turn preventing unstable or non-deterministic -transactions from passing through the network.  A transaction is sent to an -endorser in the form of a transaction proposal.  All endorsing peers are also -committing peers (i.e. they write to the ledger). - -## Committer -A specific peer role, where the Committing peer appends the -validated transactions to the channel-specific ledger.  A peer can act as both -an endorser and committer, but in more regulated circumstances might only serve -as a committer. - -## Bootstrap -The initial setup of a network.  There is the bootstrap of a -peer network, during which policies, system chaincodes, and cryptographic -materials (certs) are disseminated amongst participants, and the bootstrap -of an ordering network.  The bootstrap of the ordering network must precede the -bootstrap of the peer network, as a peer network is contingent upon the presence -of an ordering service. A network need only be “bootstrapped” once. - -## Block -A batch of ordered transactions, potentially containing ones of an -invalid nature, that is delivered to the peers for validation and committal. - -## System chain -Contains a configuration block defining the network at a system level. -The system chain lives within the ordering service, and similar to a -channel, has an initial configuration containing information -such as: root certificates for participating organizations and ordering service nodes, -policies, listening address for OSN, and configuration details. Any change to the -overall network (e.g. a new org joining or a new OSN being added) will result -in a new configuration block being added to the system chain. - -The system chain can be thought of as the common binding for a channel or group -of channels. For instance, a collection of financial institutions may form a -consortium (represented through the system chain), and then proceed to create -channels relative to their aligned and varying business agendas. - -## Channel -A Channel is formed as an offshoot of the system chain; and best thought of -as a “topic” for peers to subscribe to, or rather, a subset of a -broader blockchain network. A peer may subscribe on various channels and can -only access the transactions on the subscribed channels.  Each channel will have -a unique ledger, thus accommodating confidentiality and execution of multilateral -contracts. - -## Multi-channel -The fabric will allow for multiple channels with a -designated ledger per channel.  This capability allows for multilateral contracts -where only the restricted participants on the channel will submit, endorse, -order, or commit transactions on that channel.  As such, a single peer can -maintain multiple ledgers without compromising privacy and confidentiality. - -## Configuration Block -Contains the configuration data defining members and -policies for a system chain or channel(s). Any changes to the channel(s) or -overall network (e.g. a new member successfully joining) will result in a new -configuration block being appended to the appropriate chain.  This block will -contain the contents of the genesis block, plus the delta. The policy to alter -or edit a channel-level configuration block is defined through the Configuration -System Chaincode (CSCC). - -## Genesis Block -The configuration block that initializes a blockchain -network or channel, and also serves as the first block on a chain. - -## Ledger -An append-only transaction log managed by peers.  Ledger keeps the -log of ordered transaction batches. There are two denotations for ledger; peer -and validated. The peer ledger contains all batched transactions coming out of -the ordering service, some of which may in fact be invalid. The validated ledger -will contain fully endorsed and validated transaction blocks. In other words, -transactions in the validated ledger have passed the entire gamut of "consensus" -- i.e. they have been endorsed, ordered, and validated. - -## Dynamic membership -he fabric will allow for endorsers and committers to -come and go based on membership, and the blockchain network will continue to -operate. Dynamic membership is critical when businesses grow and members need to -be added or removed for various reasons. - -## Query/Non-Key Value Query -using couchDB 2.0 you now have the capability -to leverage an API to perform more complex queries against combinations of -variables, including time ranges, transaction types, users, etc.  This feature -allows for auditors and regulators to aggregate and mine large chunks of data. - -## Gossip Protocol -A communication protocol used among peers in a channel, to -maintain their network and to elect Leaders, through which funnels all -communications with the Ordering Service. Gossip allows for data dissemination, -therein providing support for scalability due to the fact that not all peers -are required to execute transactions and communicate with the ordering service. - -## System Chaincode -System Chaincode (SCC) is a chaincode built with the peer -and run in the same process as the peer. SCC is responsible for broader -configurations of fabric behavior, such as timing and naming services. - -## Lifecycle System Chaincode -Lifecycle System Chaincode (LSCC) is a system chaincode that handles deployment, -upgrade and termination transactions for user chaincodes. - -## Configuration System Chaincode -Configuration System Chaincode (CSCC) is a “management” system chaincode that -handles configuration requests to alter an aspect of a channel -(e.g. add a new member).  The CSCC will interrogate the channel’s policies to -determine if a new configuration block can be created. - -## Endorsement System Chaincode -Endorsement System Chaincode (ESCC) is a system chaincode that andles the -endorsement policy for specific pieces of chaincode deployed on a network, -and defines the necessary parameters (percentage or combination of signatures -from endorsing peers) for a transaction proposal to receive a successful -proposal response (i.e. endorsement).  Deployments and invocations of user -chaincodes both require a corresponding ESCC, which is defined at the time of -the deployment transaction proposal for the user chaincode. - -## Validation System Chaincode -Validation System Chaincode (VSCC) Handles the validation policy for -specific pieces of chaincode deployed on a network.  Deployments and invocations -of user chaincodes both require a corresponding VSCC, which is defined at the -time of the deployment transaction proposal for the user chaincode. VSCC -validates the specified level of "endorsement" (i.e. endorsement policy) in -order to prevent malicious or faulty behavior from the client. - -## Policy -There are policies for endorsement, validation, block committal, -chaincode management and network/channel management.  Policies are defined -through system chaincodes, and contain the requisite specifications for a -network action to succeed.  For example, an endorsement policy may require that -100% of endorsers achieve the same result upon transaction simulation. - -## Endorsement policy -A blockchain network must establish rules that govern -the endorsement (or not) of proposed, simulated transactions. This endorsement -policy could require that a transaction be endorsed by a minimum number of -endorsing peers, a minimum percentage of endorsing peers, or by all endorsing -peers that are assigned to a specific chaincode application. Policies can be -curated based on the application and the desired level of resilience against -misbehavior (deliberate or not) by the endorsing peers. A distinct endorsement -policy for deploy transactions, which install new chaincode, is also required. - -## Proposal -A transaction request sent from a client or admin user to one or -more peers in a network; examples include deploy, invoke, query, or -configuration request. - -## Deploy -Refers to the function through which chaincode applications are -deployed on `chain`. A deploy is first sent from the client SDK or CLI to a -Lifecycle System Chaincode in the form of a proposal. - -## Invoke -Used to call chaincode functions.  Invocations are captured as -transaction proposals, which then pass through a modular flow of endorsement, -ordering, validation, committal.  The structure of invoke is a function and an -array of arguments. - -## Membership Services -Membership Services manages user identities on a -permissioned blockchain network; this function is implemented through the -`fabric-ca` component.  `fabric-ca` is comprised of a client and server, and -handles the distribution and revocation of enrollment materials (certificates), -which serve to identify and authenticate users on a network. - -The in-line `MembershipSrvc` code (MSP) runs on the peers themselves, and is used by -the peer when authenticating transaction processing results, and by the client -to verify/authenticate transactions. Membership Services provides a distinction -of roles by combining elements of Public Key Infrastructure (PKI) and -decentralization (consensus). By contrast, non-permissioned networks do not -provide member-specific authority or a distinction of roles. - -A permissioned blockchain requires entities to register for long-term identity -credentials (Enrollment Certificates), which can be distinguished according to -entity type. For users, an Enrollment Certificate authorizes the Transaction -Certificate Authority (TCA) to issue pseudonymous credentials; these -certificates authorize transactions submitted by the user. Transaction -certificates persist on the blockchain, and enable authorized auditors to -associate, and identify the transacting parties for otherwise un-linkable -transactions. - -## Membership Service Provider -The Membership Service Provider (MSP) refers to an abstract component of the -system that provides (anonymous) credentials to clients, and peers for them to -participate in a Hyperledger/fabric network. Clients use these credentials to -authenticate their transactions, and peers use these credentials to authenticate -transaction processing results (endorsements). While strongly connected to the -transaction processing components of the systems, this interface aims to have -membership services components defined, in such a way that alternate -implementations of this can be smoothly plugged in without modifying the core of -transaction processing components of the system. - -## Initialize -A chaincode method to define the assets and parameters in a -piece of chaincode prior to issuing deploys and invocations.  As the name -implies, this function should be used to do any initialization to the chaincode, -such as configure the initial state of a key/value pair on the ledger. - -## appshim -An application client used by ordering service nodes to -process "broadcast" messages arriving from clients or peers. This shim allows -the ordering service to perform membership-related functionality checks. In -other words, is a peer or client properly authorized to perform the requested -function (e.g. upgrade chaincode or reconfigure channel settings). - -## osshim -An ordering service client used by the application to process -ordering service messages (i.e. "deliver" messages) that are advertised -within a channel. - -## Hyperledger Fabric Client SDK -Provides a powerful set of APIs and contains myriad “methods” or “calls” -that expose the capabilities and functionalities in the Hyperledger Fabric -code base.  For example, `addMember`, `removeMember`. The Fabric SDK -comes in multiple flavors - Node.js, Java, and Python, for starters - -thus, allowing developers to write application code in any of those -programming languages. - -## Chaincode -Embedded logic that encodes the rules for specific types of -network transactions. Developers write chaincode applications, which are then -deployed onto a chain by an appropriately authorized member. End users then -invoke chaincode through a client-side application that interfaces with a -network peer. Chaincode runs network transactions, which if validated, are -appended to the shared ledger and modify world state. diff --git a/docs/gossip.md b/docs/gossip.md deleted file mode 100644 index 8726654bbef..00000000000 --- a/docs/gossip.md +++ /dev/null @@ -1,3 +0,0 @@ -## Gossip data dissemination protocol - -...coming soon diff --git a/docs/included.md b/docs/included.md deleted file mode 100644 index a7db3f94c68..00000000000 --- a/docs/included.md +++ /dev/null @@ -1,24 +0,0 @@ -# What's Included? - -This section demonstrates an example using the Hyperledger Fabric V1.0 architecture. -The scenario will include the creation and joining of channels, client side authentication, -and the deployment and invocation of chaincode. CLI will be used for the creation and -joining of the channel and the node SDK will be used for the client authentication, -and chaincode functions utilizing the channel. - -Docker Compose will be used to create a consortium of three organizations, each -running an endorsing/committing peer, as well as a "solo" orderer and a Certificate Authority (CA). -The cryptographic material, based on standard PKI implementation, has been pre-generated -and is included in the `sfhackfest.tar.gz` in order to expedite the flow. The CA, responsible for -issuing, revoking and maintaining the crypto material, represents one of the organizations and -is needed by the client (node SDK) for authentication. In an enterprise scenario, each -organization might have their own CA, with more complex security measures implemented - e.g. -cross-signing certificates, etc. - -The network will be generated automatically upon execution of `docker-compose up`, -and the APIs for create channel and join channel will be explained and demonstrated; -as such, a user can go through the steps to manually generate their own network -and channel, or quickly jump to the application development phase. - -It is recommended to run through this section in the order it is laid out - node -program first, followed by the CLI approach. diff --git a/docs/incubation.md b/docs/incubation.md deleted file mode 100644 index cf9f0b2969a..00000000000 --- a/docs/incubation.md +++ /dev/null @@ -1,6 +0,0 @@ -# Incubation Notice - -This project is a Hyperledger project in _Incubation_. It was proposed to the -community and documented [here](https://goo.gl/RYQZ5N). Information on what -_Incubation_ entails can be found in the [Hyperledger Project Lifecycle -document](https://goo.gl/4edNRc). diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 419ada2c418..00000000000 --- a/docs/index.md +++ /dev/null @@ -1,21 +0,0 @@ -[![Build Status](https://jenkins.hyperledger.org/buildStatus/icon?job=fabric-merge-x86_64)](https://jenkins.hyperledger.org/view/fabric/job/fabric-merge-x86_64/) -[![Go Report Card](https://goreportcard.com/badge/github.com/hyperledger/fabric)](https://goreportcard.com/report/github.com/hyperledger/fabric) -[![GoDoc](https://godoc.org/github.com/hyperledger/fabric?status.svg)](https://godoc.org/github.com/hyperledger/fabric) -[![Documentation Status](https://readthedocs.org/projects/hyperledger-fabric/badge/?version=latest)](http://hyperledger-fabric.readthedocs.io/en/latest/?badge=latest) - -# Hyperledger Fabric - -Hyperledger Fabric is an open source blockchain technology that leverages -proven technologies in providing a base [architecture](architecture.md) for -custom enterprise networks. Hyperledger Fabric is modular, allowing for -pluggable implementation of blockchain components, such as smart contracts -(chaincode), cryptographic algorithms, consensus protocols and data store -solutions. The fabric leverages powerful container technology for deployment, -and to provide a secure chaincode execution environment that protects the -network against malicious code. - -**Attention**: The Hyperledger Fabric project team is continually working to -improve the security, performance and robustness of the released software, and -frequently publishes updates. To stay current as the project progresses, please -see the **Communication** and **Still Have Questions?** topics. Your -participation in Linux Foundation projects is welcomed and encouraged! diff --git a/docs/install_instantiate.md b/docs/install_instantiate.md deleted file mode 100644 index 1f491b034b9..00000000000 --- a/docs/install_instantiate.md +++ /dev/null @@ -1,139 +0,0 @@ -# Install and Instantiate - -This tutorial requires the latest builds for `hyperledger/fabric-baseimage`, `hyperledger/fabric-peer` -and `hyperledger/fabric-orderer`. Rather than pull from docker hub, you can compile -these images locally to ensure they are up to date. It is up to the user how to build -the images, although a typical approach is through vagrant. If you do choose to build -through vagrant, make sure you have followed the steps outlined in -[setting up the development environment](dev-setup/devenv.md). Then from the -fabric directory within your vagrant environment, execute the `make peer-docker` -and `make orderer-docker` commands. - -### Start the network of 2 peers, an orderer, and a CLI container -Navigate to the fabric/docs directory in your vagrant environment and start your network: -```bash -docker-compose -f docker-2peer.yml up -``` -View all your containers: -```bash -# active and non-active -docker ps -a -``` - -### Get into the CLI container -Now, open a second terminal and navigate once again to your vagrant environment. -```bash -docker exec -it cli bash -``` -You should see the following in your terminal: -```bash -root@ccd3308afc73:/opt/gopath/src/github.com/hyperledger/fabric/peer# -``` - -### Create and join channel from the remote CLI -From your second terminal, lets create a channel by the name of "myc": -```bash -peer channel create -c myc -o orderer:5005 -``` -This will generate a genesis block - `myc.block` - and place it into the same directory -from which you issued your `peer channel create` command. Now, from the same directory, -direct both peers to join channel - `myc` - by passing in the genesis block -- `myc.block` - with a `peer channel join` command: -```bash -CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc.block -CORE_PEER_ADDRESS=peer1:7051 peer channel join -b myc.block -``` - -### Install the chaincode on peer0 from the remote CLI -From your second terminal, and still within the CLI container, issue the following -command to install a chaincode named `mycc` with a version of `v0` onto `peer0`. -```bash -CORE_PEER_ADDRESS=peer0:7051 peer chaincode install \ - -o orderer:5005 \ - -n mycc \ - -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 \ - -v v0 -``` - -### Instantiate the chaincode on the channel from the remote CLI -Now, still within the cli container in your second terminal, instantiate the chaincode -`mycc` with version `v0` onto `peer0`. This instantiation will initialize the chaincode -with key value pairs of ["a","100"] and ["b","200"]. -```bash -CORE_PEER_ADDRESS=peer0:7051 peer chaincode instantiate \ - -o orderer:5005 \ - -C myc \ - -n mycc \ - -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 \ - -c '{"Args":["init","a","100","b","200"]}' \ - -v v0 -``` -__Continue operating within your second terminal for the remainder of the commands__ - -### Query for the value of "a" to make sure the chaincode container has successfully started -Send a query to `peer0` for the value of key `"a"`: -```bash -CORE_PEER_ADDRESS=peer0:7051 peer chaincode query \ - -C myc \ - -n mycc \ - -c '{"Args":["query","a"]}' \ - -v v0 -``` -This query should return "100". - -### Invoke to make a state change -Send an invoke request to `peer0` to move 10 units from "a" to "b": -```bash -CORE_PEER_ADDRESS=peer0:7051 peer chaincode invoke \ - -C myc \ - -n mycc \ - -c '{"Args":["invoke","a","b","10"]}' \ - -v v0 -``` - -### Query on the second peer -Issue a query against the key "a" to `peer1`. Recall that `peer1` has successfully -joined the channel. -```bash -CORE_PEER_ADDRESS=peer1:7051 peer chaincode query \ - -C myc \ - -n mycc \ - -c '{"Args":["query","a"]}' \ - -v v0 -``` -This will return an error response because `peer1` does not have the chaincode installed. - -### Install on the second peer -Now add the chaincode to `peer1` so that you can successfully perform read/write operations. -```bash -CORE_PEER_ADDRESS=peer1:7051 peer chaincode install \ - -o orderer:5005 \ - -n mycc \ - -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 \ - -v v0 -``` -__Note__: The initial instantiation applies to all peers in the channel, and is -affected upon any peer that has the chaincode installed. Therefore, we installed -the chaincode on `peer0` in order to execute the instantiate command through it. -Now that we want to access the chaincode on `peer1`, we must install the chaincode -on `peer1` as well. In general, a chaincode has to be installed only on those peers -through which the chaincode needs to be accessed from. In particular, the -chaincode must be installed on any peer receiving endorsement requests for that chaincode. - -### Query on the second peer -Now issue the same query request to `peer1`. -```bash -CORE_PEER_ADDRESS=peer1:7051 peer chaincode query \ - -C myc \ - -n mycc \ - -c '{"Args":["query","a"]}' \ - -v v0 -``` -Query will now succeed. - -### What does this demonstrate? -- The ability to invoke (alter key value states) is restricted to peers that have the chaincode installed. -- Just as state changes due to invoke on a peer affects all peers in the channel, the instantiate on a peer will -likewise affect all peers in the channel. -- The world state of the chaincode is available to all peers on the channel - even those that do not have the chaincode installed. -- Once the chaincode is installed on a peer, invokes and queries can access those states normally. diff --git a/docs/javasdk.md b/docs/javasdk.md deleted file mode 100644 index d72032c72a4..00000000000 --- a/docs/javasdk.md +++ /dev/null @@ -1,12 +0,0 @@ -# Java SDK - -[WIP] -...coming soon - -In the meantime, refer to the [Hyperledger Fabric SDK design doc](https://docs.google.com/document/d/1R5RtIBMW9fZpli37E5Li5_Q9ve3BnQ4q3gWmGZj6Sv4/edit#heading=h.z6ne0og04bp5) -for more details on the APIs and specifications. - -OR - -Refer to the [fabric-sdk-java](https://github.com/hyperledger/fabric-sdk-java) -repository in the Hyperledger community. diff --git a/docs/jira_navigation.md b/docs/jira_navigation.md deleted file mode 100644 index 7183c926852..00000000000 --- a/docs/jira_navigation.md +++ /dev/null @@ -1,49 +0,0 @@ -# Using Jira to understand current work items - -This document has been created to give further insight into the work in progress -towards the hyperledger/fabric v1 architecture based off the community roadmap. -The requirements for the roadmap are being tracked in [Jira]( https://jira.hyperledger.org/). - -It was determined to organize in sprints to better track and show a prioritized -order of items to be implemented based on feedback received. We’ve done this via -boards. -To see these boards and the priorities click on **Boards** -> **Manage Boards**: - -![Jira boards](images/Jira.png) - -Now on the left side of the screen click on **All boards**: - -![Jira boards](images/Jira1.png) - -On this page you will see all the public (and restricted) boards that have been -created. If you want to see the items with current sprint focus, click on the -boards where the column labeled **Visibility** is **All Users** and the column -**Board type** is labeled **Scrum**. For example the **Board Name** Consensus: - -![Jira boards](images/Jira2.png) - -When you click on Consensus under **Board name** you will be directed to a page -that contains the following columns: - -![Jira boards](images/Jira3.png) - -The meanings to these columns are as follows: - -* Backlog – list of items slated for the current sprint (sprints are defined in - 2 week iterations), but are not currently in progress -* In progress – are items currently being worked by someone in the community. -* In Review – waiting to be reviewed and merged in Gerritt -* Done – merged and complete in the sprint. - -If you want to see all items in the backlog for a given feature set click on the -stacked rows on the left navigation of the screen: - -![Jira boards](images/Jira4.png) - -This shows you items slated for the current sprint at the top, and all items in -the backlog at the bottom. Items are listed in priority order. - -If there is an item you are interested in working on, want more information or -have questions, or if there is an item that you feel needs to be in higher -priority, please add comments directly to the Jira item. All feedback and help -is very much appreciated. diff --git a/docs/learn_chaincode.md b/docs/learn_chaincode.md deleted file mode 100644 index 61e84dadbdd..00000000000 --- a/docs/learn_chaincode.md +++ /dev/null @@ -1,10 +0,0 @@ -# Learn to write chaincode - -[WIP] -...coming soon - -Teaches a developer how to write chaincode functions and implement the necessary -interfaces to create generic assets. - -In the meantime, visit the learn chaincode repo [here](https://github.com/IBM-Blockchain/learn-chaincode) -to familiarize yourself with high level concepts and go code. diff --git a/docs/ledger.md b/docs/ledger.md deleted file mode 100644 index 9cf5aef8d45..00000000000 --- a/docs/ledger.md +++ /dev/null @@ -1,15 +0,0 @@ -# Ledger - -[WIP] -...coming soon - -The ledger exists as a peer process utilizing levelDB. It supports the high level -transaction flow - read-write-set simulation, endorsement, MVCC check, file-based -blockchain transaction log, and state database. - -v1 architecture has been designed to support various ledger implementations such -as couchDB, where more complexity with rich queries, pruning, archiving, etc... -becomes possible. - -For more information on the current state of ledger development, explore the corresponding -JIRA issue - https://jira.hyperledger.org/browse/FAB-758 diff --git a/docs/license.md b/docs/license.md deleted file mode 100644 index aa433338eba..00000000000 --- a/docs/license.md +++ /dev/null @@ -1,3 +0,0 @@ -# License -The Hyperledger Project uses the [Apache License Version 2.0](LICENSE) software -license. diff --git a/docs/marbles.md b/docs/marbles.md deleted file mode 100644 index 7a673456c8b..00000000000 --- a/docs/marbles.md +++ /dev/null @@ -1,10 +0,0 @@ -# Marbles - -[WIP] -...coming soon - -The marbles chaincode application demonstrates the ability to create assets (marbles) -with unique attributes - size, color, owner, etc... and trade these assets with fellow -participants in a blockchain network. It is not yet stable with v1 codebase. - -Learn more about the marbles chaincode and client-side application [here](https://github.com/IBM-Blockchain/marbles) diff --git a/docs/multichannel.md b/docs/multichannel.md deleted file mode 100644 index 833b68b56ab..00000000000 --- a/docs/multichannel.md +++ /dev/null @@ -1,12 +0,0 @@ -# Multichannel - -[WIP] - -The fabric will allow for multiple channels with a designated ledger per channel (data segregation). -This capability allows for multilateral contracts where only the restricted -participants on the channel will submit, endorse, order, or commit transactions -on that channel.  As such, a single peer can maintain multiple ledgers without -compromising privacy and confidentiality. - -Refer to the [multichannel design document](https://docs.google.com/document/d/1eRNxxQ0P8yp4Wh__Vi6ddaN_vhN2RQHP-IruHNUwyhc/edit#heading=h.hml58k6zw29h) -for more detailed explanation on the mechanics and architecture. diff --git a/docs/nodesdk.md b/docs/nodesdk.md deleted file mode 100644 index eb72b328bbb..00000000000 --- a/docs/nodesdk.md +++ /dev/null @@ -1,12 +0,0 @@ -# Node SDK - -[WIP] -...coming soon - -In the meantime, refer to the [Hyperledger Fabric SDK design doc](https://docs.google.com/document/d/1R5RtIBMW9fZpli37E5Li5_Q9ve3BnQ4q3gWmGZj6Sv4/edit#heading=h.z6ne0og04bp5) -for more details on the APIs and specifications. - -OR - -Refer to the [fabric-sdk-node](https://github.com/hyperledger/fabric-sdk-node) -repository in the Hyperledger community. diff --git a/docs/orderingservice.md b/docs/orderingservice.md deleted file mode 100644 index e6f16fb1ee7..00000000000 --- a/docs/orderingservice.md +++ /dev/null @@ -1,13 +0,0 @@ -# Ordering Service - -[WIP] -...coming soon - -This topic will outline the role and functionalities of the ordering service, and -explain its place in the broader network and in the lifecycle of a transaction. -The v1 architecture has been designed such that the ordering service is the centralized -point of trust in a decentralized network, but also such that the specific -implementation of "ordering" (solo, kafka, BFT) becomes a pluggable component. - -Refer to the design document on a [Kafka-based Ordering Service](https://docs.google.com/document/d/1vNMaM7XhOlu9tB_10dKnlrhy5d7b1u8lSY8a-kVjCO4/edit) -for more information on the default v1 implementation. diff --git a/docs/overview.md b/docs/overview.md deleted file mode 100644 index cff2e68521e..00000000000 --- a/docs/overview.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -**Hyperledger Fabric** is an implementation of a robust and flexible blockchain network architecture -that provides enterprise-ready security, scalability, confidentiality and -performance. Its unique implementation of distributed ledger technology (DLT) -ensures data integrity and consistency, while delivering accountability, -transparency and efficiency to the network. - -The key design features woven into the fabric fulfill its promise of a -comprehensive, yet customizable, enterprise blockchain solution: - -- Permissioned membership provides a trusted blockchain network, where -participants know that all transactions can be detected and traced by authorized -regulators and auditors. -- Channels enable multi-lateral transactions with the high degrees of privacy -and confidentiality required by competing businesses and regulated industries -that exchange assets on a common network. -- The immutable, shared ledger encodes the entire transaction history for each -channel, and includes SQL-like query capability for efficient auditing and -dispute resolution. -- Chaincode execution is partitioned from transaction ordering, limiting -the required levels of trust and verification across node types, and optimizing -network scalability and performance. -- Modularity enables network designers to plug in their preferred -implementations for components such as transaction ordering (consensus), -identity management and encryption. - -Hyperledger Fabric delivers a uniquely elastic and extensible architecture, -distinguishing it from alternative blockchain solutions. Planning for the -future of enterprise blockchain requires building on top of a fully-vetted, -open architecture; Hyperledger Fabric is your starting point. diff --git a/docs/paper.md b/docs/paper.md deleted file mode 100644 index f381690ae3e..00000000000 --- a/docs/paper.md +++ /dev/null @@ -1,9 +0,0 @@ -# Commercial Paper - -[WIP] -...coming soon - -Web application demonstrating a commercial trading network and the issuance and -maturation of trades. Not yet stable with v1 codebase. - -Learn more about the application and underlying chaincode [here](https://github.com/IBM-Blockchain/cp-web) diff --git a/docs/pluggableos.md b/docs/pluggableos.md deleted file mode 100644 index ad45af734f2..00000000000 --- a/docs/pluggableos.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pluggable Ordering implementations - -[WIP] -...coming soon - -This topic is intended to explain how to configure an ordering service such that -it implements a alternate protocol from the default kafka-based method. - -This JIRA issue outlines the proposal for a Simplified Byzantine Fault Tolerant -consensus protocol - https://jira.hyperledger.org/browse/FAB-378 diff --git a/docs/protocol-spec.md b/docs/protocol-spec.md deleted file mode 100644 index 96be4ac14e1..00000000000 --- a/docs/protocol-spec.md +++ /dev/null @@ -1,3089 +0,0 @@ -# Protocol Specification - -## Preface -This document is the protocol specification for a permissioned blockchain implementation for industry use-cases. It is not intended to be a complete explanation of the implementation, but rather a description of the interfaces and relationships between components in the system and the application. - -### Intended Audience -The intended audience for this specification includes the following groups: - -- Blockchain vendors who want to implement blockchain systems that conform to this specification -- Tool developers who want to extend the capabilities of the fabric -- Application developers who want to leverage blockchain technologies to enrich their applications -________________________________________________________ - -## Table of Contents -#### [1. Introduction](#1-introduction_1) - - [1.1 What is the fabric?](#11-what-is-the-fabric) - - [1.2 Why the fabric?](#12-why-the-fabric) - - [1.3 Terminology](#13-terminology) - -#### [2. Fabric](#2-fabric_1) - - [2.1 Architecture](#21-architecture) - - [2.1.1 Membership Services](#211-membership-services) - - [2.1.2 Blockchain Services](#212-blockchain-services) - - [2.1.3 Chaincode Services](#213-chaincode-services) - - [2.1.4 Events](#214-events) - - [2.1.5 Application Programming Interface (API)](#215-application-programming-interface-api) - - [2.1.6 Command Line Interface (CLI)](#216-command-line-interface-cli) - - [2.2 Topology](#22-topology) - - [2.2.1 Single Validating Peer](#221-single-validating-peer) - - [2.2.2 Multiple Validating Peers](#222-multiple-validating-peers) - - [2.2.3 Multichain](#223-multichain) - -#### [3. Protocol](#3-protocol_1) - - [3.1 Message](#31-message) - - [3.1.1 Discovery Messages](#311-discovery-messages) - - [3.1.2 Transaction Messages](#312-transaction-messages) - - [3.1.2.1 Transaction Data Structure](#3121-transaction-data-structure) - - [3.1.2.2 Transaction Specification](#3122-transaction-specification) - - [3.1.2.3 Deploy Transaction](#3123-deploy-transaction) - - [3.1.2.4 Invoke Transaction](#3124-invoke-transaction) - - [3.1.2.5 Query Transaction](#3125-query-transaction) - - [3.1.3 Synchronization Messages](#313-synchronization-messages) - - [3.1.4 Consensus Messages](#314-consensus-messages) - - [3.2 Ledger](#32-ledger) - - [3.2.1 Blockchain](#321-blockchain) - - [3.2.1.1 Block](#3211-block) - - [3.2.1.2 Block Hashing](#3212-block-hashing) - - [3.2.1.3 NonHashData](#3213-nonhashdata) - - [3.2.1.4 Transaction Execution](#3214-transaction-execution) - - [3.2.2 World State](#322-world-state) - - [3.2.2.1 Hashing the world state](#3221-hashing-the-world-state) - - [3.2.2.1.1 Bucket-tree](#32211-buckettree) - - [3.3 Chaincode](#33-chaincode) - - [3.3.1 Virtual Machine Instantiation](#331-virtual-machine-instantiation) - - [3.3.2 Chaincode Protocol](#332-chaincode-protocol) - - [3.3.2.1 Chaincode Deploy](#3321-chaincode-deploy) - - [3.3.2.2 Chaincode Invoke](#3322-chaincode-invoke) - - [3.3.2.3 Chaincode Query](#3323-chaincode-query) - - [3.3.2.4 Chaincode State](#3324-chaincode-state) - - [3.4 Pluggable Consensus Framework](#34-pluggable-consensus-framework) - - [3.4.1 Consenter interface](#341-consenter-interface) - - [3.4.2 CPI interface](#342-cpi-interface) - - [3.4.3 Inquirer interface](#343-inquirer-interface) - - [3.4.4 Communicator interface](#344-communicator-interface) - - [3.4.5 SecurityUtils interface](#345-securityutils-interface) - - [3.4.6 LedgerStack interface](#346-ledgerstack-interface) - - [3.4.7 Executor interface](#347-executor-interface) - - [3.4.7.1 Beginning a transaction batch](#3471-beginning-a-transaction-batch) - - [3.4.7.2 Executing transactions](#3472-executing-transactions) - - [3.4.7.3 Committing and rolling-back transactions](#3473-committing-and-rollingback-transactions) - - [3.4.8 Ledger interface](#348-ledger-interface) - - [3.4.8.1 ReadOnlyLedger interface](#3481-readonlyledger-interface) - - [3.4.8.2 UtilLedger interface](#3482-utilledger-interface) - - [3.4.8.3 WritableLedger interface](#3483-writableledger-interface) - - [3.4.9 RemoteLedgers interface](#349-remoteledgers-interface) - - [3.4.10 controller package](#3410-controller-package) - - [3.4.10.1 controller.NewConsenter](#34101-controllernewconsenter) - - [3.4.11 helper package](#3411-helper-package) - - [3.4.11.1 High-level overview](#34111-highlevel-overview) - - [3.4.11.2 helper.ConsensusHandler](#34112-helperconsensushandler) - - [3.4.11.3 helper.NewConsensusHandler](#34113-helpernewconsensushandler) - - [3.4.11.4 helper.Helper](#34114-helperhelper) - - [3.4.11.5 helper.NewHelper](#34115-helpernewhelper) - - [3.4.11.6 helper.HandleMessage](#34116-helperhandlemessage) - - [3.5 Events](#35-events) - - [3.5.1 Event Stream](#351-event-stream) - - [3.5.1.1 Event Producer](#3511-event-producer) - - [3.5.1.2 Event Consumer](#3512-event-consumer) - - [3.5.2 Event Adapters](#352-event-adapters) - - [3.5.3 Event Structure](#353-event-structure) - -#### [4. Security](#4-security_1) - - [4.1 Business security requirements](#41-business-security-requirements) - - [4.2 User Privacy through Membership Services](#42-user-privacy-through-membership-services) - - [4.2.1 User/Client Enrollment Process](#421-userclient-enrollment-process) - - [4.2.2 Expiration and revocation of certificates](#422-expiration-and-revocation-of-certificates) - - [4.3 Transaction security offerings at the infrastructure level](#43-transaction-security-offerings-at-the-infrastructure-level) - - [4.3.1 Security Lifecycle of Transactions](#431-security-lifecycle-of-transactions) - - [4.3.2 Transaction confidentiality](#432-transaction-confidentiality) - - [4.3.2.1 Confidentiality against users](#4321-confidentiality-against-users) - - [4.3.2.2 Confidentiality against validators](#4322-confidentiality-against-validators) - - [4.3.3 Replay attack resistance](#433-replay-attack-resistance) - - [4.4 Access control features on the application](#44-access-control-features-on-the-application) - - [4.4.1 Invocation access control](#441-invocation-access-control) - - [4.4.2 Read access control](#442-read-access-control) - - [4.5 Online wallet service](#45-online-wallet-service) - - [4.6 Network security (TLS)](#46-network-security-tls) - - [4.7 Restrictions in the current release](#47-restrictions-in-the-current-release) - - [4.7.1 Simplified client](#471-simplified-client) - - [4.7.2 Simplified transaction confidentiality](#472-simplified-transaction-confidentiality) - -#### [5. Byzantine Consensus](#5-byzantine-consensus_1) - - [5.1 Overview](#51-overview) - - [5.2 Core PBFT Functions](#52-core-pbft-functions) - - [5.2.1 newPbftCore](#521-newpbftcore) - -#### [6. Application Programming Interface](#6-application-programming-interface_1) - - [6.1 REST Service](#61-rest-service) - - [6.2 REST API](#62-rest-api) - - [6.2.1 REST Endpoints](#621-rest-endpoints) - - [6.2.1.1 Block API](#6211-block-api) - - [6.2.1.2 Blockchain API](#6212-blockchain-api) - - [6.2.1.3 Chaincode API](#6213-chaincode-api) - - [6.2.1.4 Network API](#6214-network-api) - - [6.2.1.5 Registrar API (member services)](#6215-registrar-api-member-services) - - [6.2.1.6 Transactions API](#6216-transactions-api) - - [6.3 CLI](#63-cli) - - [6.3.1 CLI Commands](#631-cli-commands) - - [6.3.1.1 node start](#6311-node-start) - - [6.3.1.2 network login](#6312-network-login) - - [6.3.1.3 chaincode deploy](#6313-chaincode-deploy) - - [6.3.1.4 chaincode invoke](#6314-chaincode-invoke) - - [6.3.1.5 chaincode query](#6315-chaincode-query) - -#### [7. Application Model](#7-application-model_1) - - [7.1 Composition of an Application](#71-composition-of-an-application) - - [7.2 Sample Application](#72-sample-application) - -#### [8. Future Directions](#8-future-directions_1) - - [8.1 Enterprise Integration](#81-enterprise-integration) - - [8.2 Performance and Scalability](#82-performance-and-scalability) - - [8.3 Additional Consensus Plugins](#83-additional-consensus-plugins) - - [8.4 Additional Languages](#84-additional-languages) - -#### [9.1 Authors](#91-authors) -#### [9.2 Reviewers](#92-reviewers) -#### [9.3 Acknowledgements](#93-acknowledgements) - -#### [10. References](#10-references_1) - -________________________________________________________ - -## 1. Introduction -This document specifies the principles, architecture, and protocol of a blockchain implementation suitable for industrial use-cases. - -### 1.1 What is the fabric? -The fabric is a ledger of digital events, called transactions, shared among different participants, each having a stake in the system. The ledger can only be updated by consensus of the participants, and, once recorded, information can never be altered. Each recorded event is cryptographically verifiable with proof of agreement from the participants. - -Transactions are secured, private, and confidential. Each participant registers with proof of identity to the network membership services to gain access to the system. Transactions are issued with derived certificates unlinkable to the individual participant, offering a complete anonymity on the network. Transaction content is encrypted with sophisticated key derivation functions to ensure only intended participants may see the content, protecting the confidentiality of the business transactions. - -The ledger allows compliance with regulations as ledger entries are auditable in whole or in part. In collaboration with participants, auditors may obtain time-based certificates to allow viewing the ledger and linking transactions to provide an accurate assessment of the operations. - -The fabric is an implementation of blockchain technology, where Bitcoin could be a simple application built on the fabric. It is a modular architecture allowing components to be plug-and-play by implementing this protocol specification. It features powerful container technology to host any main stream language for smart contracts development. Leveraging familiar and proven technologies is the motto of the fabric architecture. - -### 1.2 Why the fabric? - -Early blockchain technology serves a set of purposes but is often not well-suited for the needs of specific industries. To meet the demands of modern markets, the fabric is based on an industry-focused design that addresses the multiple and varied requirements of specific industry use cases, extending the learning of the pioneers in this field while also addressing issues such as scalability. The fabric provides a new approach to enable permissioned networks, privacy, and confidentially on multiple blockchain networks. - -### 1.3 Terminology -The following terminology is defined within the limited scope of this specification to help readers understand clearly and precisely the concepts described here. - -**Transaction** is a request to the blockchain to execute a function on the ledger. The function is implemented by a **chaincode**. - -**Transactor** is an entity that issues transactions such as a client application. - -**Ledger** is a sequence of cryptographically linked blocks, containing transactions and current **world state**. - -**World State** is the collection of variables containing the results of executed transactions. - -**Chaincode** is an application-level code (a.k.a. [smart contract](https://en.wikipedia.org/wiki/Smart_contract)) stored on the ledger as a part of a transaction. Chaincode runs transactions that may modify the world state. - -**Validating Peer** is a computer node on the network responsible for running consensus, validating transactions, and maintaining the ledger. - -**Non-validating Peer** is a computer node on the network which functions as a proxy connecting transactors to the neighboring validating peers. A non-validating peer doesn't execute transactions but does verify them. It also hosts the event stream server and the REST service. - -**Permissioned Ledger** is a blockchain network where each entity or node is required to be a member of the network. Anonymous nodes are not allowed to connect. - -**Privacy** is required by the chain transactors to conceal their identities on the network. While members of the network may examine the transactions, the transactions can't be linked to the transactor without special privilege. - -**Confidentiality** is the ability to render the transaction content inaccessible to anyone other than the stakeholders of the transaction. - -**Auditability** of the blockchain is required, as business usage of blockchain needs to comply with regulations to make it easy for regulators to investigate transaction records. - - - -## 2. Fabric - -The fabric is made up of the core components described in the subsections below. - -### 2.1 Architecture -The reference architecture is aligned in 3 categories: Membership, Blockchain, and Chaincode services. These categories are logical structures, not a physical depiction of partitioning of components into separate processes, address spaces or (virtual) machines. - -![Reference architecture](images/refarch.png) - -#### 2.1.1 Membership Services -Membership provides services for managing identity, privacy, confidentiality and auditability on the network. In a non-permissioned blockchain, participation does not require authorization and all nodes can equally submit transactions and/or attempt to accumulate them into acceptable blocks, i.e. there are no distinctions of roles. Membership services combine elements of Public Key Infrastructure (PKI) and decentralization/consensus to transform a non-permissioned blockchain into a permissioned blockchain. In the latter, entities register in order to acquire long-term identity credentials (enrollment certificates), and may be distinguished according to entity type. In the case of users, such credentials enable the Transaction Certificate Authority (TCA) to issue pseudonymous credentials. Such credentials, i.e., transaction certificates, are used to authorize submitted transactions. Transaction certificates persist on the blockchain, and enable authorized auditors to cluster otherwise unlinkable transactions. - -#### 2.1.2 Blockchain Services -Blockchain services manage the distributed ledger through a peer-to-peer protocol, built on HTTP/2. The data structures are highly optimized to provide the most efficient hash algorithm for maintaining the world state replication. Different consensus (PBFT, Raft, PoW, PoS) may be plugged in and configured per deployment. - -#### 2.1.3 Chaincode Services -Chaincode services provides a secured and lightweight way to sandbox the chaincode execution on the validating nodes. The environment is a “locked down” and secured container along with a set of signed base images containing secure OS and chaincode language, runtime and SDK layers for Go, Java, and Node.js. Other languages can be enabled if required. - -#### 2.1.4 Events -Validating peers and chaincodes can emit events on the network that applications may listen for and take actions on. There is a set of pre-defined events, and chaincodes can generate custom events. Events are consumed by 1 or more event adapters. Adapters may further deliver events using other vehicles such as Web hooks or Kafka. - -#### 2.1.5 Application Programming Interface (API) -The primary interface to the fabric is a REST API and its variations over Swagger 2.0. The API allows applications to register users, query the blockchain, and to issue transactions. There is a set of APIs specifically for chaincode to interact with the stack to execute transactions and query transaction results. - -#### 2.1.6 Command Line Interface (CLI) -CLI includes a subset of the REST API to enable developers to quickly test chaincodes or query for status of transactions. CLI is implemented in Golang and operable on multiple OS platforms. - -### 2.2 Topology -A deployment of the fabric can consist of a membership service, many validating peers, non-validating peers, and 1 or more applications. All of these components make up a chain. There can be multiple chains; each one having its own operating parameters and security requirements. - -#### 2.2.1 Single Validating Peer -Functionally, a non-validating peer is a subset of a validating peer; that is, every capability on a non-validating peer may be enabled on a validating peer, so the simplest network may consist of a single validating peer node. This configuration is most appropriate for a development environment, where a single validating peer may be started up during the edit-compile-debug cycle. - -![Single Validating Peer](images/top-single-peer.png) - -A single validating peer doesn't require consensus, and by default uses the `noops` plugin, which executes transactions as they arrive. This gives the developer an immediate feedback during development. - -#### 2.2.2 Multiple Validating Peers -Production or test networks should be made up of multiple validating and non-validating peers as necessary. Non-validating peers can take workload off the validating peers, such as handling API requests and processing events. - -![Multiple Validating Peers](images/top-multi-peer.png) - -The validating peers form a mesh-network (every validating peer connects to every other validating peer) to disseminate information. A non-validating peer connects to a neighboring validating peer that it is allowed to connect to. Non-validating peers are optional since applications may communicate directly with validating peers. - -#### 2.2.3 Multichain -Each network of validating and non-validating peers makes up a chain. Many chains may be created to address different needs, similar to having multiple Web sites, each serving a different purpose. - - -## 3. Protocol -The fabric's peer-to-peer communication is built on [gRPC](http://www.grpc.io/docs/), which allows bi-directional stream-based messaging. It uses [Protocol Buffers](https://developers.google.com/protocol-buffers) to serialize data structures for data transfer between peers. Protocol buffers are a language-neutral, platform-neutral and extensible mechanism for serializing structured data. Data structures, messages, and services are described using [proto3 language](https://developers.google.com/protocol-buffers/docs/proto3) notation. - -### 3.1 Message -Messages passed between nodes are encapsulated by `Message` proto structure, which consists of 4 types: Discovery, Transaction, Synchronization, and Consensus. Each type may define more subtypes embedded in the `payload`. - -``` -message Message { - enum Type { - UNDEFINED = 0; - - DISC_HELLO = 1; - DISC_DISCONNECT = 2; - DISC_GET_PEERS = 3; - DISC_PEERS = 4; - DISC_NEWMSG = 5; - - CHAIN_STATUS = 6; - CHAIN_TRANSACTION = 7; - CHAIN_GET_TRANSACTIONS = 8; - CHAIN_QUERY = 9; - - SYNC_GET_BLOCKS = 11; - SYNC_BLOCKS = 12; - SYNC_BLOCK_ADDED = 13; - - SYNC_STATE_GET_SNAPSHOT = 14; - SYNC_STATE_SNAPSHOT = 15; - SYNC_STATE_GET_DELTAS = 16; - SYNC_STATE_DELTAS = 17; - - RESPONSE = 20; - CONSENSUS = 21; - } - Type type = 1; - bytes payload = 2; - google.protobuf.Timestamp timestamp = 3; -} -``` -The `payload` is an opaque byte array containing other objects such as `Transaction` or `Response` depending on the type of the message. For example, if the `type` is `CHAIN_TRANSACTION`, the `payload` is a `Transaction` object. - -#### 3.1.1 Discovery Messages -Upon start up, a peer runs discovery protocol if `CORE_PEER_DISCOVERY_ROOTNODE` is specified. `CORE_PEER_DISCOVERY_ROOTNODE` is the IP address of another peer on the network (any peer) that serves as the starting point for discovering all the peers on the network. The protocol sequence begins with `DISC_HELLO`, whose `payload` is a `HelloMessage` object, containing its endpoint: - -``` -message HelloMessage { - PeerEndpoint peerEndpoint = 1; - uint64 blockNumber = 2; -} -message PeerEndpoint { - PeerID ID = 1; - string address = 2; - enum Type { - UNDEFINED = 0; - VALIDATOR = 1; - NON_VALIDATOR = 2; - } - Type type = 3; - bytes pkiID = 4; -} - -message PeerID { - string name = 1; -} -``` - -**Definition of fields:** - -- `PeerID` is any name given to the peer at start up or defined in the config file -- `PeerEndpoint` describes the endpoint and whether it's a validating or a non-validating peer -- `pkiID` is the cryptographic ID of the peer -- `address` is host or IP address and port of the peer in the format `ip:port` -- `blockNumber` is the height of the blockchain the peer currently has - -If the block height received upon `DISC_HELLO` is higher than the current block height of the peer, it immediately initiates the synchronization protocol to catch up with the network. - -After `DISC_HELLO`, peer sends `DISC_GET_PEERS` periodically to discover any additional peers joining the network. In response to `DISC_GET_PEERS`, a peer sends `DISC_PEERS` with `payload` containing an array of `PeerEndpoint`. Other discovery message types are not used at this point. - -#### 3.1.2 Transaction Messages -There are 3 types of transactions: Deploy, Invoke and Query. A deploy transaction installs the specified chaincode on the chain, while invoke and query transactions call a function of a deployed chaincode. Another type in consideration is Create transaction, where a deployed chaincode may be instantiated on the chain and is addressable. This type has not been implemented as of this writing. - -##### 3.1.2.1 Transaction Data Structure - -Messages with type `CHAIN_TRANSACTION` or `CHAIN_QUERY` carry a `Transaction` object in the `payload`: - -``` -message Transaction { - enum Type { - UNDEFINED = 0; - CHAINCODE_DEPLOY = 1; - CHAINCODE_INVOKE = 2; - CHAINCODE_QUERY = 3; - CHAINCODE_TERMINATE = 4; - } - Type type = 1; - string uuid = 5; - bytes chaincodeID = 2; - bytes payloadHash = 3; - - ConfidentialityLevel confidentialityLevel = 7; - bytes nonce = 8; - bytes cert = 9; - bytes signature = 10; - - bytes metadata = 4; - google.protobuf.Timestamp timestamp = 6; -} - -message TransactionPayload { - bytes payload = 1; -} - -enum ConfidentialityLevel { - PUBLIC = 0; - CONFIDENTIAL = 1; -} - -``` -**Definition of fields:** -- `type` - The type of the transaction, which is 1 of the following: - - `UNDEFINED` - Reserved for future use. - - `CHAINCODE_DEPLOY` - Represents the deployment of a new chaincode. - - `CHAINCODE_INVOKE` - Represents a chaincode function execution that may read and modify the world state. - - `CHAINCODE_QUERY` - Represents a chaincode function execution that may only read the world state. - - `CHAINCODE_TERMINATE` - Marks a chaincode as inactive so that future functions of the chaincode can no longer be invoked. -- `chaincodeID` - The ID of a chaincode which is a hash of the chaincode source, path to the source code, constructor function, and parameters. -- `payloadHash` - Bytes defining the hash of `TransactionPayload.payload`. -- `metadata` - Bytes defining any associated transaction metadata that the application may use. -- `uuid` - A unique ID for the transaction. -- `timestamp` - A timestamp of when the transaction request was received by the peer. -- `confidentialityLevel` - Level of data confidentiality. There are currently 2 levels. Future releases may define more levels. -- `nonce` - Used for security. -- `cert` - Certificate of the transactor. -- `signature` - Signature of the transactor. -- `TransactionPayload.payload` - Bytes defining the payload of the transaction. As the payload can be large, only the payload hash is included directly in the transaction message. - -More detail on transaction security can be found in section 4. - -##### 3.1.2.2 Transaction Specification -A transaction is always associated with a chaincode specification which defines the chaincode and the execution environment such as language and security context. Currently there is an implementation that uses Golang for writing chaincode. Other languages may be added in the future. - -``` -message ChaincodeSpec { - enum Type { - UNDEFINED = 0; - GOLANG = 1; - NODE = 2; - } - Type type = 1; - ChaincodeID chaincodeID = 2; - ChaincodeInput input = 3; - int32 timeout = 4; - string secureContext = 5; - ConfidentialityLevel confidentialityLevel = 6; - bytes metadata = 7; -} - -message ChaincodeID { - string path = 1; - string name = 2; -} - -message ChaincodeInput { - string function = 1; - repeated string args = 2; -} -``` - -**Definition of fields:** -- `chaincodeID` - The chaincode source code path and name. -- `input` - Function name and argument parameters to call. -- `timeout` - Time in milliseconds to execute the transaction. -- `confidentialityLevel` - Confidentiality level of this transaction. -- `secureContext` - Security context of the transactor. -- `metadata` - Any data the application wants to pass along. - -The peer, receiving the `chaincodeSpec`, wraps it in an appropriate transaction message and broadcasts to the network. - -##### 3.1.2.3 Deploy Transaction -Transaction `type` of a deploy transaction is `CHAINCODE_DEPLOY` and the payload contains an object of `ChaincodeDeploymentSpec`. - -``` -message ChaincodeDeploymentSpec { - ChaincodeSpec chaincodeSpec = 1; - google.protobuf.Timestamp effectiveDate = 2; - bytes codePackage = 3; -} -``` -**Definition of fields:** -- `chaincodeSpec` - See section 3.1.2.2, above. -- `effectiveDate` - Time when the chaincode is ready to accept invocations. -- `codePackage` - gzip of the chaincode source. - -The validating peers always verify the hash of the `codePackage` when they deploy the chaincode to make sure the package has not been tampered with since the deploy transaction entered the network. - -##### 3.1.2.4 Invoke Transaction -Transaction `type` of an invoke transaction is `CHAINCODE_INVOKE` and the `payload` contains an object of `ChaincodeInvocationSpec`. - -``` -message ChaincodeInvocationSpec { - ChaincodeSpec chaincodeSpec = 1; -} -``` - -##### 3.1.2.5 Query Transaction -A query transaction is similar to an invoke transaction, but the message `type` is `CHAINCODE_QUERY`. - -#### 3.1.3 Synchronization Messages -Synchronization protocol starts with discovery, described above in section 3.1.1, when a peer realizes that it's behind or its current block is not the same with others. A peer broadcasts either `SYNC_GET_BLOCKS`, `SYNC_STATE_GET_SNAPSHOT`, or `SYNC_STATE_GET_DELTAS` and receives `SYNC_BLOCKS`, `SYNC_STATE_SNAPSHOT`, or `SYNC_STATE_DELTAS` respectively. - -The installed consensus plugin (e.g. pbft) dictates how synchronization protocol is being applied. Each message is designed for a specific situation: - -**SYNC_GET_BLOCKS** requests for a range of contiguous blocks expressed in the message `payload`, which is an object of `SyncBlockRange`. The correlationId specified is included in the `SyncBlockRange` of any replies to this message. -``` -message SyncBlockRange { - uint64 correlationId = 1; - uint64 start = 2; - uint64 end = 3; -} -``` -A receiving peer responds with a `SYNC_BLOCKS` message whose `payload` contains an object of `SyncBlocks` -``` -message SyncBlocks { - SyncBlockRange range = 1; - repeated Block blocks = 2; -} -``` -The `start` and `end` indicate the starting and ending blocks inclusively. The order in which blocks are returned is defined by the `start` and `end` values. For example, if `start`=3 and `end`=5, the order of blocks will be 3, 4, 5. If `start`=5 and `end`=3, the order will be 5, 4, 3. - -**SYNC_STATE_GET_SNAPSHOT** requests for the snapshot of the current world state. The `payload` is an object of `SyncStateSnapshotRequest` -``` -message SyncStateSnapshotRequest { - uint64 correlationId = 1; -} -``` -The `correlationId` is used by the requesting peer to keep track of the response messages. A receiving peer replies with `SYNC_STATE_SNAPSHOT` message whose `payload` is an instance of `SyncStateSnapshot` -``` -message SyncStateSnapshot { - bytes delta = 1; - uint64 sequence = 2; - uint64 blockNumber = 3; - SyncStateSnapshotRequest request = 4; -} -``` -This message contains the snapshot or a chunk of the snapshot on the stream, and in which case, the sequence indicate the order starting at 0. The terminating message will have len(delta) == 0. - -**SYNC_STATE_GET_DELTAS** requests for the state deltas of a range of contiguous blocks. By default, the Ledger maintains 500 transition deltas. A delta(j) is a state transition between block(i) and block(j) where i = j-1. The message `payload` contains an instance of `SyncStateDeltasRequest` -``` -message SyncStateDeltasRequest { - SyncBlockRange range = 1; -} -``` -A receiving peer responds with `SYNC_STATE_DELTAS`, whose `payload` is an instance of `SyncStateDeltas` -``` -message SyncStateDeltas { - SyncBlockRange range = 1; - repeated bytes deltas = 2; -} -``` -A delta may be applied forward (from i to j) or backward (from j to i) in the state transition. - -#### 3.1.4 Consensus Messages -Consensus deals with transactions, so a `CONSENSUS` message is initiated internally by the consensus framework when it receives a `CHAIN_TRANSACTION` message. The framework converts `CHAIN_TRANSACTION` into `CONSENSUS` then broadcasts to the validating nodes with the same `payload`. The consensus plugin receives this message and process according to its internal algorithm. The plugin may create custom subtypes to manage consensus finite state machine. See section 3.4 for more details. - - -### 3.2 Ledger - -The ledger consists of two primary pieces, the blockchain and the world state. The blockchain is a series of linked blocks that is used to record transactions within the ledger. The world state is a key-value database that chaincodes may use to store state when executed by a transaction. - -#### 3.2.1 Blockchain - -##### 3.2.1.1 Block - -The blockchain is defined as a linked list of blocks as each block contains the hash of the previous block in the chain. The two other important pieces of information that a block contains are the list of transactions contained within the block and the hash of the world state after executing all transactions in the block. - -``` -message Block { - version = 1; - google.protobuf.Timestamp timestamp = 2; - bytes transactionsHash = 3; - bytes stateHash = 4; - bytes previousBlockHash = 5; - bytes consensusMetadata = 6; - NonHashData nonHashData = 7; -} - -message BlockTransactions { - repeated Transaction transactions = 1; -} -``` -* `version` - Version used to track any protocol changes. -* `timestamp` - The timestamp to be filled in by the block proposer. -* `transactionsHash` - The merkle root hash of the block's transactions. -* `stateHash` - The merkle root hash of the world state. -* `previousBlockHash` - The hash of the previous block. -* `consensusMetadata` - Optional metadata that the consensus may include in a block. -* `nonHashData` - A `NonHashData` message that is set to nil before computing the hash of the block, but stored as part of the block in the database. -* `BlockTransactions.transactions` - An array of Transaction messages. Transactions are not included in the block directly due to their size. - -##### 3.2.1.2 Block Hashing - -* The `previousBlockHash` hash is calculated using the following algorithm. - 1. Serialize the Block message to bytes using the protocol buffer library. - - 2. Hash the serialized block message to 512 bits of output using the SHA3 SHAKE256 algorithm as described in [FIPS 202](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf). - -* The `transactionHash` is the root of the transaction merkle tree. Defining the merkle tree implementation is a TODO. - -* The `stateHash` is defined in section 3.2.2.1. - -##### 3.2.1.3 NonHashData - -The NonHashData message is used to store block metadata that is not required to be the same value on all peers. These are suggested values. - -``` -message NonHashData { - google.protobuf.Timestamp localLedgerCommitTimestamp = 1; - repeated TransactionResult transactionResults = 2; -} - -message TransactionResult { - string uuid = 1; - bytes result = 2; - uint32 errorCode = 3; - string error = 4; -} -``` - -* `localLedgerCommitTimestamp` - A timestamp indicating when the block was commited to the local ledger. - -* `TransactionResult` - An array of transaction results. - -* `TransactionResult.uuid` - The ID of the transaction. - -* `TransactionResult.result` - The return value of the transaction. - -* `TransactionResult.errorCode` - A code that can be used to log errors associated with the transaction. - -* `TransactionResult.error` - A string that can be used to log errors associated with the transaction. - - -##### 3.2.1.4 Transaction Execution - -A transaction defines either the deployment of a chaincode or the execution of a chaincode. All transactions within a block are run before recording a block in the ledger. When chaincodes execute, they may modify the world state. The hash of the world state is then recorded in the block. - - -#### 3.2.2 World State -The *world state* of a peer refers to the collection of the *states* of all the deployed chaincodes. Further, the state of a chaincode is represented as a collection of key-value pairs. Thus, logically, the world state of a peer is also a collection of key-value pairs where key consists of a tuple `{chaincodeID, ckey}`. Here, we use the term `key` to represent a key in the world state i.e., a tuple `{chaincodeID, ckey}` and we use the term `cKey` to represent a unique key within a chaincode. - -For the purpose of the description below, `chaincodeID` is assumed to be a valid utf8 string and `ckey` and the `value` can be a sequence of one or more arbitrary bytes. - -##### 3.2.2.1 Hashing the world state -During the functioning of a network, many occasions such as committing transactions and synchronizing peers may require computing a crypto-hash of the world state observed by a peer. For instance, the consensus protocol may require to ensure that a *minimum* number of peers in the network observe the same world state. - -Since, computing the crypto-hash of the world state could be an expensive operation, this is highly desirable to organize the world state such that it enables an efficient crypto-hash computation of the world state when a change occurs in the world state. Further, different organization designs may be suitable under different workloads conditions. - -Because the fabric is expected to function under a variety of scenarios leading to different workloads conditions, a pluggable mechanism is supported for organizing the world state. - -###### 3.2.2.1.1 Bucket-tree - -*Bucket-tree* is one of the implementations for organizing the world state. For the purpose of the description below, a key in the world state is represented as a concatenation of the two components (`chaincodeID` and `ckey`) separated by a `nil` byte i.e., `key` = `chaincodeID`+`nil`+`cKey`. - -This method models a *merkle-tree* on top of buckets of a *hash table* in order to compute the crypto-hash of the *world state*. - -At the core of this method, the *key-values* of the world state are assumed to be stored in a hash-table that consists of a pre-decided number of buckets (`numBuckets`). A hash function (`hashFunction`) is employed to determine the bucket number that should contain a given key. Please note that the `hashFunction` does not represent a crypto-hash method such as SHA3, rather this is a regular programming language hash function that decides the bucket number for a given key. - -For modeling the merkle-tree, the ordered buckets act as leaf nodes of the tree - lowest numbered bucket being the left most leaf node in the tree. For constructing the second-last level of the tree, a pre-decided number of leaf nodes (`maxGroupingAtEachLevel`), starting from left, are grouped together and for each such group, a node is inserted at the second-last level that acts as a common parent for all the leaf nodes in the group. Note that the number of children for the last parent node may be less than `maxGroupingAtEachLevel`. This grouping method of constructing the next higher level is repeated until the root node of the tree is constructed. - -An example setup with configuration `{numBuckets=10009 and maxGroupingAtEachLevel=10}` will result in a tree with number of nodes at different level as depicted in the following table. - -| Level | Number of nodes | -| ------------- |:---------------:| -| 0 | 1 | -| 1 | 2 | -| 2 | 11 | -| 3 | 101 | -| 4 | 1001 | -| 5 | 10009 | - -For computing the crypto-hash of the world state, the crypto-hash of each bucket is computed and is assumed to be the crypto-hash of leaf-nodes of the merkle-tree. In order to compute crypto-hash of a bucket, the key-values present in the bucket are first serialized and crypto-hash function is applied on the serialized bytes. For serializing the key-values of a bucket, all the key-values with a common chaincodeID prefix are serialized separately and then appending together, in the ascending order of chaincodeIDs. For serializing the key-values of a chaincodeID, the following information is concatenated: - 1. Length of chaincodeID (number of bytes in the chaincodeID) - - The utf8 bytes of the chaincodeID - - Number of key-values for the chaincodeID - - For each key-value (in sorted order of the ckey) - - Length of the ckey - - ckey bytes - - Length of the value - - value bytes - -For all the numeric types in the above list of items (e.g., Length of chaincodeID), protobuf's varint encoding is assumed to be used. The purpose of the above encoding is to achieve a byte representation of the key-values within a bucket that can not be arrived at by any other combination of key-values and also to reduce the overall size of the serialized bytes. - -For example, consider a bucket that contains three key-values namely, `chaincodeID1_key1:value1, chaincodeID1_key2:value2, and chaincodeID2_key1:value1`. The serialized bytes for the bucket would logically look as - `12 + chaincodeID1 + 2 + 4 + key1 + 6 + value1 + 4 + key2 + 6 + value2 + 12 + chaincodeID2 + 1 + 4 + key1 + 6 + value1` - -If a bucket has no key-value present, the crypto-hash is considered as `nil`. - -The crypto-hash of an intermediate node and root node are computed just like in a standard merkle-tree i.e., applying a crypto-hash function on the bytes obtained by concatenating the crypto-hash of all the children nodes, from left to right. Further, if a child has a crypto-hash as `nil`, the crypto-hash of the child is omitted when concatenating the children crypto-hashes. If the node has a single child, the crypto-hash of the child is assumed to be the crypto-hash of the node. Finally, the crypto-hash of the root node is considered as the crypto-hash of the world state. - -The above method offers performance benefits for computing crypto-hash when a few key-values change in the state. The major benefits include - - Computation of crypto-hashes of the unchanged buckets can be skipped - - The depth and breadth of the merkle-tree can be controlled by configuring the parameters `numBuckets` and `maxGroupingAtEachLevel`. Both depth and breadth of the tree has different implication on the performance cost incurred by and resource demand of different resources (namely - disk I/O, storage, and memory) - -In a particular deployment, all the peer nodes are expected to use same values for the configurations `numBuckets, maxGroupingAtEachLevel, and hashFunction`. Further, if any of these configurations are to be changed at a later stage, the configurations should be changed on all the peer nodes so that the comparison of crypto-hashes across peer nodes is meaningful. Also, this may require to migrate the existing data based on the implementation. For example, an implementation is expected to store the last computed crypto-hashes for all the nodes in the tree which would need to be recalculated. - - -### 3.3 Chaincode -Chaincode is an application-level code deployed as a transaction (see section 3.1.2) to be distributed to the network and managed by each validating peer as isolated sandbox. Though any virtualization technology can support the sandbox, currently Docker container is utilized to run the chaincode. The protocol described in this section enables different virtualization support implementation to plug and play. - -#### 3.3.1 Virtual Machine Instantiation -A virtual machine implements the VM interface: -``` -type VM interface { - build(ctxt context.Context, id string, args []string, env []string, attachstdin bool, attachstdout bool, reader io.Reader) error - start(ctxt context.Context, id string, args []string, env []string, attachstdin bool, attachstdout bool) error - stop(ctxt context.Context, id string, timeout uint, dontkill bool, dontremove bool) error -} -``` -The fabric instantiates the VM when it processes a Deploy transaction or other transactions on the chaincode while the VM for that chaincode is not running (either crashed or previously brought down due to inactivity). Each chaincode image is built by the `build` function, started by `start` and stopped by `stop` function. - -Once the chaincode container is up, it makes a gRPC connection back to the validating peer that started the chaincode, and that establishes the channel for Invoke and Query transactions on the chaincode. - -#### 3.3.2 Chaincode Protocol -Communication between a validating peer and its chaincodes is based on a bidirectional gRPC stream. There is a shim layer on the chaincode container to handle the message protocol between the chaincode and the validating peer using protobuf message. -``` -message ChaincodeMessage { - - enum Type { - UNDEFINED = 0; - REGISTER = 1; - REGISTERED = 2; - INIT = 3; - READY = 4; - TRANSACTION = 5; - COMPLETED = 6; - ERROR = 7; - GET_STATE = 8; - PUT_STATE = 9; - DEL_STATE = 10; - INVOKE_CHAINCODE = 11; - INVOKE_QUERY = 12; - RESPONSE = 13; - QUERY = 14; - QUERY_COMPLETED = 15; - QUERY_ERROR = 16; - GET_STATE_BY_RANGE = 17; - } - - Type type = 1; - google.protobuf.Timestamp timestamp = 2; - bytes payload = 3; - string uuid = 4; -} -``` - -**Definition of fields:** -- `Type` is the type of the message. -- `payload` is the payload of the message. Each payload depends on the `Type`. -- `uuid` is a unique identifier of the message. - -The message types are described in the following sub-sections. - -A chaincode implements the `Chaincode` interface, which is called by the validating peer when it processes Deploy, Invoke or Query transactions. - -``` -type Chaincode interface { -i Init(stub *ChaincodeStub, function string, args []string) ([]byte, error) - Invoke(stub *ChaincodeStub, function string, args []string) ([]byte, error) - Query(stub *ChaincodeStub, function string, args []string) ([]byte, error) -} -``` - -`Init`, `Invoke` and `Query` functions take `function` and `args` as parameters to be used by those methods to support a variety of transactions. `Init` is a constructor function, which will only be invoked by the Deploy transaction. The `Query` function is not allowed to modify the state of the chaincode; it can only read and calculate the return value as a byte array. - -##### 3.3.2.1 Chaincode Deploy -Upon deploy (chaincode container is started), the shim layer sends a one time `REGISTER` message to the validating peer with the `payload` containing the `ChaincodeID`. The validating peer responds with `REGISTERED` or `ERROR` on success or failure respectively. The shim closes the connection and exits if it receives an `ERROR`. - -After registration, the validating peer sends `INIT` with the `payload` containing a `ChaincodeInput` object. The shim calls the `Init` function with the parameters from the `ChaincodeInput`, enabling the chaincode to perform any initialization, such as setting up the persistent state. - -The shim responds with `RESPONSE` or `ERROR` message depending on the returned value from the chaincode `Init` function. If there are no errors, the chaincode initialization is complete and is ready to receive Invoke and Query transactions. - -##### 3.3.2.2 Chaincode Invoke -When processing an invoke transaction, the validating peer sends a `TRANSACTION` message to the chaincode container shim, which in turn calls the chaincode `Invoke` function, passing the parameters from the `ChaincodeInput` object. The shim responds to the validating peer with `RESPONSE` or `ERROR` message, indicating the completion of the function. If `ERROR` is received, the `payload` contains the error message generated by the chaincode. - -##### 3.3.2.3 Chaincode Query -Similar to an invoke transaction, when processing a query, the validating peer sends a `QUERY` message to the chaincode container shim, which in turn calls the chaincode `Query` function, passing the parameters from the `ChaincodeInput` object. The `Query` function may return a state value or an error, which the shim forwards to the validating peer using `RESPONSE` or `ERROR` messages respectively. - -##### 3.3.2.4 Chaincode State -Each chaincode may define its own persistent state variables. For example, a chaincode may create assets such as TVs, cars, or stocks using state variables to hold the assets attributes. During `Invoke` function processing, the chaincode may update the state variables, for example, changing an asset owner. A chaincode manipulates the state variables by using the following message types: - -###### PUT_STATE -Chaincode sends a `PUT_STATE` message to persist a key-value pair, with the `payload` containing `PutStateInfo` object. - -``` -message PutStateInfo { - string key = 1; - bytes value = 2; -} -``` - -###### GET_STATE -Chaincode sends a `GET_STATE` message to retrieve the value whose key is specified in the `payload`. - -###### DEL_STATE -Chaincode sends a `DEL_STATE` message to delete the value whose key is specified in the `payload`. - -###### GET_STATE_BY_RANGE -Chaincode sends a `GET_STATE_BY_RANGE` message to get a range of values. The message `payload` contains a `GetStateByRangeInfo` object. - -``` -message GetStateByRange { - string startKey = 1; - string endKey = 2; -} -``` - -The `startKey` and `endKey` are inclusive and assumed to be in lexical order. The validating peer responds with `RESPONSE` message whose `payload` is a `GetStateByRangeResponse` object. - -``` -message GetStateByRangeResponse { - repeated GetStateByRangeKeyValue keysAndValues = 1; - bool hasMore = 2; - string ID = 3; -} -message GetStateByRangeKeyValue { - string key = 1; - bytes value = 2; -} -``` - -If `hasMore=true` in the response, this indicates that additional keys are available in the requested range. The chaincode can request the next set of keys and values by sending a `GetStateByRangeNext` message with an ID that matches the ID returned in the response. - -``` -message GetStateByRangeNext { - string ID = 1; -} -``` - -When the chaincode is finished reading from the range, it should send a `GetStateByRangeClose` message with the ID it wishes to close. - -``` -message GetStateByRangeClose { - string ID = 1; -} -``` - -###### INVOKE_CHAINCODE -Chaincode may call another chaincode in the same transaction context by sending an `INVOKE_CHAINCODE` message to the validating peer with the `payload` containing a `ChaincodeSpec` object. - -###### QUERY_CHAINCODE -Chaincode may query another chaincode in the same transaction context by sending a `QUERY_CHAINCODE` message with the `payload` containing a `ChaincodeSpec` object. - - -### 3.4 Pluggable Consensus Framework - -The consensus framework defines the interfaces that every consensus _plugin_ implements: - - - `consensus.Consenter`: interface that allows consensus plugin to receive messages from the network. - - `consensus.CPI`: _Consensus Programming Interface_ (`CPI`) is used by consensus plugin to interact with rest of the stack. This interface is split in two parts: - - `consensus.Communicator`: used to send (broadcast and unicast) messages to other validating peers. - - `consensus.LedgerStack`: which is used as an interface to the execution framework as well as the ledger. - -As described below in more details, `consensus.LedgerStack` encapsulates, among other interfaces, the `consensus.Executor` interface, which is the key part of the consensus framework. Namely, `consensus.Executor` interface allows for a (batch of) transaction to be started, executed, rolled back if necessary, previewed, and potentially committed. A particular property that every consensus plugin needs to satisfy is that batches (blocks) of transactions are committed to the ledger (via `consensus.Executor.CommitTxBatch`) in total order across all validating peers (see `consensus.Executor` interface description below for more details). - -Currently, consensus framework consists of 3 packages `consensus`, `controller`, and `helper`. The primary reason for `controller` and `helper` packages is to avoid "import cycle" in Go (golang) and minimize code changes for plugin to update. - -- `controller` package specifies the consensus plugin used by a validating peer. -- `helper` package is a shim around a consensus plugin that helps it interact with the rest of the stack, such as maintaining message handlers to other peers. - -There are 2 consensus plugins provided: `pbft` and `noops`: - -- `pbft` package contains consensus plugin that implements the *PBFT* [1] consensus protocol. See section 5 for more detail. -- `noops` is a ''dummy'' consensus plugin for development and test purposes. It doesn't perform consensus but processes all consensus messages. It also serves as a good simple sample to start learning how to code a consensus plugin. - - -#### 3.4.1 `Consenter` interface - -Definition: -``` -type Consenter interface { - RecvMsg(msg *pb.Message) error -} -``` -The plugin's entry point for (external) client requests, and consensus messages generated internally (i.e. from the consensus module) during the consensus process. The `controller.NewConsenter` creates the plugin `Consenter`. `RecvMsg` processes the incoming transactions in order to reach consensus. - -See `helper.HandleMessage` below to understand how the peer interacts with this interface. - -#### 3.4.2 `CPI` interface - -Definition: -``` -type CPI interface { - Inquirer - Communicator - SecurityUtils - LedgerStack -} -``` -`CPI` allows the plugin to interact with the stack. It is implemented by the `helper.Helper` object. Recall that this object: - - 1. Is instantiated when the `helper.NewConsensusHandler` is called. - 2. Is accessible to the plugin author when they construct their plugin's `consensus.Consenter` object. - -#### 3.4.3 `Inquirer` interface - -Definition: -``` -type Inquirer interface { - GetNetworkInfo() (self *pb.PeerEndpoint, network []*pb.PeerEndpoint, err error) - GetNetworkHandles() (self *pb.PeerID, network []*pb.PeerID, err error) -} -``` -This interface is a part of the `consensus.CPI` interface. It is used to get the handles of the validating peers in the network (`GetNetworkHandles`) as well as details about the those validating peers (`GetNetworkInfo`): - -Note that the peers are identified by a `pb.PeerID` object. This is a protobuf message (in the `protos` package), currently defined as (notice that this definition will likely be modified): - -``` -message PeerID { - string name = 1; -} -``` - -#### 3.4.4 `Communicator` interface - -Definition: - -``` -type Communicator interface { - Broadcast(msg *pb.Message) error - Unicast(msg *pb.Message, receiverHandle *pb.PeerID) error -} -``` - -This interface is a part of the `consensus.CPI` interface. It is used to communicate with other peers on the network (`helper.Broadcast`, `helper.Unicast`): - -#### 3.4.5 `SecurityUtils` interface - -Definition: - -``` -type SecurityUtils interface { - Sign(msg []byte) ([]byte, error) - Verify(peerID *pb.PeerID, signature []byte, message []byte) error -} -``` - -This interface is a part of the `consensus.CPI` interface. It is used to handle the cryptographic operations of message signing (`Sign`) and verifying signatures (`Verify`) - -#### 3.4.6 `LedgerStack` interface - -Definition: - -``` -type LedgerStack interface { - Executor - Ledger - RemoteLedgers -} -``` - -A key member of the `CPI` interface, `LedgerStack` groups interaction of consensus with the rest of the fabric, such as the execution of transactions, querying, and updating the ledger. This interface supports querying the local blockchain and state, updating the local blockchain and state, and querying the blockchain and state of other nodes in the consensus network. It consists of three parts: `Executor`, `Ledger` and `RemoteLedgers` interfaces. These are described in the following. - -#### 3.4.7 `Executor` interface - -Definition: - -``` -type Executor interface { - BeginTxBatch(id interface{}) error - ExecTXs(id interface{}, txs []*pb.Transaction) ([]byte, []error) - CommitTxBatch(id interface{}, transactions []*pb.Transaction, transactionsResults []*pb.TransactionResult, metadata []byte) error - RollbackTxBatch(id interface{}) error - PreviewCommitTxBatchBlock(id interface{}, transactions []*pb.Transaction, metadata []byte) (*pb.Block, error) -} -``` - -The executor interface is the most frequently utilized portion of the `LedgerStack` interface, and is the only piece which is strictly necessary for a consensus network to make progress. The interface allows for a transaction to be started, executed, rolled back if necessary, previewed, and potentially committed. This interface is comprised of the following methods. - -##### 3.4.7.1 Beginning a transaction batch - -``` -BeginTxBatch(id interface{}) error -``` - -This call accepts an arbitrary `id`, deliberately opaque, as a way for the consensus plugin to ensure only the transactions associated with this particular batch are executed. For instance, in the pbft implementation, this `id` is the an encoded hash of the transactions to be executed. - -##### 3.4.7.2 Executing transactions - -``` -ExecTXs(id interface{}, txs []*pb.Transaction) ([]byte, []error) -``` - -This call accepts an array of transactions to execute against the current state of the ledger and returns the current state hash in addition to an array of errors corresponding to the array of transactions. Note that a transaction resulting in an error has no effect on whether a transaction batch is safe to commit. It is up to the consensus plugin to determine the behavior which should occur when failing transactions are encountered. This call is safe to invoke multiple times. - -##### 3.4.7.3 Committing and rolling-back transactions - -``` -RollbackTxBatch(id interface{}) error -``` - -This call aborts an execution batch. This will undo the changes to the current state, and restore the ledger to its previous state. It concludes the batch begun with `BeginBatchTx` and a new one must be created before executing any transactions. - -``` -PreviewCommitTxBatchBlock(id interface{}, transactions []*pb.Transaction, metadata []byte) (*pb.Block, error) -``` - -This call is most useful for consensus plugins which wish to test for non-deterministic transaction execution. The hashable portions of the block returned are guaranteed to be identical to the block which would be committed if `CommitTxBatch` were immediately invoked. This guarantee is violated if any new transactions are executed. - -``` -CommitTxBatch(id interface{}, transactions []*pb.Transaction, transactionsResults []*pb.TransactionResult, metadata []byte) error -``` - -This call commits a block to the blockchain. Blocks must be committed to a blockchain in total order. ``CommitTxBatch`` concludes the transaction batch, and a new call to `BeginTxBatch` must be made before any new transactions are executed and committed. - - -#### 3.4.8 `Ledger` interface - -Definition: - -``` -type Ledger interface { - ReadOnlyLedger - UtilLedger - WritableLedger -} -``` - -``Ledger`` interface is intended to allow the consensus plugin to interrogate and possibly update the current state and blockchain. It is comprised of the three interfaces described below. - -##### 3.4.8.1 `ReadOnlyLedger` interface - -Definition: - -``` -type ReadOnlyLedger interface { - GetBlock(id uint64) (block *pb.Block, err error) - GetCurrentStateHash() (stateHash []byte, err error) - GetBlockchainSize() (uint64, error) -} -``` - -`ReadOnlyLedger` interface is intended to query the local copy of the ledger without the possibility of modifying it. It is comprised of the following functions. - -``` -GetBlockchainSize() (uint64, error) -``` - -This call returns the current length of the blockchain ledger. In general, this function should never fail, though in the unlikely event that this occurs, the error is passed to the caller to decide what if any recovery is necessary. The block with the highest number will have block number `GetBlockchainSize()-1`. - -Note that in the event that the local copy of the blockchain ledger is corrupt or incomplete, this call will return the highest block number in the chain, plus one. This allows for a node to continue operating from the current state/block even when older blocks are corrupt or missing. - -``` -GetBlock(id uint64) (block *pb.Block, err error) -``` - -This call returns the block from the blockchain with block number `id`. In general, this call should not fail, except when the block queried exceeds the current blocklength, or when the underlying blockchain has somehow become corrupt. A failure of `GetBlock` has a possible resolution of using the state transfer mechanism to retrieve it. - - -``` -GetCurrentStateHash() (stateHash []byte, err error) -``` - -This call returns the current state hash for the ledger. In general, this function should never fail, though in the unlikely event that this occurs, the error is passed to the caller to decide what if any recovery is necessary. - - -##### 3.4.8.2 `UtilLedger` interface - -Definition: - -``` -type UtilLedger interface { - HashBlock(block *pb.Block) ([]byte, error) - VerifyBlockchain(start, finish uint64) (uint64, error) -} -``` - -`UtilLedger` interface defines some useful utility functions which are provided by the local ledger. Overriding these functions in a mock interface can be useful for testing purposes. This interface is comprised of two functions. - -``` -HashBlock(block *pb.Block) ([]byte, error) -``` - -Although `*pb.Block` has a `GetHash` method defined, for mock testing, overriding this method can be very useful. Therefore, it is recommended that the `GetHash` method never be directly invoked, but instead invoked via this `UtilLedger.HashBlock` interface. In general, this method should never fail, but the error is still passed to the caller to decide what if any recovery is appropriate. - -``` -VerifyBlockchain(start, finish uint64) (uint64, error) -``` - -This utility method is intended for verifying large sections of the blockchain. It proceeds from a high block `start` to a lower block `finish`, returning the block number of the first block whose `PreviousBlockHash` does not match the block hash of the previous block as well as an error. Note, this generally indicates the last good block number, not the first bad block number. - - - -##### 3.4.8.3 `WritableLedger` interface - -Definition: - -``` -type WritableLedger interface { - PutBlock(blockNumber uint64, block *pb.Block) error - ApplyStateDelta(id interface{}, delta *statemgmt.StateDelta) error - CommitStateDelta(id interface{}) error - RollbackStateDelta(id interface{}) error - EmptyState() error -} -``` - -`WritableLedger` interface allows for the caller to update the blockchain. Note that this is _NOT_ intended for use in normal operation of a consensus plugin. The current state should be modified by executing transactions using the `Executor` interface, and new blocks will be generated when transactions are committed. This interface is instead intended primarily for state transfer or corruption recovery. In particular, functions in this interface should _NEVER_ be exposed directly via consensus messages, as this could result in violating the immutability promises of the blockchain concept. This interface is comprised of the following functions. - - - - ``` - PutBlock(blockNumber uint64, block *pb.Block) error - ``` - - This function takes a provided, raw block, and inserts it into the blockchain at the given blockNumber. Note that this intended to be an unsafe interface, so no error or sanity checking is performed. Inserting a block with a number higher than the current block height is permitted, similarly overwriting existing already committed blocks is also permitted. Remember, this does not affect the auditability or immutability of the chain, as the hashing techniques make it computationally infeasible to forge a block earlier in the chain. Any attempt to rewrite the blockchain history is therefore easily detectable. This is generally only useful to the state transfer API. - - - - ``` - ApplyStateDelta(id interface{}, delta *statemgmt.StateDelta) error - ``` - - This function takes a state delta, and applies it to the current state. The delta will be applied to transition a state forward or backwards depending on the construction of the state delta. Like the `Executor` methods, `ApplyStateDelta` accepts an opaque interface `id` which should also be passed into `CommitStateDelta` or `RollbackStateDelta` as appropriate. - - - - ``` - CommitStateDelta(id interface{}) error - ``` - - This function commits the state delta which was applied in `ApplyStateDelta`. This is intended to be invoked after the caller to `ApplyStateDelta` has verified the state via the state hash obtained via `GetCurrentStateHash()`. This call takes the same `id` which was passed into `ApplyStateDelta`. - - - - ``` - RollbackStateDelta(id interface{}) error - ``` - - This function unapplies a state delta which was applied in `ApplyStateDelta`. This is intended to be invoked after the caller to `ApplyStateDelta` has detected the state hash obtained via `GetCurrentStateHash()` is incorrect. This call takes the same `id` which was passed into `ApplyStateDelta`. - - - - - ``` - EmptyState() error - ``` - - This function will delete the entire current state, resulting in a pristine empty state. It is intended to be called before loading an entirely new state via deltas. This is generally only useful to the state transfer API. - -#### 3.4.9 `RemoteLedgers` interface - -Definition: - -``` -type RemoteLedgers interface { - GetRemoteBlocks(peerID uint64, start, finish uint64) (<-chan *pb.SyncBlocks, error) - GetRemoteStateSnapshot(peerID uint64) (<-chan *pb.SyncStateSnapshot, error) - GetRemoteStateDeltas(peerID uint64, start, finish uint64) (<-chan *pb.SyncStateDeltas, error) -} -``` - -The `RemoteLedgers` interface exists primarily to enable state transfer and to interrogate the blockchain state at other replicas. Just like the `WritableLedger` interface, it is not intended to be used in normal operation and is designed to be used for catchup, error recovery, etc. For all functions in this interface it is the caller's responsibility to enforce timeouts. This interface contains the following functions. - - - - ``` - GetRemoteBlocks(peerID uint64, start, finish uint64) (<-chan *pb.SyncBlocks, error) - ``` - - This function attempts to retrieve a stream of `*pb.SyncBlocks` from the peer designated by `peerID` for the range from `start` to `finish`. In general, `start` should be specified with a higher block number than `finish`, as the blockchain must be validated from end to beginning. The caller must validate that the desired block is being returned, as it is possible that slow results from another request could appear on this channel. Invoking this call for the same `peerID` a second time will cause the first channel to close. - - - - ``` - GetRemoteStateSnapshot(peerID uint64) (<-chan *pb.SyncStateSnapshot, error) - ``` - - This function attempts to retrieve a stream of `*pb.SyncStateSnapshot` from the peer designated by `peerID`. To apply the result, the existing state should first be emptied via the `WritableLedger` `EmptyState` call, then the contained deltas in the stream should be applied sequentially. - - - - ``` - GetRemoteStateDeltas(peerID uint64, start, finish uint64) (<-chan *pb.SyncStateDeltas, error) - ``` - - This function attempts to retrieve a stream of `*pb.SyncStateDeltas` from the peer designated by `peerID` for the range from `start` to `finish`. The caller must validated that the desired block delta is being returned, as it is possible that slow results from another request could appear on this channel. Invoking this call for the same `peerID` a second time will cause the first channel to close. - -#### 3.4.10 `controller` package - -##### 3.4.10.1 controller.NewConsenter - -Signature: - -``` -func NewConsenter(cpi consensus.CPI) (consenter consensus.Consenter) -``` - -This function reads the `peer.validator.consensus` value in `core.yaml` configuration file, which is the configuration file for the `peer` process. The value of the `peer.validator.consensus` key defines whether the validating peer will run with the `noops` consensus plugin or the `pbft` one. (Notice that this should eventually be changed to either `noops` or `custom`. In case of `custom`, the validating peer will run with the consensus plugin defined in `consensus/config.yaml`.) - -The plugin author needs to edit the function's body so that it routes to the right constructor for their package. For example, for `pbft` we point to the `pbft.GetPlugin` constructor. - -This function is called by `helper.NewConsensusHandler` when setting the `consenter` field of the returned message handler. The input argument `cpi` is the output of the `helper.NewHelper` constructor and implements the `consensus.CPI` interface. - -#### 3.4.11 `helper` package - -##### 3.4.11.1 High-level overview - -A validating peer establishes a message handler (`helper.ConsensusHandler`) for every connected peer, via the `helper.NewConsensusHandler` function (a handler factory). Every incoming message is inspected on its type (`helper.HandleMessage`); if it's a message for which consensus needs to be reached, it's passed on to the peer's consenter object (`consensus.Consenter`). Otherwise it's passed on to the next message handler in the stack. - -##### 3.4.11.2 helper.ConsensusHandler - -Definition: - -``` -type ConsensusHandler struct { - chatStream peer.ChatStream - consenter consensus.Consenter - coordinator peer.MessageHandlerCoordinator - done chan struct{} - peerHandler peer.MessageHandler -} -``` - -Within the context of consensus, we focus only on the `coordinator` and `consenter` fields. The `coordinator`, as the name implies, is used to coordinate between the peer's message handlers. This is, for instance, the object that is accessed when the peer wishes to `Broadcast`. The `consenter` receives the messages for which consensus needs to be reached and processes them. - -Notice that `fabric/peer/peer.go` defines the `peer.MessageHandler` (interface), and `peer.MessageHandlerCoordinator` (interface) types. - -##### 3.4.11.3 helper.NewConsensusHandler - -Signature: - -``` -func NewConsensusHandler(coord peer.MessageHandlerCoordinator, stream peer.ChatStream, initiatedStream bool, next peer.MessageHandler) (peer.MessageHandler, error) -``` - -Creates a `helper.ConsensusHandler` object. Sets the same `coordinator` for every message handler. Also sets the `consenter` equal to: `controller.NewConsenter(NewHelper(coord))` - -##### 3.4.11.4 helper.Helper - -Definition: - -``` -type Helper struct { - coordinator peer.MessageHandlerCoordinator -} -``` - -Contains the reference to the validating peer's `coordinator`. Is the object that implements the `consensus.CPI` interface for the peer. - -##### 3.4.11.5 helper.NewHelper - -Signature: - -``` -func NewHelper(mhc peer.MessageHandlerCoordinator) consensus.CPI -``` - -Returns a `helper.Helper` object whose `coordinator` is set to the input argument `mhc` (the `coordinator` field of the `helper.ConsensusHandler` message handler). This object implements the `consensus.CPI` interface, thus allowing the plugin to interact with the stack. - - -##### 3.4.11.6 helper.HandleMessage - -Recall that the `helper.ConsensusHandler` object returned by `helper.NewConsensusHandler` implements the `peer.MessageHandler` interface: - -``` -type MessageHandler interface { - RemoteLedger - HandleMessage(msg *pb.Message) error - SendMessage(msg *pb.Message) error - To() (pb.PeerEndpoint, error) - Stop() error -} -``` - -Within the context of consensus, we focus only on the `HandleMessage` method. Signature: - -``` -func (handler *ConsensusHandler) HandleMessage(msg *pb.Message) error -``` - -The function inspects the `Type` of the incoming `Message`. There are four cases: - - 1. Equal to `pb.Message_CONSENSUS`: passed to the handler's `consenter.RecvMsg` function. - 2. Equal to `pb.Message_CHAIN_TRANSACTION` (i.e. an external deployment request): a response message is sent to the user first, then the message is passed to the `consenter.RecvMsg` function. - 3. Equal to `pb.Message_CHAIN_QUERY` (i.e. a query): passed to the `helper.doChainQuery` method so as to get executed locally. - 4. Otherwise: passed to the `HandleMessage` method of the next handler down the stack. - - -### 3.5 Events -The event framework provides the ability to generate and consume predefined and custom events. There are 3 basic components: - - Event stream - - Event adapters - - Event structures - -#### 3.5.1 Event Stream -An event stream is a gRPC channel capable of sending and receiving events. Each consumer establishes an event stream to the event framework and expresses the events that it is interested in. the event producer only sends appropriate events to the consumers who have connected to the producer over the event stream. - -The event stream initializes the buffer and timeout parameters. The buffer holds the number of events waiting for delivery, and the timeout has 3 options when the buffer is full: - -- If timeout is less than 0, drop the newly arriving events -- If timeout is 0, block on the event until the buffer becomes available -- If timeout is greater than 0, wait for the specified timeout and drop the event if the buffer remains full after the timeout - - -##### 3.5.1.1 Event Producer -The event producer exposes a function to send an event, `Send(e *pb.Event)`, where `Event` is either a pre-defined `Block` or a `Generic` event. More events will be defined in the future to include other elements of the fabric. - -``` -message Generic { - string eventType = 1; - bytes payload = 2; -} -``` - -The `eventType` and `payload` are freely defined by the event producer. For example, JSON data may be used in the `payload`. The `Generic` event may also be emitted by the chaincode or plugins to communicate with consumers. - -##### 3.5.1.2 Event Consumer -The event consumer enables external applications to listen to events. Each event consumer registers an event adapter with the event stream. The consumer framework can be viewed as a bridge between the event stream and the adapter. A typical use of the event consumer framework is: - -``` -adapter = -consumerClient = NewEventsClient(, adapter) -consumerClient.Start() -... -... -consumerClient.Stop() -``` - -#### 3.5.2 Event Adapters -The event adapter encapsulates three facets of event stream interaction: - - an interface that returns the list of all events of interest - - an interface called by the event consumer framework on receipt of an event - - an interface called by the event consumer framework when the event bus terminates - -The reference implementation provides Golang specific language binding. -``` - EventAdapter interface { - GetInterestedEvents() ([]*ehpb.Interest, error) - Recv(msg *ehpb.Event) (bool,error) - Disconnected(err error) - } -``` -Using gRPC as the event bus protocol allows the event consumer framework to be ported to different language bindings without affecting the event producer framework. - -#### 3.5.3 Event Structure - -This section details the message structures of the event system. Messages are described directly in Golang for simplicity. - -The core message used for communication between the event consumer and producer is the Event. -``` - message Event { - oneof Event { - //consumer events - Register register = 1; - - //producer events - Block block = 2; - Generic generic = 3; - } - } -``` -Per the above definition, an event has to be one of `Register`, `Block` or `Generic`. - -As mentioned in the previous sections, a consumer creates an event bus by establishing a connection with the producer and sending a `Register` event. The `Register` event is essentially an array of `Interest` messages declaring the events of interest to the consumer. -``` - message Interest { - enum ResponseType { - //don't send events (used to cancel interest) - DONTSEND = 0; - //send protobuf objects - PROTOBUF = 1; - //marshall into JSON structure - JSON = 2; - } - string eventType = 1; - ResponseType responseType = 2; - } -``` -Events can be sent directly as protobuf structures or can be sent as JSON structures by specifying the `responseType` appropriately. - -Currently, the producer framework can generate a `Block` or a `Generic` event. A `Block` is a message used for encapsulating properties of a block in the blockchain. - - -## 4. Security - -This section discusses the setting depicted in the figure below. -In particular, the system consists of the following entities: -membership management infrastructure, i.e., a set of entities that are -responsible for identifying an individual user (using any form of identification -considered in the system, e.g., credit cards, id-cards), open an account for -that user to be able to register, and issue the necessary credentials to -successfully create transactions and deploy or invoke chaincode successfully -through the fabric. -![figure-architecture](./images/sec-sec-arch.png) - * Peers, that are classified as validating peers, and non-validating peers. - Validating peers (also known as validators) order and process (check validity, execute, - and add to the blockchain) user-messages (transactions) submitted to the network. - Non validating peers (also known as peers) receive user transactions on behalf of users, - and after some fundamental validity checks, they forward the transactions to their - neighboring validating peers. Peers maintain an up-to-date copy of the blockchain, - but in contradiction to validators, they do not execute transactions - (a process also known as *transaction validation*). - * End users of the system, that have registered to our membership service administration, - after having demonstrated ownership of what is considered *identity* in the system, - and have obtained credentials to install the client-software and submit transactions - to the system. - * Client-software, the software that needs to be installed at the client side for the - latter to be able to complete his registration to our membership service and submit - transactions to the system. - * Online wallets, entities that are trusted by a user to maintain that user's credentials, - and submit transactions solely upon user request to the network. Online wallets come - with their own software at the client-side, that is usually light-weight, as the - client only needs to authenticate himself and his requests to the wallet. - While it can be the case that peers can play the role of *online wallet* for a set of - users, in the following sessions the security of online wallets is detailed separately. - -Users who wish to make use of the fabric, open an account at the membership management -administration, by proving ownership of identity as discussed in previous sections, new chaincodes -are announced to the blockchain network by the chaincode creator (developer) through the means -of a deployment transaction that the client-software would construct on behalf of the developer. -Such transaction is first received by a peer or validator, and afterwards circulated -in the entire network of validators, this transaction is executed and finds its place to -the blockchain network. Users can also invoke a function of an already deployed chain-code -through an invocation transaction. - -The next section provides a summary of the business goals of the system that drive the security requirements. We then overview the security components and their operation and show how this design fulfills the security requirements. - -### 4.1 Business security requirements -This section presents business security requirements that are relevant to the context of the fabric. -**Incorporation of identity and role management.** - -In order to adequately support real business applications it is necessary to progress beyond ensuring cryptographic continuity. A workable B2B system must consequently move towards addressing proven/demonstrated identities or other attributes relevant to conducting business. Business transactions and consumer interactions with financial institutions need to be unambiguously mapped to account holders. Business contracts typically require demonstrable affiliation with specific institutions and/or possession of other specific properties of transacting parties. Accountability and non-frameability are two reasons that identity management is a critical component of such systems. - -Accountability means that users of the system, individuals, or corporations, who misbehave can be traced back and be set accountable for their actions. In many cases, members of a B2B system are required to use their identities (in some form) to participate in the system, in a way such that accountability is guaranteed. Accountability and non-frameability are both essential security requirements in B2B systems and they are closely related. That is, a B2B system should guarantee that an honest user of such system cannot be framed to be accused as responsible for transactions originated by other users. - -In addition a B2B system should be renewable and flexible in order to accommodate changes of participants’s roles and/or affiliations. - -**Transactional privacy.** - -In B2B relationships there is a strong need for transactional privacy, i.e., allowing the end-user of a system to control the degree to which it interacts and shares information with its environment. For example, a corporation doing business through a transactional B2B system requires that its transactions are not visible to other corporations or industrial partners that are not authorized to share classified information with. - - -Transactional privacy in the fabric is offered by the mechanisms to achieve two properties with respect to non authorized users: - -* Transaction anonymity, where the owner of a transaction is hidden among the so called *anonymity set*, which in the fabric, is the set of users. - -* Transaction unlinkability, where two or more transactions of the same user should not be linked as such. - -Clearly depending on the context, non-authorized users can be anyone outside the system, or a subset of users. - -Transactional privacy is strongly associated to the confidentiality of the content of a contractual agreement between two or more members of a B2B system, as well as to the anonymity and unlinkability of any authentication mechanism that should be in place within transactions. - -**Reconciling transactional privacy with identity management.** - -As described later in this document, the approach taken here to reconcile identity management with user privacy and to enable competitive institutions to transact effectively on a common blockchain (for both intra- and inter-institutional transactions) is as follows: - -1. add certificates to transactions to implement a “permissioned” blockchain - -2. utilize a two-level system: - - 1. (relatively) static enrollment certificates (ECerts), acquired via registration with an enrollment certificate authority (CA). - - 2. transaction certificates (TCerts) that faithfully but pseudonymously represent enrolled users, acquired via a transaction CA. - -3. offer mechanisms to conceal the content of transactions to unauthorized members of the system. - -**Audit support.** Commercial systems are occasionally subjected to audits. Auditors in such cases should be given the means to check a certain transaction, or a certain group of transactions, the activity of a particular user of the system, or the operation of the system itself. Thus, such capabilities should be offered by any system featuring transactions containing contractual agreements between business partners. - -### 4.2 User Privacy through Membership Services - -Membership Services consists of an infrastructure of several entities that together manage the identity and privacy of users on the network. These services validate user’s identity, register the user in the system, and provide all the credentials needed for him/her to be an active and compliant participant able to create and/or invoke transactions. A Public Key Infrastructure (PKI) is a framework based on public key cryptography that ensures not only the secure exchange of data over public networks but also affirms the identity of the other party. A PKI manages the generation, distribution and revocation of keys and digital certificates. Digital certificates are used to establish user credentials and to sign messages. Signing messages with a certificate ensures that the message has not been altered. Typically a PKI has a Certificate Authority (CA), a Registration Authority (RA), a certificate database, and a certificate storage. The RA is a trusted party that authenticates users and vets the legitimacy of data, certificates or other evidence submitted to support the user’s request for one or more certificates that reflect that user’s identity or other properties. A CA, upon advice from an RA, issues digital certificates for specific uses and is certified directly or hierarchically by a root CA. Alternatively, the user-facing communications and due diligence responsibilities of the RA can be subsumed as part of the CA. Membership Services is composed of the entities shown in the following figure. Introduction of such full PKI reinforces the strength of this system for B2B (over, e.g. Bitcoin). - -![Figure 1](./images/sec-memserv-components.png) - -*Root Certificate Authority (Root CA):* entity that represents the trust anchor for the PKI scheme. Digital certificates verification follows a chain of trust. The Root CA is the top-most CA in the PKI hierarchy. - -*Registration Authority (RA):* a trusted entity that can ascertain the validity and identity of users who want to participate in the permissioned blockchain. It is responsible for out-of-band communication with the user to validate his/her identity and role. It creates registration credentials needed for enrollment and information on root of trust. - -*Enrollment Certificate Authority (ECA):* responsible for issuing Enrollment Certificates (ECerts) after validating the registration credentials provided by the user. - -*Transaction Certificate Authority (TCA):* responsible for issuing Transaction Certificates (TCerts) after validating the enrollment credentials provided by the user. - -*TLS Certificate Authority (TLS-CA):* responsible for issuing TLS certificates and credentials that allow the user to make use of its network. It validates the credential(s) or evidence provided by the user that justifies issuance of a TLS certificate that includes specific information pertaining to the user. - -In this specification, membership services is expressed through the following associated certificates issued by the PKI: - -*Enrollment Certificates (ECerts)* -ECerts are long-term certificates. They are issued for all roles, i.e. users, non-validating peers, and validating peers. In the case of users, who submit transactions for candidate incorporation into the blockchain and who also own TCerts (discussed below), there are two possible structure and usage models for ECerts: - - * Model A: ECerts contain the identity/enrollmentID of their owner and can be used to offer only nominal entity-authentication for TCert requests and/or within transactions. They contain the public part of two key pairs – a signature key-pair and an encryption/key agreement key-pair. ECerts are accessible to everyone. - - * Model B: ECerts contain the identity/enrollmentID of their owner and can be used to offer only nominal entity-authentication for TCert requests. They contain the public part of a signature key-pair, i.e., a signature verification public key. ECerts are preferably accessible to only TCA and auditors, as relying parties. They are invisible to transactions, and thus (unlike TCerts) their signature key pairs do not play a non-repudiation role at that level. - -*Transaction Certificates (TCerts)* -TCerts are short-term certificates for each transaction. They are issued by the TCA upon authenticated user-request. They securely authorize a transaction and may be configured to not reveal the identities of who is involved in the transaction or to selectively reveal such identity/enrollmentID information. They include the public part of a signature key-pair, and may be configured to also include the public part of a key agreement key pair. They are issued only to users. They are uniquely associated to the owner – they may be configured so that this association is known only by the TCA (and to authorized auditors). TCerts may be configured to not carry information of the identity of the user. They enable the user not only to anonymously participate in the system but also prevent linkability of transactions. - -However, auditability and accountability requirements assume that the TCA is able to retrieve TCerts of a given identity, or retrieve the owner of a specific TCert. For details on how TCerts are used in deployment and invocation transactions see Section 4.3, Transaction Security offerings at the infrastructure level. - -TCerts can accommodate encryption or key agreement public keys (as well as digital signature verification public keys). -If TCerts are thus equipped, then enrollment certificates need not also contain encryption or key agreement public keys. - -Such a key agreement public key, Key_Agreement_TCertPub_Key, can be generated by the transaction certificate authority (TCA) using a method that is the same as that used to generate the Signature_Verification_TCertPub_Key, but using an index value of TCertIndex + 1 rather than TCertIndex, where TCertIndex is hidden within the TCert by the TCA for recovery by the TCert owner. - -The structure of a Transaction Certificate (TCert) is as follows: -* TCertID – transaction certificate ID (preferably generated by TCA randomly in order to avoid unintended linkability via the Hidden Enrollment ID field). -* Hidden Enrollment ID: AES_EncryptK(enrollmentID), where key K = [HMAC(Pre-K, TCertID)]256-bit truncation and where three distinct key distribution scenarios for Pre-K are defined below as (a), (b) and (c). -* Hidden Private Keys Extraction: AES_EncryptTCertOwner_EncryptKey(TCertIndex || known padding/parity check vector) where || denotes concatenation, and where each batch has a unique (per batch) time-stamp/random offset that is added to a counter (initialized at 1 in this implementation) in order to generate TCertIndex. The counter can be incremented by 2 each time in order to accommodate generation by the TCA of the public keys and recovery by the TCert owner of the private keys of both types, i.e., signature key pairs and key agreement key pairs. -* Sign Verification Public Key – TCert signature verification public key. -* Key Agreement Public Key – TCert key agreement public key. -* Validity period – the time window during which the transaction certificate can be used for the outer/external signature of a transaction. - -There are at least three useful ways to consider configuring the key distribution scenario for the Hidden Enrollment ID field: -*(a)* Pre-K is distributed during enrollment to user clients, peers and auditors, and is available to the TCA and authorized auditors. It may, for example, be derived from Kchain (described subsequently in this specification) or be independent of key(s) used for chaincode confidentiality. - -*(b)* Pre-K is available to validators, the TCA and authorized auditors. K is made available by a validator to a user (under TLS) in response to a successful query transaction. The query transaction can have the same format as the invocation transaction. Corresponding to Example 1 below, the querying user would learn the enrollmentID of the user who created the Deployment Transaction if the querying user owns one of the TCerts in the ACL of the Deployment Transaction. Corresponding to Example 2 below, the querying user would learn the enrollmentID of the user who created the Deployment Transaction if the enrollmentID of the TCert used to query matches one of the affiliations/roles in the Access Control field of the Deployment Transaction. - -*Example 1:* - -![Example 1](./images/sec-example-1.png) - -*Example 2:* - -![Example 2](./images/sec-example-2.png) - -*(c)* Pre-K is available to the TCA and authorized auditors. The TCert-specific K can be distributed the TCert owner (under TLS) along with the TCert, for each TCert in the batch. This enables targeted release by the TCert owner of K (and thus trusted notification of the TCert owner’s enrollmentID). Such targeted release can use key agreement public keys of the intended recipients and/or PKchain where SKchain is available to validators as described subsequently in this specification. Such targeted release to other contract participants can be incorporated into a transaction or done out-of-band. - -If the TCerts are used in conjunction with ECert Model A above, then using (c) where K is not distributed to the TCert owner may suffice. -If the TCerts are used in conjunction with ECert Model A above, then the Key Agreement Public Key field of the TCert may not be necessary. - -The Transaction Certificate Authority (TCA) returns TCerts in batches, each batch contains the KeyDF_Key (Key-Derivation-Function Key) which is not included within every TCert but delivered to the client with the batch of TCerts (using TLS). The KeyDF_Key allows the TCert owner to derive TCertOwner_EncryptKey which in turn enables recovery of TCertIndex from AES_EncryptTCertOwner_EncryptKey(TCertIndex || known padding/parity check vector). - -*TLS-Certificates (TLS-Certs)* -TLS-Certs are certificates used for system/component-to-system/component communications. They carry the identity of their owner and are used for network level security. - -This implementation of membership services provides the following basic functionality: there is no expiration/revocation of ECerts; expiration of TCerts is provided via the validity period time window; there is no revocation of TCerts. The ECA, TCA, and TLS CA certificates are self-signed, where the TLS CA is provisioned as a trust anchor. - -#### 4.2.1 User/Client Enrollment Process - -The next figure has a high-level description of the user enrollment process. It has an offline and an online phase. - -![Registration](./images/sec-registration-high-level.png) - -*Offline Process:* in Step 1, each user/non-validating peer/validating peer has to present strong identification credentials (proof of ID) to a Registration Authority (RA) offline. This has to be done out-of-band to provide the evidence needed by the RA to create (and store) an account for the user. In Step 2, the RA returns the associated username/password and trust anchor (TLS-CA Cert in this implementation) to the user. If the user has access to a local client then this is one way the client can be securely provisioned with the TLS-CA certificate as trust anchor. - -*Online Phase:* In Step 3, the user connects to the client to request to be enrolled in the system. The user sends his username and password to the client. On behalf of the user, the client sends the request to the PKI framework, Step 4, and receives a package, Step 5, containing several certificates, some of which should correspond to private/secret keys held by the client. Once the client verifies that the all the crypto material in the package is correct/valid, it stores the certificates in local storage and notifies the user. At this point the user enrollment has been completed. - -![Figure 4](./images/sec-registration-detailed.png) - -Figure 4 shows a detailed description of the enrollment process. The PKI framework has the following entities – RA, ECA, TCA and TLS-CA. After Step 1, the RA calls the function “AddEntry” to enter the (username/password) in its database. At this point the user has been formally registered into the system database. The client needs the TLS-CA certificate (as trust anchor) to verify that the TLS handshake is set up appropriately with the server. In Step 4, the client sends the registration request to the ECA along with its enrollment public key and additional identity information such as username and password (under the TLS record layer protocol). The ECA verifies that such user really exists in the database. Once it establishes this assurance the user has the right to submit his/her enrollment public key and the ECA will certify it. This enrollment information is of a one-time use. The ECA updates the database marking that this registration request information (username/password) cannot be used again. The ECA constructs, signs and sends back to the client an enrollment certificate (ECert) that contains the user’s enrollment public key (Step 5). It also sends the ECA Certificate (ECA-Cert) needed in future steps (client will need to prove to the TCA that his/her ECert was created by the proper ECA). (Although the ECA-Cert is self-signed in the initial implementation, the TCA and TLS-CA and ECA are co-located.) The client verifies, in Step 6, that the public key inside the ECert is the one originally submitted by the client (i.e. that the ECA is not cheating). It also verifies that all the expected information within the ECert is present and properly formed. - -Similarly, In Step 7, the client sends a registration request to the TLS-CA along with its public key and identity information. The TLS-CA verifies that such user is in the database. The TLS-CA generates, and signs a TLS-Cert that contains the user’s TLS public key (Step 8). TLS-CA sends the TLS-Cert and its certificate (TLS-CA Cert). Step 9 is analogous to Step 6, the client verifies that the public key inside the TLS Cert is the one originally submitted by the client and that the information in the TLS Cert is complete and properly formed. In Step 10, the client saves all certificates in local storage for both certificates. At this point the user enrollment has been completed. - -In this implementation the enrollment process for validators is the same as that for peers. However, it is possible that a different implementation would have validators enroll directly through an on-line process. - -![Figure 5](./images/sec-request-tcerts-deployment.png) -![Figure 6](./images/sec-request-tcerts-invocation.png) - -*Client:* Request for TCerts batch needs to include (in addition to count), ECert and signature of request using ECert private key (where Ecert private key is pulled from Local Storage). - -*TCA generates TCerts for batch:* Generates key derivation function key, KeyDF_Key, as HMAC(TCA_KDF_Key, EnrollPub_Key). Generates each TCert public key (using TCertPub_Key = EnrollPub_Key + ExpansionValue G, where 384-bit ExpansionValue = HMAC(Expansion_Key, TCertIndex) and 384-bit Expansion_Key = HMAC(KeyDF_Key, “2”)). Generates each AES_EncryptTCertOwner_EncryptKey(TCertIndex || known padding/parity check vector), where || denotes concatenation and where TCertOwner_EncryptKey is derived as [HMAC(KeyDF_Key, “1”)]256-bit truncation. - -*Client:* Deriving TCert private key from a TCert in order to be able to deploy or invoke or query: KeyDF_Key and ECert private key need to be pulled from Local Storage. KeyDF_Key is used to derive TCertOwner_EncryptKey as [HMAC(KeyDF_Key, “1”)]256-bit truncation; then TCertOwner_EncryptKey is used to decrypt the TCert field AES_EncryptTCertOwner_EncryptKey(TCertIndex || known padding/parity check vector); then TCertIndex is used to derive TCert private key: TCertPriv_Key = (EnrollPriv_Key + ExpansionValue) modulo n, where 384-bit ExpansionValue = HMAC(Expansion_Key, TCertIndex) and 384-bit Expansion_Key = HMAC(KeyDF_Key, “2”). - -#### 4.2.2 Expiration and revocation of certificates - -It is practical to support expiration of transaction certificates. The time window during which a transaction certificate can be used is expressed by a ‘validity period’ field. The challenge regarding support of expiration lies in the distributed nature of the system. That is, all validating entities must share the same information; i.e. be consistent with respect to the expiration of the validity period associated with the transactions to be executed and validated. To guarantee that the expiration of validity periods is done in a consistent manner across all validators, the concept of validity period identifier is introduced. This identifier acts as a logical clock enabling the system to uniquely identify a validity period. At genesis time the “current validity period” of the chain gets initialized by the TCA. It is essential that this validity period identifier is given monotonically increasing values over time, such that it imposes a total order among validity periods. - -A special type of transactions, system transactions, and the validity period identified are used together to announce the expiration of a validity period to the Blockchain. System transactions refer to contracts that have been defined in the genesis block and are part of the infrastructure. The validity period identified is updated periodically by the TCA invoking a system chaincode. Note that only the TCA should be allowed to update the validity period. The TCA sets the validity period for each transaction certificate by setting the appropriate integer values in the following two fields that define a range: ‘not-before’ and ‘not-after’ fields. - -TCert Expiration: -At the time of processing a TCert, validators read from the state table associated with the ledger the value of ‘current validity period’ to check if the outer certificate associated with the transaction being evaluated is currently valid. That is, the current value in the state table has to be within the range defined by TCert sub-fields ‘not-before’ and ‘not-after’. If this is the case, the validator continues processing the transaction. In the case that the current value is not within range, the TCert has expired or is not yet valid and the validator should stop processing the transaction. - -ECert Expiration: -Enrollment certificates have different validity period length(s) than those in transaction certificates. - -Revocation is supported in the form of Certificate Revocation Lists (CRLs). CRLs identify revoked certificates. Changes to the CRLs, incremental differences, are announced through the Blockchain. - -### 4.3 Transaction security offerings at the infrastructure level - -Transactions in the fabric are user-messages submitted to be included -in the ledger. As discussed in previous sections, these messages have a -specific structure, and enable users to deploy new chaincodes, invoke existing -chaincodes, or query the state of existing chaincodes. -Therefore, the way transactions are formed, announced and processed plays -an important role to the privacy and security offerings of the entire system. - -On one hand our membership service provides the means to authenticate transactions as -having originated by valid users of the system, to disassociate transactions with user identities, -but while efficiently tracing the transactions a particular individual under certain conditions -(law enforcement, auditing). In other words, membership services offer to transactions authentication -mechanisms that marry user-privacy with accountability and non-repudiation. - -On the other hand, membership services alone cannot offer full privacy of user-activities within -the fabric. First of all, for privacy provisions offered by the fabric to be complete, -privacy-preserving authentication mechanisms need to be accompanied by transaction confidentiality. -This becomes clear if one considers that the content of a chaincode, may leak information on who may have -created it, and thus break the privacy of that chaincode's creator. The first subsection -discusses transaction confidentiality. - - - -Enforcing access control for the invocation of chaincode is an important security requirement. -The fabric exposes to the application (e.g., chaincode creator) the means for the application -to perform its own invocation access control, while leveraging the fabric's membership services. -Section 4.4 elaborates on this. - - - -Replay attacks is another crucial aspect of the security of the chaincode, -as a malicious user may copy a transaction that was added to the Blockchain -in the past, and replay it in the network to distort its operation. -This is the topic of Section 4.3.3. - -The rest of this Section presents an overview of how security mechanisms in the -infrastructure are incorporated in the transactions' lifecycle, -and details each security mechanism separately. - - -#### 4.3.1 Security Lifecycle of Transactions -Transactions are created on the client side. The client can be either plain -client, or a more specialized application, i.e., piece of -software that handles (server) or invokes (client) specific chaincodes -through the blockchain. Such applications are built on top of the -platform (client) and are detailed in Section 4.4. - -Developers of new chaincodes create a new deploy transaction by passing to -the fabric infrastructure: -* the confidentiality/security version or type they want the transaction to conform with, -* the set of users who wish to be given access to parts of the chaincode and - a proper representation of their (read) access rights - -* the chaincode specification, -* code metadata, containing information that should be passed to the chaincode - at the time of its execution - (e.g., configuration parameters), and -* transaction metadata, that is attached to the transaction structure, - and is only used by the application that deployed the chaincode. - -Invoke and query transactions corresponding to chaincodes with confidentiality -restrictions are created using a similar approach. The transactor provides the -identifier of the chaincode to be executed, the name of the function to be -invoked and its arguments. Optionally, the invoker can pass to the -transaction creation function, code invocation metadata, that will be provided -to the chaincode at the time of its execution. Transaction metadata is another -field that the application of the invoker or the invoker himself can leverage -for their own purposes. - -Finally transactions at the client side, are signed by a certificate of their -creator and released to the network of validators. -Validators receive the confidential transactions, and pass them through the following phases: -* *pre-validation* phase, where validators validate the transaction certificate against the accepted root certificate authority, - verify transaction certificate signature included in the transaction (statically), and check whether the transaction is a replay (see, later section for details on replay attack protection). -* *consensus* phase, where the validators add this transaction to the total order of transactions (ultimately included in the ledger) -* *pre-execution* phase, where validators verify the validity of the transaction / enrollment certificate against the current validity period, - decrypt the transaction (if the transaction is encrypted), and check that the transaction's plaintext is correctly formed(e.g., invocation access control is respected, included TCerts are correctly formed); - mini replay-attack check is also performed here within the transactions of the currently processed block. -* *execution* phase, where the (decrypted) chaincode is passed to a container, along with the associated code metadata, and is executed -* *commit* phase, where (encrypted) updates of that chaincodes state is committed to the ledger with the transaction itself. - - -#### 4.3.2 Transaction confidentiality - -Transaction confidentiality requires that under the request of the developer, the plain-text -of a chaincode, i.e., code, description, is not accessible or inferable (assuming a computational -attacker) by any unauthorized entities(i.e., user or peer not authorized by the developer). -For the latter, it is important that for chaincodes with confidentiality requirements the -content of both *deploy* and *invoke* transactions remains concealed. In the same spirit, -non-authorized parties, should not be able to associate invocations (invoke transactions) of a -chaincode to the chaincode itself (deploy transaction) or these invocations to each other. - -Additional requirements for any candidate solution is that it respects and supports the privacy -and security provisions of the underlying membership service. In addition, it should not prevent -the enforcement of any invocation access control of the chain-code functions in the fabric, or -the implementation of enforcement of access-control mechanisms on the application (See Subsection 4.4). - -In the following is provided the specification of transaction confidentiality -mechanisms at the granularity of users. The last subsection provides some guidelines -on how to extend this functionality at the level of validators. -Information on the features supported in current release and its security -provisions, you can find in Section 4.7. - -The goal is to achieve a design that will allow for granting or restricting -access to an entity to any subset of the following parts of a chain-code: -1. chaincode content, i.e., complete (source) code of the - chaincode, - -2. chaincode function headers, i.e., the prototypes of the functions included in a chaincode, - - -3. chaincode [invocations &] state, i.e., successive updates to the state of a specific chaincode, - when one or more functions of its are invoked -4. all the above - -Notice, that this design offers the application the capability to leverage the fabric's -membership service infrastructure and its public key infrastructure to build their own access -control policies and enforcement mechanisms. - -##### 4.3.2.1 Confidentiality against users - -To support fine-grained confidentiality control, i.e., restrict read-access to the -plain-text of a chaincode to a subset of users that the chaincode creator -defines, a chain is bound to a single long-term encryption key-pair -(PKchain, SKchain). -Though initially this key-pair is to be stored and maintained by each chain's -PKI, in later releases, however, this restriction will be moved away, -as chains (and the associated key-pairs) can be triggered through the Blockchain -by any user with *special* (admin) privileges (See, Section 4.3.2.2). - -**Setup**. At enrollment phase, users obtain (as before) an enrollment certificate, -denoted by Certui for user ui, while each -validator vj obtain its enrollment certificate denoted by -Certvj. Enrollment would grant users and validators the -following credentials: - -1. Users: - - a. claim and grant themselves signing key-pair (spku, ssku), - - b. claim and grant themselves encryption key-pair (epku, esku), - - c. obtain the encryption (public) key of the chain PKchain - -2. Validators: - - a. claim and grant themselves signing key-pair (spkv, sskv), - - b. claim and grant themselves an encryption key-pair (epkv, eskv), - - c. obtain the decryption (secret) key of the chain SKchain - -Thus, enrollment certificates contain the public part of two key-pairs: -* one signature key-pair [denoted by (spkvj,sskvj) - for validators and by (spkui, sskui) for users], and -* an encryption key-pair [denoted by (epkvj,eskvj) - for validators and (epkui, eskui) for users] - -Chain, validator and user enrollment public keys are accessible to everyone. - -In addition to enrollment certificates, users who wish to anonymously -participate in transactions issue transaction certificates. For simplicity -transaction certificates of a user ui are denoted by -TCertui. Transaction certificates include the public part -of a signature key-pair denoted by -(tpkui,tskui). - -The following section provides a high level description of how transaction -format accommodates read-access restrictions at the granularity of users. - -**Structure of deploy transaction.** -The following figure depicts the structure of a typical deploy -transaction with confidentiality enabled. - -![FirstRelease-deploy](./images/sec-usrconf-deploy.png) - -One can notice that a deployment transaction consists of several sections: -* Section *general-info*: contains the administration details of the - transaction, i.e., which chain this transaction corresponds to (chained), - the type of transaction (that is set to ''deplTrans''), the version number of - confidentiality policy implemented, its creator identifier (expressed by means - of transaction certificate TCert of enrollment certificate Cert), and a Nonce, - that facilitates primarily replay-attack resistance techniques. -* Section *code-info*: contains information on the chain-code source code, - and function headers. As shown in the figure below, there is a symmetric key - used for the source-code of the chaincode (KC), and another - symmetric key used for the function prototypes (KH). A signature of - the creator of the chaincode is included on the plain-text code such that - the latter cannot be detached from the transaction and replayed by another - party. -* Section *chain-validators*: where appropriate key material is passed to the - validators for the latter to be able to (i) decrypt the chain-code source - (KC), (ii) decrypt the headers, and - (iii) encrypt the state when the chain-code has been - invoked accordingly(KS). In particular, the chain-code creator - generates an encryption key-pair for the chain-code it deploys - (PKC, SKC). It then uses PKC - to encrypt all the keys associated to the chain-code: -
[(''code'',KC) ,(''headr'',KH),(''code-state'',KS), SigTCertuc(\*)]PKc,
- and passes the secret key SKC to the validators using the - chain-specific public key: -
[(''chaincode'',SKC), SigTCertuc(*)]PKchain.
-* Section *contract-users*: where the public encryption keys of the contract users, - i.e., users who are given read-access to parts of the chaincode, are used to encrypt - the keys associated to their access rights: - - 1. SKc for the users to be able to read any message associated to - that chain-code (invocation, state, etc), - - 2. KC for the user to be able to read only the contract code, - - 3. KH for the user to only be able to read the headers, - - 4. KS for the user to be able to read the state associated to that contract. - - Finally users are given the contract's public key PKc, - for them to be able to encrypt information related to that contract for the validators - (or any in possession of SKc) to be able to read it. Transaction certificate - of each contract user is appended to the transaction and follows that user's message. - This is done for users to be able to easily search the blockchain - for transactions they have been part of. Notice that the deployment transaction also - appends a message to the creator uc of the chain-code, for the - latter to be able to retrieve this transaction through parsing the ledger and without - keeping any state locally. - - -The entire transaction is signed by a certificate of the chaincode creator, i.e., enrollment -or transaction certificate as decided by the latter. -Two noteworthy points: -* Messages that are included in a transaction in an encrypted format, i.e., code-functions, code-hdrs, - are signed before they are encrypted using the same TCert the entire transaction is signed with, or - even with a different TCert or the ECert of the user (if the transaction deployment should carry the identity - of its owner. A binding to the underlying transaction carrier should be included in the signed message, e.g., - the hash of the TCert the transaction is signed, such that mix\&match attacks are not possible. - Though we detail such attacks in Section 4.4, in these cases an attacker who sees a transaction should not be able - to isolate the ciphertext corresponding to, e.g., code-info, and use it for another transaction of her own. - Clearly, such an ability would disrupt the operation of the system, as a chaincode that was first created by user A, - will now also belong to malicious user B (who is not even able to read it). -* To offer the ability to the users to cross-verify they are given access to the - correct key, i.e., to the same key as the other contract users, transaction - ciphertexts that are encrypted with a key K are accompanied by a commitment - to K, while the opening of this commitment value is passed to all users who - are entitled access to K in contract-users, and chain-validator sections. - - In this way, anyone who is entitled access to that key can verify that the key - has been properly passed to it. This part is omitted in the figure above to - avoid confusion. - - - -**Structure of invoke transaction.** -A transaction invoking the chain-code triggering the execution of a function of the chain-code with -user-specified arguments is structured as depicted in the figure below. - -![FirstRelease-deploy](./images/sec-usrconf-invoke.png) - -Invocation transaction as in the case of deployment transaction consists of a -*general-info* section, a *code-info* section, a section for the *chain-validators*, -and one for the *contract users*, signed altogether with one of the invoker's -transaction certificates. - -- General-info follows the same structure as the corresponding section of the -deployment transaction. -The only difference relates to the transaction type that is now set to ''InvocTx'', -and the chain-code identifier or name that is now encrypted under the -chain-specific encryption (public) key. - -- Code-info exhibits the same structure as the one of the deployment transaction. -Code payload, as in the case of deployment transaction, consists of function -invocation details (the name of the function invoked, and associated arguments), -code-metadata provided by the application and the transaction's creator -(invoker's u) certificate, TCertu. Code payload is signed by the -transaction certificate TCertu of the invoker u, as in the case -of deploy transactions. As in the case of -deploy transactions, code-metadata, and tx-metadata, are fields that are -provided by the application and can be used (as described in Section 4.4), -for the latter to implement their own access control mechanisms and roles. - -- Finally, contract-users and chain-validator sections provide the key the payload -is encrypted with, the invoker's key, and the chain encryption key respectively. -Upon receiving such transactions, the validators decrypt [code-name]PKchain using the -chain-specific secret key SKchain and obtain the invoked chain-code identifier. -Given the latter, validators retrieve from their local storage the chaincode's -decryption key SKc, and use it to decrypt chain-validators' message, -that would equip them with the symmetric key KI the invocation -transaction's payload was encrypted with. -Given the latter, validators decrypt code-info, and execute the chain-code -function with the specified arguments, -and the code-metadata attached(See, Section 4.4 for more details on the use of -code-metadata). While the chain-code is executed, updates of the state of that -chain-code are possible. -These are encrypted using the state-specific key Ks that was defined -during that chain-code's deployment. In particular, Ks is used the -same way KiTx is used in the design of our current release -(See, Section 4.7). - -**Structure of query transaction.** -Query transactions have the same format as invoke transactions. -The only difference is that Query transactions do not affect the state -of the chaincode, and thus there is no need for the state to be retrieved -(decrypted) and/or updated (encrypted) after the execution of the chaincode -completes. - -##### 4.3.2.2 Confidentiality against validators -This section deals with ways of how to support execution of certain transactions -under a different (or subset) sets of validators in the current chain. This -section inhibits IP restrictions and will be expanded in the following few weeks. - - -#### 4.3.3 Replay attack resistance -In replay attacks the attacker "replays" a message it "eavesdropped" on the network or ''saw'' on the Blockchain. -Replay attacks are a big problem here, as they can incur into the validating entities re-doing a computationally intensive -process (chaincode invocation) and/or affect the state of the corresponding chaincode, while it requires minimal or no -power from the attacker side. To make matters worse, if a transaction was a payment transaction, replays could -potentially incur into the payment being performed more than once, without this being the original intention of the payer. -Existing systems resist replay attacks as follows: -* Record hashes of transactions in the system. This solution would require that validators maintain a log of the hash of - each transaction that has ever been announced through the network, and compare a new transaction against their locally - stored transaction record. Clearly such approach cannot scale for large networks, and could easily result into validators - spending a lot of time to do the check of whether a transaction has been replayed, than executing the actual transaction. -* Leverage state that is maintained per user identity (Ethereum). Ethereum keeps some state, e.g., counter (initially set to 1) - for each identity/pseudonym in the system. Users also maintain their own counter (initially set to 0) for each - identity/pseudonym of theirs. Each time a user sends a transaction using an identity/pseudonym of his, he increases - his local counter by one and adds the resulting value to the transaction. The transaction is subsequently signed by that - user identity and released to the network. When picking up this transaction, validators check the counter value included - within and compare it with the one they have stored locally; if the value is the same, they increase the local value of - that identity's counter and accept the transaction. Otherwise, they reject the transaction as invalid or replay. - Although this would work well in cases where we have limited number of user identities/pseudonyms (e.g., not too large), - it would ultimately not scale in a system where users use a different identifier (transaction certificate) per transaction, - and thus have a number of user pseudonyms proportional to the number of transactions. - -Other asset management systems, e.g., Bitcoin, though not directly dealing with replay attacks, they resist them. In systems -that manage (digital) assets, state is maintained on a per asset basis, i.e., validators only keep a record of who owns what. -Resistance to replay attacks come as a direct result from this, as replays of transactions would be immediately be -deemed as invalid by the protocol (since can only be shown to be derived from older owners of an asset/coin). While this would -be appropriate for asset management systems, this does not abide with the needs of a Blockchain systems with more generic -use than asset management. - -In the fabric, replay attack protection uses a hybrid approach. -That is, users add in the transaction a nonce that is generated in a different manner -depending on whether the transaction is anonymous (followed and signed by a transaction certificate) or not -(followed and signed by a long term enrollment certificate). More specifically: - -* Users submitting a transaction with their enrollment certificate should include in that - transaction a nonce that is a function of the nonce they used in the previous transaction - they issued with the same certificate (e.g., a counter function or a hash). The nonce included - in the first transaction of each enrollment certificate can be either pre-fixed by the system - (e.g., included in the genesis block) or chosen by the user. In the first case, the genesis block - would need to include nonceall , i.e., a fixed number and the nonce used by user with identity - IDA for his first enrollment certificate signed transaction would be -
nonceround0IDA <- hash(IDA, nonceall),
- where IDA appears in the enrollment certificate. From that point onward successive transactions of - that user with enrollment certificate would include a nonce as follows -
nonceroundiIDA <- hash(nonceround{i-1}IDA),
- that is the nonce of the ith transaction would be using the hash of the nonce used in the {i-1}th transaction of that certificate. - Validators here continue to process a transaction they receive, as long as it satisfies the condition mentioned above. - Upon successful validation of transaction's format, the validators update their database with that nonce. - - **Storage overhead**: - - 1. on the user side: only the most recently used nonce, - - 2. on validator side: O(n), where n is the number of users. -* Users submitting a transaction with a transaction certificate - should include in the transaction a random nonce, that would guarantee that - two transactions do not result into the same hash. Validators add the hash of - this transaction in their local database if the transaction certificate used within - it has not expired. To avoid storing large amounts of hashes, validity periods of transaction certificates - are leveraged. In particular validators maintain an updated record of received - transactions' hashes within the current or future validity period. - - **Storage overhead** (only makes sense for validators here): O(m), where m is the approximate number of - transactions within a validity period and corresponding validity period identifier (see below). - -### 4.4 Access control features on the application - -An application, is a piece of software that runs on top of a Blockchain client software, and, -performs a special task over the Blockchain, i.e., restaurant table reservation. -Application software have a version of -developer, enabling the latter to generate and manage a couple of chaincodes that are necessary for -the business this application serves, and a client-version that would allow the application's end-users -to make use of the application, by invoking these chain-codes. -The use of the Blockchain can be transparent to the application end-users or not. - -This section describes how an application leveraging chaincodes can implement its own access control policies, -and guidelines on how our Membership services PKI can be leveraged for the same purpose. - -The presentation is divided into enforcement of invocation access control, -and enforcement of read-access control by the application. - - -#### 4.4.1 Invocation access control -To allow the application to implement its own invocation access control at the -application layer securely, special support by the fabric must be provided. -In the following we elaborate on the tools exposed by the fabric to the -application for this purpose, and provide guidelines on how these should be used -by the application for the latter to enforce access control securely. - - -**Support from the infrastructure.** -For the chaincode creator, let it be, *uc*, -to be able to implement its own invocation access control at -the application layer securely, special support by the fabric must be provided. -More specifically fabric layer gives access to following capabilities: - -1. The client-application can request the fabric to sign and verify any message with specific transaction certificates or enrollment certificate the client owns; this is expressed via the Certificate Handler interface - -2. The client-application can request the fabric a unique *binding* to be used to bind authentication data of the application to the underlying transaction transporting it; this is expressed via the Transaction Handler interface - -3. Support for a transaction format, that allows for the application to specify metadata, that are passed to the chain-code at deployment, and invocation time; the latter denoted by code-metadata. - - -The **Certificate Handler** interface allows to sign and verify any message using signing key-pair underlying the associated certificate. -The certificate can be a TCert or an ECert. - -``` -// CertificateHandler exposes methods to deal with an ECert/TCert -type CertificateHandler interface { - - // GetCertificate returns the certificate's DER - GetCertificate() []byte - - // Sign signs msg using the signing key corresponding to the certificate - Sign(msg []byte) ([]byte, error) - - // Verify verifies msg using the verifying key corresponding to the certificate - Verify(signature []byte, msg []byte) error - - // GetTransactionHandler returns a new transaction handler relative to this certificate - GetTransactionHandler() (TransactionHandler, error) -} -``` - - -The **Transaction Handler** interface allows to create transactions and give access to the underlying *binding* that can be leveraged to link -application data to the underlying transaction. Bindings are a concept that have been introduced in network transport protocols (See, https://tools.ietf.org/html/rfc5056), -known as *channel bindings*, that *allows applications to establish that the two end-points of a secure channel at one network layer are the same as at a higher layer -by binding authentication at the higher layer to the channel at the lower layer. -This allows applications to delegate session protection to lower layers, which has various performance benefits.* -Transaction bindings offer the ability to uniquely identify the fabric layer of the transaction that serves as the container that -application data uses to be added to the ledger. - -``` -// TransactionHandler represents a single transaction that can be uniquely determined or identified by the output of the GetBinding method. -// This transaction is linked to a single Certificate (TCert or ECert). -type TransactionHandler interface { - - // GetCertificateHandler returns the certificate handler relative to the certificate mapped to this transaction - GetCertificateHandler() (CertificateHandler, error) - - // GetBinding returns a binding to the underlying transaction (container) - GetBinding() ([]byte, error) - - // NewChaincodeDeployTransaction is used to deploy chaincode - NewChaincodeDeployTransaction(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string) (*obc.Transaction, error) - - // NewChaincodeExecute is used to execute chaincode's functions - NewChaincodeExecute(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) - - // NewChaincodeQuery is used to query chaincode's functions - NewChaincodeQuery(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) -} -``` -For version 1, *binding* consists of the *hash*(TCert, Nonce), where TCert, is the transaction certificate -used to sign the entire transaction, while Nonce, is the nonce number used within. - -The **Client** interface is more generic, and offers a mean to get instances of the previous interfaces. - -``` -type Client interface { - - ... - - // GetEnrollmentCertHandler returns a CertificateHandler whose certificate is the enrollment certificate - GetEnrollmentCertificateHandler() (CertificateHandler, error) - - // GetTCertHandlerNext returns a CertificateHandler whose certificate is the next available TCert - GetTCertificateHandlerNext() (CertificateHandler, error) - - // GetTCertHandlerFromDER returns a CertificateHandler whose certificate is the one passed - GetTCertificateHandlerFromDER(der []byte) (CertificateHandler, error) - -} -``` - -To support application-level access control lists for controlling chaincode -invocation, the fabric's transaction and chaincode specification format -have an additional field to store application-specific metadata. -This field is depicted in both figures 1, by code-metadata. The content of this field is decided -by the application, at the transaction creation time. -The fabric layer treats it as an unstructured stream of bytes. - - - -``` - -message ChaincodeSpec { - - ... - - ConfidentialityLevel confidentialityLevel; - bytes metadata; - - ... -} - - -message Transaction { - ... - - bytes payload; - bytes metadata; - - ... -} -``` - -To assist chaincode execution, at the chain-code invocation time, the validators provide the -chaincode with additional information, like the metadata and the binding. - -**Application invocation access control.** -This section describes how the application can leverage the means provided by the fabric -to implement its own access control on its chain-code functions. -In the scenario considered here, the following entities are identified: - -1. **C**: is a chaincode that contains a single function, e.g., called *hello*; - -2. **uc**: is the **C** deployer; - -3. **ui**: is a user who is authorized to invoke **C**'s functions. User uc wants to ensure that only ui can invoke the function *hello*. - -*Deployment of a Chaincode:* At deployment time, uc has full control on the deployment transaction's metadata, - and can be used to store a list of ACLs (one per function), or a list of roles that are needed by the application. The format which is used to store these ACLs is up to the deployer's application, as the chain-code is the one -who would need to parse the metadata at execution time. -To define each of these lists/roles, uc can use any TCerts/Certs of the ui (or, if applicable, or other users who have been assigned that privilege or role). Let this be TCertui. -The exchange of TCerts or Certs among the developer and authorized users is done through an out-of-band channel. - -Assume that the application of uc's requires that to invoke the *hello* function, a certain message *M* has to be authenticated by an authorized invoker (ui, in our example). -One can distinguish the following two cases: - -1. *M* is one of the chaincode's function arguments; - -2. *M* is the invocation message itself, i.e., function-name, function-arguments. - -*Chaincode invocation:* -To invoke C, ui's application needs to sign *M* using the TCert/ECert, that was used to identify ui's participation in the chain-code at the associated -deployment transaction's metadata, i.e., TCertui. More specifically, ui's client application does the following: - -1. Retrieves a CertificateHandler for Certui, *cHandler*; - -2. obtains a new TransactionHandler to issue the execute transaction, *txHandler* relative to his next available TCert or his ECert; - -3. gets *txHandler*'s *binding* by invoking *txHandler.getBinding()*; - -4. signs *'*M* || txBinding'* by invoking *cHandler.Sign('*M* || txBinding')*, let *sigma* be the output of the signing function; - -5. issues a new execute transaction by invoking, *txHandler.NewChaincodeExecute(...)*. Now, *sigma* can be included in the transaction as one of the arguments that are passed to the function (case 1) or as part of the code-metadata section of the payload(case 2). - -*Chaincode processing:* -The validators, who receive the execute transaction issued ui, will provide to *hello* the following information: - -1. The *binding* of the execute transaction, that can be independently computed at the validator side; - -2. The *metadata* of the execute transaction (code-metadata section of the transaction); - -3. The *metadata* of the deploy transaction (code-metadata component of the corresponding deployment transaction). - -Notice that *sigma* is either part of the arguments of the invoked function, or stored inside the code-metadata of the invocation transaction (properly formatted by the client-application). -Application ACLs are included in the code-metadata section, that is also passed to the chain-code at execution time. -Function *hello* is responsible for checking that *sigma* is indeed a valid signature issued by TCertui, on '*M* || *txBinding'*. - -#### 4.4.2 Read access control -This section describes how the fabric's infrastructure offers support to the application to -enforce its own read-access control policies at the level of users. As in the case of invocation access -control, the first part describes the infrastructure features that can be leveraged by the application for this -purpose, and the last part details on the way applications should use these tools. - -For the purpose of this discussion, we leverage a similar example as before, i.e., - -1. **C**: is a chaincode that contains a single function, e.g., called *hello*; - -2. **uA**: is the **C**'s deployer, also known as application; - -3. **ur**: is a user who is authorized to read **C**'s functions. User uA wants to ensure that only ur can read the function *hello*. - -**Support from the infrastructure.** -For **uA** to be able to implement its own read access control at the application layer securely, our infrastructure is required to -support the transaction format for code deployment and invocation, as depicted in the two figures below. - -![SecRelease-RACappDepl title="Deployment transaction format supporting application-level read access control."](./images/sec-usrconf-deploy-interm.png) - -![SecRelease-RACappInv title="Invocation transaction format supporting application-level read access control."](./images/sec-usrconf-invoke-interm.png) - -More specifically fabric layer is required to provide the following functionality: - -1. Provide minimal encryption capability such that data is only decryptable by a validator's (infrastructure) side; this means that the infrastructure should move closer to our future version, where an asymmetric encryption scheme is used for encrypting transactions. More specifically, an asymmetric key-pair is used for the chain, denoted by Kchain in the Figures above, but detailed in Section Transaction Confidentiality. - -2. The client-application can request the infrastructure sitting on the client-side to encrypt/decrypt information using a specific public encryption key, or that client's long-term decryption key. - -3. The transaction format offers the ability to the application to store additional transaction metadata, that can be passed to the client-application after the latter's request. Transaction metadata, as opposed to code-metadata, is not encrypted or provided to the chain-code at execution time. Validators treat these metadata as a list of bytes they are not responsible for checking validity of. - -**Application read-access control.** -For this reason the application may request and obtain access to the public encryption key of the user **ur**; let that be **PKur**. Optionally, -**ur** may be providing **uA** with a certificate of its, that would be leveraged by the application, say, TCertur; given the latter, -the application would, e.g., be able to trace that user's transactions w.r.t. the application's chain-codes. TCertur, and PKur, are -exchanged in an out-of-band channel. - -At deployment time, application **uA** performs the following steps: - -1. Uses the underlying infrastructure to encrypt the information of **C**, the application would like to make accessible to **ur**, using PKur. - Let Cur be the resulting ciphertext. - -2. (optional) Cur can be concatenated with TCertur - -3. Passes the overall string as ''Tx-metadata'' of the confidential transaction to be constructed. - -At invocation time, the client-application on ur's node, would be able, by obtaining the deployment transaction to retrieve the content of **C**. -It just needs to retrieve the **tx-metadata** field of the associated deployment transaction, and trigger the decryption functionality offered by our Blockchain -infrastrucure's client, for Cur. Notice that it is the application's responsibility to encrypt the correct **C** for ur. -Also, the use of **tx-metadata** field can be generalized to accommodate application-needs. E.g., it can be that invokers leverage the same field of invocation transactions -to pass information to the developer of the application, etc. - -**Important Note:** It is essential to note that validators **do not provide** any decryption oracle to the chain-code -throughout its execution. Its infrastructure is though responsible for decrypting the payload of the chain-code itself (as well as -the code-metadata fields near it), and provide those to containers for deployment/execution. - -### 4.5 Online wallet service - - -This section describes the security design of a wallet service, which in this case is a node with which end-users can register, store their key material and through which they can perform transactions. -Because the wallet service is in possession of the user's key material, it is clear that without a secure authorization -mechanism in place a malicious wallet service could successfully impersonate the user. -We thus emphasize that this design corresponds to a wallet service that is **trusted** to only perform transactions -on behalf of its clients, with the consent of the latter. -There are two cases for the registration of an end-user to an online wallet service: - -1. When the user has registered with the registration authority and acquired his/her ``, - but has not installed the client to trigger and complete the enrollment process; -2. When the user has already installed the client, and completed the enrollment phase. - -Initially, the user interacts with the online wallet service to issue credentials that would allow him to authenticate -to the wallet service. That is, the user is given a username, and password, where username identifies the user in the -membership service, denoted by AccPub, and password is the associated secret, denoted by AccSec, that is **shared** by -both user and service. - -To enroll through the online wallet service, a user must provide the following request -object to the wallet service: - - - AccountRequest /* account request of u \*/ - { - OBCSecCtx , /* credentials associated to network \*/ - AccPubu, /* account identifier of u \*/ - AccSecProofu /* proof of AccSecu\*/ - } - -OBCSecCtx refers to user credentials, which depending on the stage of his enrollment process, can be either his enrollment ID and password, `` or his enrollment certificate and associated secret key(s) -(ECertu, sku), where sku denotes for simplicity signing and decryption secret of the user. -The content of AccSecProofu is an HMAC on the rest fields of request using the shared secret. Nonce-based methods -similar to what we have in the fabric can be used to protect against replays. -OBCSecCtx would give the online wallet service the necessary information to enroll the user or issue required TCerts. - -For subsequent requests, the user u should provide to the wallet service a request of similar format. - - TransactionRequest /* account request of u \*/ - { - TxDetails, /* specifications for the new transaction \*/ - AccPubu, /* account identifier of u \*/ - AccSecProofu /* proof of AccSecu \*/ - } - -Here, TxDetails refer to the information needed by the online service to construct a transaction on behalf of the user, i.e., -the type, and user-specified content of the transaction. - -AccSecProofu is again an HMAC on the rest fields of request using the shared secret. -Nonce-based methods similar to what we have in the fabric can be used to protect against replays. - -TLS connections can be used in each case with server side authentication to secure the request at the -network layer (confidentiality, replay attack protection, etc) - - - - -### 4.6 Network security (TLS) -The TLS CA should be capable of issuing TLS certificates to (non-validating) peers, validators, and individual clients (or browsers capable of storing a private key). Preferably, these certificates are distinguished by type, per above. TLS certificates for CAs of the various types (such as TLS CA, ECA, TCA) could be issued by an intermediate CA (i.e., a CA that is subordinate to the root CA). Where there is not a particular traffic analysis issue, any given TLS connection can be mutually authenticated, except for requests to the TLS CA for TLS certificates. - -In the current implementation the only trust anchor is the TLS CA self-signed certificate in order to accommodate the limitation of a single port to communicate with all three (co-located) servers, i.e., the TLS CA, the TCA and the ECA. Consequently, the TLS handshake is established with the TLS CA, which passes the resultant session keys to the co-located TCA and ECA. The trust in validity of the TCA and ECA self-signed certificates is therefore inherited from trust in the TLS CA. In an implementation that does not thus elevate the TLS CA above other CAs, the trust anchor should be replaced with a root CA under which the TLS CA and all other CAs are certified. - - - -### 4.7 Restrictions in the current release -This section lists the restrictions of the current release of the fabric. -A particular focus is given on client operations and the design of transaction confidentiality, -as depicted in Sections 4.7.1 and 4.7.2. - - - Client side enrollment and transaction creation is performed entirely by a - non-validating peer that is trusted not to impersonate the user. - See, Section 4.7.1 for more information. - - A minimal set of confidentiality properties where a chaincode is accessible - by any entity that is member of the system, i.e., validators and users who - have registered through Hyperledger Fabric's Membership Services and is not accessible by anyone else. - The latter include any party that has access to the storage area where the - ledger is maintained, or other entities that are able to see the transactions - that are announced in the validator network. The design of the first release - is detailed in subsection 4.7.2 - - The code utilizes self-signed certificates for entities such as the - enrollment CA (ECA) and the transaction CA (TCA) - - Replay attack resistance mechanism is not available - - Invocation access control can be enforced at the application layer: - it is up to the application to leverage the infrastructure's tools properly - for security to be guaranteed. This means, that if the application fails to - *bind* the transaction binding offered by the fabric, secure transaction - processing may be at risk. - -#### 4.7.1 Simplified client - -Client-side enrollment and transaction creation are performed entirely by a non-validating peer that plays the role of an online wallet. -In particular, the end-user leverages their registration credentials to open an account to a non-validating peer -and uses these credentials to further authorize the peer to build transactions on the user's behalf. It needs to be noted, that such -a design does not provide secure **authorization** for the peer to submit transactions on behalf of the user, as a malicious peer -could impersonate the user. Details on the specifications of a design that deals with the security issues of online wallet can be found is Section 4.5. -Currently the maximum number of peers a user can register to and perform transactions through is one. - -#### 4.7.2 Simplified transaction confidentiality - -**Disclaimer:** The current version of transaction confidentiality is minimal, and will be used as an intermediate step -to reach a design that allows for fine grained (invocation) access control enforcement in a subsequent release. - -In its current form, confidentiality of transactions is offered solely at the chain-level, i.e., that the -content of a transaction included in a ledger, is readable by all members of that chain, i.e., validators -and users. At the same time, application auditors who are not members of the system can be given -the means to perform auditing by passively observing the blockchain data, while -guaranteeing that they are given access solely to the transactions related to the application under audit. -State is encrypted in a way that such auditing requirements are satisfied, while not disrupting the -proper operation of the underlying consensus network. - -More specifically, currently symmetric key encryption is supported in the process of offering transaction confidentiality. In this setting, one of the main challenges that is specific to the blockchain setting, -is that validators need to run consensus over the state of the blockchain, that, aside from the transactions themselves, -also includes the state updates of individual contracts or chaincode. Though this is trivial to do for non-confidential chaincode, for confidential chaincode, one needs to design the state encryption mechanism such that the resulting ciphertexts are semantically secure, and yet, identical if the plaintext state is the same. - -To overcome this challenge, the fabric utilizes a key hierarchy that reduces the number of ciphertexts -that are encrypted under the same key. At the same time, as some of these keys are used for the generation of IVs, -this allows the validating parties to generate exactly the same ciphertext when executing the same transaction -(this is necessary to remain agnostic to the underlying consensus algorithm) and offers the possibility of controlling audit by disclosing to auditing entities only the most relevant keys. - - -**Method description:** -Membership service generates a symmetric key for the ledger (Kchain) that is distributed -at registration time to all the entities of the blockchain system, i.e., the clients and the -validating entities that have issued credentials through the membership service of the chain. -At enrollment phase, user obtain (as before) an enrollment certificate, denoted by Certui -for user ui , while each validator vj obtains its enrollment certificate denoted by Certvj. - -Entity enrollment would be enhanced, as follows. In addition to enrollment certificates, -users who wish to anonymously participate in transactions issue transaction certificates. -For simplicity transaction certificates of a user ui are denoted by TCertui. -Transaction certificates include the public part of a signature key-pair denoted by (tpkui,tskui). - -In order to defeat crypto-analysis and enforce confidentiality, the following key hierarchy is considered for generation and validation of confidential transactions: -To submit a confidential transaction (Tx) to the ledger, a client first samples a nonce (N), which is required to be unique among all the transactions submitted to the blockchain, and derive a transaction symmetric -key (KTx) by applying the HMAC function keyed with Kchain and on input the nonce, KTx= HMAC(Kchain, N). From KTx, the client derives two AES keys: -KTxCID as HMAC(KTx, c1), KTxP as HMAC(KTx, c2)) to encrypt respectively the chain-code name or identifier CID and code (or payload) P. -c1, c2 are public constants. The nonce, the Encrypted Chaincode ID (ECID) and the Encrypted Payload (EP) are added in the transaction Tx structure, that is finally signed and so -authenticated. Figure below shows how encryption keys for the client's transaction are generated. Arrows in this figure denote application of an HMAC, keyed by the key at the source of the arrow and -using the number in the arrow as argument. Deployment/Invocation transactions' keys are indicated by d/i respectively. - - - -![FirstRelease-clientSide](./images/sec-firstrel-1.png) - -To validate a confidential transaction Tx submitted to the blockchain by a client, -a validating entity first decrypts ECID and EP by re-deriving KTxCID and KTxP -from Kchain and Tx.Nonce as done before. Once the Chaincode ID and the -Payload are recovered the transaction can be processed. - -![FirstRelease-validatorSide](./images/sec-firstrel-2.png) - -When V validates a confidential transaction, the corresponding chaincode can access and modify the -chaincode's state. V keeps the chaincode's state encrypted. In order to do so, V generates symmetric -keys as depicted in the figure above. Let iTx be a confidential transaction invoking a function -deployed at an early stage by the confidential transaction dTx (notice that iTx can be dTx itself -in the case, for example, that dTx has a setup function that initializes the chaincode's state). -Then, V generates two symmetric keys KIV and Kstate as follows: - -1. It computes as KdTx , i.e., the transaction key of the corresponding deployment - transaction, and then Nstate = HMAC(Kdtx ,hash(Ni)), where Ni - is the nonce appearing in the invocation transaction, and *hash* a hash function. -2. It sets Kstate = HMAC(KdTx, c3 || Nstate), - truncated opportunely deeding on the underlying cipher used to encrypt; c3 is a constant number -3. It sets KIV = HMAC(KdTx, c4 || Nstate); c4 is a constant number - - -In order to encrypt a state variable S, a validator first generates the IV as HMAC(KIV, crtstate) -properly truncated, where crtstate is a counter value that increases each time a state update -is requested for the same chaincode invocation. The counter is discarded after the execution of -the chaincode terminates. After IV has been generated, V encrypts with authentication (i.e., GSM mode) -the value of S concatenated with Nstate(Actually, Nstate doesn't need to be encrypted but -only authenticated). To the resulting ciphertext (CT), Nstate and the IV used is appended. -In order to decrypt an encrypted state CT|| Nstate' , a validator first generates the symmetric -keys KdTX' ,Kstate' using Nstate' and then decrypts CT. - -Generation of IVs: In order to be agnostic to any underlying consensus algorithm, all the validating -parties need a method to produce the same exact ciphertexts. In order to do so, the validators need -to use the same IVs. Reusing the same IV with the same symmetric key completely breaks the security -of the underlying cipher. Therefore, the process described before is followed. In particular, V first -derives an IV generation key KIV by computing HMAC(KdTX, c4 || Nstate ), -where c4 is a constant number, and keeps a counter crtstate for the pair -(dTx, iTx) with is initially set to 0. Then, each time a new ciphertext has to be generated, the validator -generates a new IV by computing it as the output of HMAC(KIV, crtstate) -and then increments the crtstate by one. - -Another benefit that comes with the above key hierarchy is the ability to enable controlled auditing. -For example, while by releasing Kchain one would provide read access to the whole chain, -by releasing only Kstate for a given pair of transactions (dTx,iTx) access would be granted to a state -updated by iTx, and so on. - - -The following figures demonstrate the format of a deployment and invocation transaction currently available in the code. - -![FirstRelease-deploy](./images/sec-firstrel-depl.png) - -![FirstRelease-deploy](./images/sec-firstrel-inv.png) - - -One can notice that both deployment and invocation transactions consist of two sections: - -* Section *general-info*: contains the administration details of the transaction, i.e., which chain this transaction corresponds to (is chained to), the type of transaction (that is set to ''deploymTx'' or ''invocTx''), the version number of confidentiality policy implemented, its creator identifier (expressed by means of TCert of Cert) and a nonce (facilitates primarily replay-attack resistance techniques). - -* Section *code-info*: contains information on the chain-code source code. For deployment transaction this is essentially the chain-code identifier/name and source code, while for invocation chain-code is the name of the function invoked and its arguments. As shown in the two figures code-info in both transactions are encrypted ultimately using the chain-specific symmetric key Kchain. - -## 5. Byzantine Consensus -The ``pbft`` package is an implementation of the seminal [PBFT](http://dl.acm.org/citation.cfm?id=571640 "PBFT") consensus protocol [1], which provides consensus among validators despite a threshold of validators acting as _Byzantine_, i.e., being malicious or failing in an unpredictable manner. In the default configuration, PBFT tolerates up to t -The fabric API design covers the categories below, though the implementation is incomplete for some of them in the current release. The [REST API](#62-rest-api) section will describe the APIs currently supported. - -* Identity - Enrollment to acquire or to revoke a certificate -* Address - Target and source of a transaction -* Transaction - Unit of execution on the ledger -* Chaincode - Program running on the ledger -* Blockchain - Contents of the ledger -* Network - Information about the blockchain peer network -* Storage - External store for files or documents -* Event Stream - Sub/pub events on the blockchain - -### 6.1 REST Service -The REST service can be enabled (via configuration) on either validating or non-validating peers, but it is recommended to only enable the REST service on non-validating peers on production networks. - -``` -func StartOpenchainRESTServer(server *oc.ServerOpenchain, devops *oc.Devops) -``` - -This function reads the `rest.address` value in the `core.yaml` configuration file, which is the configuration file for the `peer` process. The value of the `rest.address` key defines the default address and port on which the peer will listen for HTTP REST requests. - -It is assumed that the REST service receives requests from applications which have already authenticated the end user. - -### 6.2 REST API - -You can work with the REST API through any tool of your choice. For example, the curl command line utility or a browser based client such as the Firefox Rest Client or Chrome Postman. You can likewise trigger REST requests directly through [Swagger](http://swagger.io/). To obtain the REST API Swagger description, click [here](https://github.com/hyperledger/fabric/blob/master/core/rest/rest_api.json). The currently available APIs are summarized in the following section. - -#### 6.2.1 REST Endpoints - -* [Block](#6211-block-api) - * GET /chain/blocks/{block-id} -* [Blockchain](#6212-blockchain-api) - * GET /chain -* [Chaincode](#6213-chaincode-api) - * POST /chaincode -* [Network](#6214-network-api) - * GET /network/peers -* [Registrar](#6215-registrar-api-member-services) - * POST /registrar - * GET /registrar/{enrollmentID} - * DELETE /registrar/{enrollmentID} - * GET /registrar/{enrollmentID}/ecert - * GET /registrar/{enrollmentID}/tcert -* [Transactions](#6216-transactions-api) - * GET /transactions/{UUID} - -##### 6.2.1.1 Block API - -* **GET /chain/blocks/{block-id}** - -Use the Block API to retrieve the contents of various blocks from the blockchain. The returned Block message structure is defined in section [3.2.1.1](#3211-block). - -Block Retrieval Request: -``` -GET host:port/chain/blocks/173 -``` - -Block Retrieval Response: -``` -{ - "transactions": [ - { - "type": 3, - "chaincodeID": "EgRteWNj", - "payload": "Ch4IARIGEgRteWNjGhIKBmludm9rZRIBYRIBYhICMTA=", - "uuid": "f5978e82-6d8c-47d1-adec-f18b794f570e", - "timestamp": { - "seconds": 1453758316, - "nanos": 206716775 - }, - "cert": "MIIB/zCCAYWgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMTI1MjE0MTE3WhcNMTYwNDI0MjE0MTE3WjArMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQ4wDAYDVQQDEwVsdWthczB2MBAGByqGSM49AgEGBSuBBAAiA2IABC/BBkt8izf6Ew8UDd62EdWFikJhyCPY5VO9Wxq9JVzt3D6nubx2jO5JdfWt49q8V1Aythia50MZEDpmKhtM6z7LHOU1RxuxdjcYDOvkNJo6pX144U4N1J8/D3A+97qZpKN/MH0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDA9BgYqAwQFBgcBAf8EMABNbPHZ0e/2EToi0H8mkouuUDwurgBYuUB+vZfeMewBre3wXG0irzMtfwHlfECRDDAKBggqhkjOPQQDAwNoADBlAjAoote5zYFv91lHzpbEwTfJL/+r+CG7oMVFUFuoSlvBSCObK2bDIbNkW4VQ+ZC9GTsCMQC5GCgy2oZdHw/x7XYzG2BiqmRkLRTiCS7vYCVJXLivU65P984HopxW0cEqeFM9co0=", - "signature": "MGUCMCIJaCT3YRsjXt4TzwfmD9hg9pxYnV13kWgf7e1hAW5Nar//05kFtpVlq83X+YtcmAIxAK0IQlCgS6nqQzZEGCLd9r7cg1AkQOT/RgoWB8zcaVjh3bCmgYHsoPAPgMsi3TJktg==" - } - ], - "stateHash": "7ftCvPeHIpsvSavxUoZM0u7o67MPU81ImOJIO7ZdMoH2mjnAaAAafYy9MIH3HjrWM1/Zla/Q6LsLzIjuYdYdlQ==", - "previousBlockHash": "lT0InRg4Cvk4cKykWpCRKWDZ9YNYMzuHdUzsaeTeAcH3HdfriLEcTuxrFJ76W4jrWVvTBdI1etxuIV9AO6UF4Q==", - "nonHashData": { - "localLedgerCommitTimestamp": { - "seconds": 1453758316, - "nanos": 250834782 - } - } -} -``` - -##### 6.2.1.2 Blockchain API - -* **GET /chain** - -Use the Chain API to retrieve the current state of the blockchain. The returned BlockchainInfo message is defined below. - -``` -message BlockchainInfo { - uint64 height = 1; - bytes currentBlockHash = 2; - bytes previousBlockHash = 3; -} -``` - -* `height` - Number of blocks in the blockchain, including the genesis block. - -* `currentBlockHash` - The hash of the current or last block. - -* `previousBlockHash` - The hash of the previous block. - -Blockchain Retrieval Request: -``` -GET host:port/chain -``` - -Blockchain Retrieval Response: -``` -{ - "height": 174, - "currentBlockHash": "lIfbDax2NZMU3rG3cDR11OGicPLp1yebIkia33Zte9AnfqvffK6tsHRyKwsw0hZFZkCGIa9wHVkOGyFTcFxM5w==", - "previousBlockHash": "Vlz6Dv5OSy0OZpJvijrU1cmY2cNS5Ar3xX5DxAi/seaHHRPdssrljDeppDLzGx6ZVyayt8Ru6jO+E68IwMrXLQ==" -} -``` - -##### 6.2.1.3 Chaincode API - -* **POST /chaincode** - -Use the Chaincode API to deploy, invoke, and query chaincodes. The deploy request requires the client to supply a `path` parameter, pointing to the directory containing the chaincode in the file system. The response to a deploy request is either a message containing a confirmation of successful chaincode deployment or an error, containing a reason for the failure. It also contains the generated chaincode `name` in the `message` field, which is to be used in subsequent invocation and query transactions to uniquely identify the deployed chaincode. - -To deploy a chaincode, supply the required ChaincodeSpec payload, defined in section [3.1.2.2](#3122-transaction-specification). - -Deploy Request: -``` -POST host:port/chaincode - -{ - "jsonrpc": "2.0", - "method": "deploy", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "path":"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" - }, - "input": { - "function":"init", - "args":["a", "1000", "b", "2000"] - } - }, - "id": "1" -} -``` - -Deploy Response: -``` -{ - "jsonrpc": "2.0", - "result": { - "status": "OK", - "message": "52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" - }, - "id": 1 -} -``` - -With security enabled, modify the required payload to include the `secureContext` element passing the enrollment ID of a logged in user as follows: - -Deploy Request with security enabled: -``` -POST host:port/chaincode - -{ - "jsonrpc": "2.0", - "method": "deploy", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "path":"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" - }, - "input": { - "function":"init", - "args":["a", "1000", "b", "2000"] - }, - "secureContext": "lukas" - }, - "id": "1" -} -``` - -The invoke request requires the client to supply a `name` parameter, which was previously returned in the response from the deploy transaction. The response to an invocation request is either a message containing a confirmation of successful execution or an error, containing a reason for the failure. - -To invoke a function within a chaincode, supply the required ChaincodeSpec payload, defined in section [3.1.2.2](#3122-transaction-specification). - -Invoke Request: -``` -POST host:port/chaincode - -{ - "jsonrpc": "2.0", - "method": "invoke", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" - }, - "input": { - "function":"invoke", - "args":["a", "b", "100"] - } - }, - "id": "3" -} -``` - -Invoke Response: -``` -{ - "jsonrpc": "2.0", - "result": { - "status": "OK", - "message": "5a4540e5-902b-422d-a6ab-e70ab36a2e6d" - }, - "id": 3 -} -``` - -With security enabled, modify the required payload to include the `secureContext` element passing the enrollment ID of a logged in user as follows: - -Invoke Request with security enabled: -``` -{ - "jsonrpc": "2.0", - "method": "invoke", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" - }, - "input": { - "function":"invoke", - "args":["a", "b", "100"] - }, - "secureContext": "lukas" - }, - "id": "3" -} -``` - -The query request requires the client to supply a `name` parameter, which was previously returned in the response from the deploy transaction. The response to a query request depends on the chaincode implementation. The response will contain a message containing a confirmation of successful execution or an error, containing a reason for the failure. In the case of successful execution, the response will also contain values of requested state variables within the chaincode. - -To invoke a query function within a chaincode, supply the required ChaincodeSpec payload, defined in section [3.1.2.2](#3122-transaction-specification). - -Query Request: -``` -POST host:port/chaincode/ - -{ - "jsonrpc": "2.0", - "method": "query", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" - }, - "input": { - "function":"query", - "args":["a"] - } - }, - "id": "5" -} -``` - -Query Response: -``` -{ - "jsonrpc": "2.0", - "result": { - "status": "OK", - "message": "-400" - }, - "id": 5 -} -``` - -With security enabled, modify the required payload to include the `secureContext` element passing the enrollment ID of a logged in user as follows: - -Query Request with security enabled: -``` -{ - "jsonrpc": "2.0", - "method": "query", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" - }, - "input": { - "function":"query", - "args":["a"] - }, - "secureContext": "lukas" - }, - "id": "5" -} -``` - -##### 6.2.1.4 Network API - -Use the Network API to retrieve information about the network of peer nodes comprising the blockchain fabric. - -The /network/peers endpoint returns a list of all existing network connections for the target peer node. The list includes both validating and non-validating peers. The list of peers is returned as type `PeersMessage`, containing an array of `PeerEndpoint`, defined in section [3.1.1](#311-discovery-messages). - -``` -message PeersMessage { - repeated PeerEndpoint peers = 1; -} -``` - -Network Request: -``` -GET host:port/network/peers -``` - -Network Response: -``` -{ - "peers": [ - { - "ID": { - "name": "vp1" - }, - "address": "172.17.0.4:7051", - "type": 1, - "pkiID": "rUA+vX2jVCXev6JsXDNgNBMX03IV9mHRPWo6h6SI0KLMypBJLd+JoGGlqFgi+eq/" - }, - { - "ID": { - "name": "vp3" - }, - "address": "172.17.0.5:7051", - "type": 1, - "pkiID": "OBduaZJ72gmM+B9wp3aErQlofE0ulQfXfTHh377ruJjOpsUn0MyvsJELUTHpAbHI" - }, - { - "ID": { - "name": "vp2" - }, - "address": "172.17.0.6:7051", - "type": 1, - "pkiID": "GhtP0Y+o/XVmRNXGF6pcm9KLNTfCZp+XahTBqVRmaIumJZnBpom4ACayVbg4Q/Eb" - } - ] -} -``` - -##### 6.2.1.5 Registrar API (member services) - -* **POST /registrar** -* **GET /registrar/{enrollmentID}** -* **DELETE /registrar/{enrollmentID}** -* **GET /registrar/{enrollmentID}/ecert** -* **GET /registrar/{enrollmentID}/tcert** - -Use the Registrar APIs to manage end user registration with the certificate authority (CA). These API endpoints are used to register a user with the CA, determine whether a given user is registered, and to remove any login tokens for a target user from local storage, preventing them from executing any further transactions. The Registrar APIs are also used to retrieve user enrollment and transaction certificates from the system. - -The `/registrar` endpoint is used to register a user with the CA. The required Secret payload is defined below. The response to the registration request is either a confirmation of successful registration or an error, containing a reason for the failure. - -``` -message Secret { - string enrollId = 1; - string enrollSecret = 2; -} -``` - -* `enrollId` - Enrollment ID with the certificate authority. -* `enrollSecret` - Enrollment password with the certificate authority. - -Enrollment Request: -``` -POST host:port/registrar - -{ - "enrollId": "lukas", - "enrollSecret": "NPKYL39uKbkj" -} -``` - -Enrollment Response: -``` -{ - "OK": "Login successful for user 'lukas'." -} -``` - -The `GET /registrar/{enrollmentID}` endpoint is used to confirm whether a given user is registered with the CA. If so, a confirmation will be returned. Otherwise, an authorization error will result. - -Verify Enrollment Request: -``` -GET host:port/registrar/jim -``` - -Verify Enrollment Response: -``` -{ - "OK": "User jim is already logged in." -} -``` - -Verify Enrollment Request: -``` -GET host:port/registrar/alex -``` - -Verify Enrollment Response: -``` -{ - "Error": "User alex must log in." -} -``` - -The `DELETE /registrar/{enrollmentID}` endpoint is used to delete login tokens for a target user. If the login tokens are deleted successfully, a confirmation will be returned. Otherwise, an authorization error will result. No payload is required for this endpoint. - -Remove Enrollment Request: -``` -DELETE host:port/registrar/lukas -``` - -Remove Enrollment Response: -``` -{ - "OK": "Deleted login token and directory for user lukas." -} -``` - -The `GET /registrar/{enrollmentID}/ecert` endpoint is used to retrieve the enrollment certificate of a given user from local storage. If the target user has already registered with the CA, the response will include a URL-encoded version of the enrollment certificate. If the target user has not yet registered, an error will be returned. If the client wishes to use the returned enrollment certificate after retrieval, keep in mind that it must be URL-decoded. - -Enrollment Certificate Retrieval Request: -``` -GET host:port/registrar/jim/ecert -``` - -Enrollment Certificate Retrieval Response: -``` -{ - "OK": "-----BEGIN+CERTIFICATE-----%0AMIIBzTCCAVSgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwNPQkMwHhcNMTYwMTIxMDYzNjEwWhcNMTYwNDIw%0AMDYzNjEwWjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNP%0AQkMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARSLgjGD0omuJKYrJF5ClyYb3sGEGTU%0AH1mombSAOJ6GAOKEULt4L919sbSSChs0AEvTX7UDf4KNaKTrKrqo4khCoboMg1VS%0AXVTTPrJ%2BOxSJTXFZCohVgbhWh6ZZX2tfb7%2BjUDBOMA4GA1UdDwEB%2FwQEAwIHgDAM%0ABgNVHRMBAf8EAjAAMA0GA1UdDgQGBAQBAgMEMA8GA1UdIwQIMAaABAECAwQwDgYG%0AUQMEBQYHAQH%2FBAE0MAoGCCqGSM49BAMDA2cAMGQCMGz2RR0NsJOhxbo0CeVts2C5%0A%2BsAkKQ7v1Llbg78A1pyC5uBmoBvSnv5Dd0w2yOmj7QIwY%2Bn5pkLiwisxWurkHfiD%0AxizmN6vWQ8uhTd3PTdJiEEckjHKiq9pwD%2FGMt%2BWjP7zF%0A-----END+CERTIFICATE-----%0A" -} -``` - -The `/registrar/{enrollmentID}/tcert` endpoint retrieves the transaction certificates for a given user that has registered with the certificate authority. If the user has registered, a confirmation message will be returned containing an array of URL-encoded transaction certificates. Otherwise, an error will result. The desired number of transaction certificates is specified with the optional 'count' query parameter. The default number of returned transaction certificates is 1; and 500 is the maximum number of certificates that can be retrieved with a single request. If the client wishes to use the returned transaction certificates after retrieval, keep in mind that they must be URL-decoded. - -Transaction Certificate Retrieval Request: -``` -GET host:port/registrar/jim/tcert -``` - -Transaction Certificate Retrieval Response: -``` -{ - "OK": [ - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQfwJORRED9RAsmSl%2FEowq1STBb%0A%2FoFteymZ96RUr%2BsKmF9PNrrUNvFZFhvukxZZjqhEcGiQqFyRf%2FBnVN%2BbtRzMo38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwSRWQFmErr0SmQO9AFP4GJYzQ%0APQMmcsCjKiJf%2Bw1df%2FLnXunCsCUlf%2FalIUaeSrT7MAoGCCqGSM49BAMDA0gAMEUC%0AIQC%2FnE71FBJd0hwNTLXWmlCJff4Yi0J%2BnDi%2BYnujp%2Fn9nQIgYWg0m0QFzddyJ0%2FF%0AKzIZEJlKgZTt8ZTlGg3BBrgl7qY%3D%0A-----END+CERTIFICATE-----%0A" - ] -} -``` - -Transaction Certificate Retrieval Request: -``` -GET host:port/registrar/jim/tcert?count=5 -``` - -Transaction Certificate Retrieval Response: -``` -{ - "OK": [ - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A" - ] -} -``` - -##### 6.2.1.6 Transactions API - -* **GET /transactions/{UUID}** - -Use the Transaction API to retrieve an individual transaction matching the UUID from the blockchain. The returned transaction message is defined in section [3.1.2.1](#3121-transaction-data-structure). - -Transaction Retrieval Request: -``` -GET host:port/transactions/f5978e82-6d8c-47d1-adec-f18b794f570e -``` - -Transaction Retrieval Response: -``` -{ - "type": 3, - "chaincodeID": "EgRteWNj", - "payload": "Ch4IARIGEgRteWNjGhIKBmludm9rZRIBYRIBYhICMTA=", - "uuid": "f5978e82-6d8c-47d1-adec-f18b794f570e", - "timestamp": { - "seconds": 1453758316, - "nanos": 206716775 - }, - "cert": "MIIB/zCCAYWgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMTI1MjE0MTE3WhcNMTYwNDI0MjE0MTE3WjArMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQ4wDAYDVQQDEwVsdWthczB2MBAGByqGSM49AgEGBSuBBAAiA2IABC/BBkt8izf6Ew8UDd62EdWFikJhyCPY5VO9Wxq9JVzt3D6nubx2jO5JdfWt49q8V1Aythia50MZEDpmKhtM6z7LHOU1RxuxdjcYDOvkNJo6pX144U4N1J8/D3A+97qZpKN/MH0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDA9BgYqAwQFBgcBAf8EMABNbPHZ0e/2EToi0H8mkouuUDwurgBYuUB+vZfeMewBre3wXG0irzMtfwHlfECRDDAKBggqhkjOPQQDAwNoADBlAjAoote5zYFv91lHzpbEwTfJL/+r+CG7oMVFUFuoSlvBSCObK2bDIbNkW4VQ+ZC9GTsCMQC5GCgy2oZdHw/x7XYzG2BiqmRkLRTiCS7vYCVJXLivU65P984HopxW0cEqeFM9co0=", - "signature": "MGUCMCIJaCT3YRsjXt4TzwfmD9hg9pxYnV13kWgf7e1hAW5Nar//05kFtpVlq83X+YtcmAIxAK0IQlCgS6nqQzZEGCLd9r7cg1AkQOT/RgoWB8zcaVjh3bCmgYHsoPAPgMsi3TJktg==" -} -``` - -### 6.3 CLI - -The CLI includes a subset of the available APIs to enable developers to quickly test and debug chaincodes or query for status of transactions. CLI is implemented in Golang and operable on multiple OS platforms. The currently available CLI commands are summarized in the following section. - -#### 6.3.1 CLI Commands - -To see what CLI commands are currently available in the implementation, execute the following: - - $ peer - -You will receive a response similar to below: - -``` - Usage: - peer [command] - - Available Commands: - node node specific commands. - network network specific commands. - chaincode chaincode specific commands. - help Help about any command - - Flags: - -h, --help[=false]: help for peer - --logging-level="": Default logging level and overrides, see core.yaml for full syntax - - Use "peer [command] --help" for more information about a command. -``` - -Some of the available command line arguments for the `peer` command are listed below: - -* `-c` - constructor: function to trigger in order to initialize the chaincode state upon deployment. - -* `-l` - language: specifies the implementation language of the chaincode. Currently, only Golang is supported. - -* `-n` - name: chaincode identifier returned from the deployment transaction. Must be used in subsequent invoke and query transactions. - -* `-p` - path: identifies chaincode location in the local file system. Must be used as a parameter in the deployment transaction. - -* `-u` - username: enrollment ID of a logged in user invoking the transaction. - -Not all of the above commands are fully implemented in the current release. The fully supported commands that are helpful for chaincode development and debugging are described below. - -Note, that any configuration settings for the peer node listed in the `core.yaml` configuration file, which is the configuration file for the `peer` process, may be modified on the command line with an environment variable. For example, to set the `peer.id` or the `peer.addressAutoDetect` settings, one may pass the `CORE_PEER_ID=vp1` and `CORE_PEER_ADDRESSAUTODETECT=true` on the command line. - -##### 6.3.1.1 node start - -The CLI `node start` command will execute the peer process in either the development or production mode. The development mode is meant for running a single peer node locally, together with a local chaincode deployment. This allows a chaincode developer to modify and debug their code without standing up a complete network. An example for starting the peer in development mode follows: - -``` -peer node start --peer-chaincodedev -``` - -To start the peer process in production mode, modify the above command as follows: - -``` -peer node start -``` - -##### 6.3.1.2 network login - -The CLI `network login` command will login a user, that is already registered with the CA, through the CLI. To login through the CLI, issue the following command, where `username` is the enrollment ID of a registered user. - -``` -peer network login -``` - -The example below demonstrates the login process for user `jim`. - -``` -peer network login jim -``` - -The command will prompt for a password, which must match the enrollment password for this user registered with the certificate authority. If the password entered does not match the registered password, an error will result. - -``` -22:21:31.246 [main] login -> INFO 001 CLI client login... -22:21:31.247 [main] login -> INFO 002 Local data store for client loginToken: /var/hyperledger/production/client/ -Enter password for user 'jim': ************ -22:21:40.183 [main] login -> INFO 003 Logging in user 'jim' on CLI interface... -22:21:40.623 [main] login -> INFO 004 Storing login token for user 'jim'. -22:21:40.624 [main] login -> INFO 005 Login successful for user 'jim'. -``` - -You can also pass a password for the user with `-p` parameter. An example is below. - -``` -peer network login jim -p 123456 -``` - -##### 6.3.1.3 chaincode deploy - -The CLI `deploy` command creates the docker image for the chaincode and subsequently deploys the package to the validating peer. An example is below. - -``` -peer chaincode deploy -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' -``` - -With security enabled, the command must be modified to pass an enrollment id of a logged in user with the `-u` parameter. An example is below. - -``` -peer chaincode deploy -u jim -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' -``` - -**Note:** If your GOPATH environment variable contains more than one element, the chaincode must be found in the first one or deployment will fail. - -##### 6.3.1.4 chaincode invoke - -The CLI `invoke` command executes a specified function within the target chaincode. An example is below. - -``` -peer chaincode invoke -n -c '{"Function": "invoke", "Args": ["a", "b", "10"]}' -``` - -With security enabled, the command must be modified to pass an enrollment id of a logged in user with the `-u` parameter. An example is below. - -``` -peer chaincode invoke -u jim -n -c '{"Function": "invoke", "Args": ["a", "b", "10"]}' -``` - -##### 6.3.1.5 chaincode query - -The CLI `query` command triggers a specified query method within the target chaincode. The response that is returned depends on the chaincode implementation. An example is below. - -``` -peer chaincode query -l golang -n -c '{"Function": "query", "Args": ["a"]}' -``` - -With security enabled, the command must be modified to pass an enrollment id of a logged in user with the `-u` parameter. An example is below. - -``` -peer chaincode query -u jim -l golang -n -c '{"Function": "query", "Args": ["a"]}' -``` - - -## 7. Application Model - -### 7.1 Composition of an Application - - --- - - - -
-An application follows a MVC-B architecture – Model, View, Control, BlockChain. -

- -

    -
  • VIEW LOGIC – Mobile or Web UI interacting with control logic.
  • -
  • CONTROL LOGIC – Coordinates between UI, Data Model and APIs to drive transitions and chain-code.
  • -
  • DATA MODEL – Application Data Model – manages off-chain data, including Documents and large files.
  • -
  • BLOCKCHAIN LOGIC – Blockchain logic are extensions of the Controller Logic and Data Model, into the Blockchain realm. Controller logic is enhanced by chaincode, and the data model is enhanced with transactions on the blockchain.
  • -
-

-For example, a Bluemix PaaS application using Node.js might have a Web front-end user interface or a native mobile app with backend model on Cloudant data service. The control logic may interact with 1 or more chaincodes to process transactions on the blockchain. - -

- -### 7.2 Sample Application - - -## 8. Future Directions - -### 8.1 Enterprise Integration - -### 8.2 Performance and Scalability - -### 8.3 Additional Consensus Plugins - -### 8.4 Additional Languages - -### 9.1 Authors -The following authors have written sections of this document: Binh Q Nguyen, Elli Androulaki, Angelo De Caro, Sheehan Anderson, Manish Sethi, Thorsten Kramp, Alessandro Sorniotti, Marko Vukolic, Florian Simon Schubert, Jason K Yellick, Konstantinos Christidis, Srinivasan Muralidharan, Anna D Derbakova, Dulce Ponceleon, David Kravitz, Diego Masini. - -### 9.2 Reviewers -The following reviewers have contributed to this document: Frank Lu, John Wolpert, Bishop Brock, Nitin Gaur, Sharon Weed, Konrad Pabjan. - -### 9.3 Acknowledgements -The following contributors have provided invaluable technical input to this specification: -Gennaro Cuomo, Joseph A Latone, Christian Cachin - -## 10. References - -- [1] Miguel Castro, Barbara Liskov: Practical Byzantine fault tolerance and proactive recovery. ACM Trans. Comput. Syst. 20(4): 398-461 (2002) - -- [2] Christian Cachin, Rachid Guerraoui, Luís E. T. Rodrigues: Introduction to Reliable and Secure Distributed Programming (2. ed.). Springer 2011, ISBN 978-3-642-15259-7, pp. I-XIX, 1-367 - -- [3] Tushar Deepak Chandra, Vassos Hadzilacos, Sam Toueg: The Weakest Failure Detector for Solving Consensus. J. ACM 43(4): 685-722 (1996) - -- [4] Cynthia Dwork, Nancy A. Lynch, Larry J. Stockmeyer: Consensus in the presence of partial synchrony. J. ACM 35(2): 288-323 (1988) - -- [5] Manos Kapritsos, Yang Wang, Vivien Quéma, Allen Clement, Lorenzo Alvisi, Mike Dahlin: All about Eve: Execute-Verify Replication for Multi-Core Servers. OSDI 2012: 237-250 - -- [6] Pierre-Louis Aublin, Rachid Guerraoui, Nikola Knezevic, Vivien Quéma, Marko Vukolic: The Next 700 BFT Protocols. ACM Trans. Comput. Syst. 32(4): 12:1-12:45 (2015) - -- [7] Christian Cachin, Simon Schubert, Marko Vukolić: [Non-determinism in Byzantine Fault-Tolerant Replication](http://arxiv.org/abs/1603.07351) diff --git a/docs/protocol-spec_zh.md b/docs/protocol-spec_zh.md deleted file mode 100755 index a822b18e243..00000000000 --- a/docs/protocol-spec_zh.md +++ /dev/null @@ -1,2786 +0,0 @@ -# 协议规范 - -## 前言 -这份文档是带有权限的区块链的工业界实现的协议规范。它不会详细的解释实现细节,而是描述系统和应用之间的接口和关系。 - -### 目标读者 -这份规范的目标读者包括: - -- 想实现符合这份规范的区块链的厂商 -- 想扩展 fabric 功能的工具开发者 -- 想利用区块链技术来丰富他们应用的应用开发者 - -### 作者 -下面这些作者编写了这份分档: Binh Q Nguyen, Elli Androulaki, Angelo De Caro, Sheehan Anderson, Manish Sethi, Thorsten Kramp, Alessandro Sorniotti, Marko Vukolic, Florian Simon Schubert, Jason K Yellick, Konstantinos Christidis, Srinivasan Muralidharan, Anna D Derbakova, Dulce Ponceleon, David Kravitz, Diego Masini. - -### 评审 -下面这些评审人评审了这份文档: Frank Lu, John Wolpert, Bishop Brock, Nitin Gaur, Sharon Weed, Konrad Pabjan. - -### 致谢 -下面这些贡献者对这份规范提供了技术支持: -Gennaro Cuomo, Joseph A Latone, Christian Cachin -________________________________________________________ - -## 目录 -#### 1. 介绍 - - - 1.1 什么是 fabric ? - - 1.2 为什么是 fabric ? - - 1.3 术语 - -#### 2. Fabric - - - 2.1 架构 - - 2.1.1 Membership 服务 - - 2.1.2 Blockchain 服务 - - 2.1.3 Chaincode 服务 - - 2.1.4 事件 - - 2.1.5 应用程序接口 - - 2.1.6 命令行界面 - - 2.2 拓扑 - - 2.2.1 单验证 Peer - - 2.2.2 多验证 Peers - - 2.2.3 多链 - -#### 3. 协议 - - - 3.1 消息 - - 3.1.1 发现消息 - - 3.1.2 交易消息 - - 3.1.2.1 交易数据结构 - - 3.1.2.2 交易规范 - - 3.1.2.3 交易部署 - - 3.1.2.4 交易调用 - - 3.1.2.5 交易查询 - - 3.1.3 同步消息 - - 3.1.4 共识消息 - - 3.2 总账 - - 3.2.1 区块链 - - 3.2.1.1 块 - - 3.2.1.2 块 Hashing - - 3.2.1.3 非散列数据(NonHashData) - - 3.2.1.4 交易 - - 3.2.2 世界状态(World State) - - 3.2.2.1 世界状态的 Hashing - - 3.2.2.1.1 Bucket-tree - - 3.3 Chaincode - - 3.3.1 Virtual Machine 实例化 - - 3.3.2 Chaincode 协议 - - 3.3.2.1 Chaincode 部署 - - 3.3.2.2 Chaincode 调用 - - 3.3.2.3 Chaincode 查询 - - 3.3.2.4 Chaincode 状态 - - 3.4 可插拔的共识框架 - - 3.4.1 共识者接口 - - 3.4.2 共识程序接口 - - 3.4.3 Inquirer 接口 - - 3.4.4 Communicator 接口 - - 3.4.5 SecurityUtils 接口 - - 3.4.6 LedgerStack 接口 - - 3.4.7 Executor 接口 - - 3.4.7.1 开始批量交易 - - 3.4.7.2 执行交易 - - 3.4.7.3 提交与回滚交易 - - 3.4.8 Ledger 接口 - - 3.4.8.1 ReadOnlyLedger 接口 - - 3.4.8.2 UtilLedger 接口 - - 3.4.8.3 WritableLedger 接口 - - 3.4.9 RemoteLedgers 接口 - - 3.4.10 Controller 包 - - 3.4.11 Helper 包 - - 3.5 事件 - - 3.5.1 事件流 - - 3.5.2 事件结构 - - 3.5.3 事件适配器 - -#### 4. 安全 - - 4. 安全 - - 4.1 商业安全需求 - - 4.2 使用成员管理的用户隐私 - - 4.2.1 用户/客户端注册过程 - - 4.2.2 过期和废止证书 - - 4.3 基础设施层面提供的交易安全 - - 4.3.1 交易的安全生命周期 - - 4.3.2 交易保密性 - - 4.3.2.1 针对用户的保密 - - 4.3.2.2 针对验证器的保密 - - 4.3.3 防重放攻击 - - 4.4 应用的访问控制功能 - - 4.4.1 调用访问控制 - - 4.4.2 读访问控制 - - 4.5 在线钱包服务 - - 4.6 网络安全(TLS) - - 4.7 当前版本的限制 - - 4.7.1 简化客户端 - - 4.7.2 简化交易保密 - -#### 5. 拜占庭共识 - - 5.1 概览 - - 5.2 Core PBFT - -#### 6. 应用编程接口 - - 6.1 REST 服务 - - 6.2 REST API - - 6.3 CLI - -#### 7. 应用模型 - - 7.1 应用组成 - - 7.2 应用样例 - -#### 8. 未来发展方向 - - 8.1 企业集成 - - 8.2 性能与可扩展性 - - 8.3 附加的共识插件 - - 8.4 附加的语言 - -#### 9. References - -________________________________________________________ - -## 1. 介绍 -这份文档规范了适用于工业界的区块链的概念,架构和协议。 - -### 1.1 什么是 fabric? -fabric 是在系统中数字事件,交易调用,不同参与者共享的总账。总账只能通过共识的参与者来更新,而且一旦被记录,信息永远不能被修改。每一个记录的事件都可以根据参与者的协议进行加密验证。 - -交易是安全的,私有的并且可信的。每个参与者通过向网络membership服务证明自己的身份来访问系统。交易是通过发放给各个的参与者,不可连接的,提供在网络上完全匿名的证书来生成的。交易内容通过复杂的密钥加密来保证只有参与者才能看到,确保业务交易私密性。 - -总账可以按照规定规则来审计全部或部分总账分录。在与参与者合作中,审计员可以通过基于时间的证书来获得总账的查看,连接交易来提供实际的资产操作。 - -fabric 是区块链技术的一种实现,比特币是可以在fabric上构建的一种简单应用。它通过模块化的架构来允许组件的“插入-运行”来实现这份协议规范。它具有强大的容器技术来支持任何主流的语言来开发智能合约。利用熟悉的和被证明的技术是fabric的座右铭。 - -### 1.2 为什么是 fabric? - -早期的区块链技术提供一个目的集合,但是通常对具体的工业应用支持的不是很好。为了满足现代市场的需求,fabric 是基于工业关注点针对特定行业的多种多样的需求来设计的,并引入了这个领域内的开拓者的经验,如扩展性。fabric 为权限网络,隐私,和多个区块链网络的私密信息提供一种新的方法。 - -### 1.3 术语 -以下术语在此规范的有限范围内定义,以帮助读者清楚准确的了解这里所描述的概念。 - -**交易(Transaction)** 是区块链上执行功能的一个请求。功能是使用**链码(Chaincode)**来实现的。 - -**交易者(Transactor)** 是向客户端应用这样发出交易的实体。 - -**总账(Ledger)** 是一系列包含交易和当前**世界状态(World State)**的加密的链接块。 - -**世界状态(World State)** 是包含交易执行结果的变量集合。 - -**链码(Chaincode)** 是作为交易的一部分保存在总账上的应用级的代码(如[智能合约](https://en.wikipedia.org/wiki/Smart_contract))。链码运行的交易可能会改变世界状态。 - -**验证Peer(Validating Peer)** 是网络中负责达成共识,验证交易并维护总账的一个计算节点。 - -**非验证Peer(Non-validating Peer)** 是网络上作为代理把交易员连接到附近验证节点的计算节点。非验证Peer只验证交易但不执行它们。它还承载事件流服务和REST服务。 - -**带有权限的总账(Permissioned Ledger)** 是一个由每个实体或节点都是网络成员所组成的区块链网络。匿名节点是不允许连接的。 - -**隐私(Privacy)** 是链上的交易者需要隐瞒自己在网络上身份。虽然网络的成员可以查看交易,但是交易在没有得到特殊的权限前不能连接到交易者。 - -**保密(Confidentiality)** 是交易的内容不能被非利益相关者访问到的功能。 - -**可审计性(Auditability)** 作为商业用途的区块链需要遵守法规,很容易让监管机构审计交易记录。所以区块链是必须的。 - - -## 2. Fabric - -fabric是由下面这个小节所描述的核心组件所组成的。 - -### 2.1 架构 -这个架构参考关注在三个类别中:会员(Membership),区块链(Blockchan)和链码(chaincode)。这些类别是逻辑结构,而不是物理上的把不同的组件分割到独立的进程,地址空间,(虚拟)机器中。 - -![Reference architecture](images/refarch.png) - -### 2.1.1 成员服务 -成员服务为网络提供身份管理,隐私,保密和可审计性的服务。在一个不带权限的区块链中,参与者是不需要被授权的,且所有的节点都可以同样的提交交易并把它们汇集到可接受的块中,既:它们没有角色的区分。成员服务通过公钥基础设施(Public Key Infrastructure -(PKI))和去中心化的/共识技术使得不带权限的区块链变成带权限的区块链。在后者中,通过实体注册来获得长时间的,可能根据实体类型生成的身份凭证(登记证书enrollment certificates)。在用户使用过程中,这样的证书允许交易证书颁发机构(Transaction Certificate Authority -(TCA))颁发匿名证书。这样的证书,如交易证书,被用来对提交交易授权。交易证书存储在区块链中,并对审计集群授权,否则交易是不可链接的。 - -### 2.1.2 区块链服务 -区块链服务通过 HTTP/2 上的点对点(peer-to-peer)协议来管理分布式总账。为了提供最高效的哈希算法来维护世界状态的复制,数据结构进行了高度的优化。每个部署中可以插入和配置不同的共识算法(PBFT, Raft, PoW, PoS)。 - -### 2.1.3 链码服务 -链码服务提供一个安全的,轻量的沙箱在验证节点上执行链码。环境是一个“锁定的”且安全的包含签过名的安全操作系统镜像和链码语言,Go,Java 和 Node.js 的运行时和 SDK 层。可以根据需要来启用其他语言。 - -### 2.1.4 事件 -验证 peers 和链码可以向在网络上监听并采取行动的应用发送事件。这是一些预定义好的事件集合,链码可以生成客户化的事件。事件会被一个或多个事件适配器消费。之后适配器可能会把事件投递到其他设备,如 Web hooks 或 Kafka。 - -### 2.1.5 应用编程接口(API) -fabric的主要接口是 REST API,并通过 Swagger 2.0 来改变。API 允许注册用户,区块链查询和发布交易。链码与执行交易的堆间的交互和交易的结果查询会由 API 集合来规范。 - -### 2.1.6 命令行界面(CLI) -CLI包含REST API的一个子集使得开发者能更快的测试链码或查询交易状态。CLI 是通过 Go 语言来实现,并可在多种操作系统上操作。 - -### 2.2 拓扑 -fabric 的一个部署是由成员服务,多个验证 peers、非验证 peers 和一个或多个应用所组成一个链。也可以有多个链,各个链具有不同的操作参数和安全要求。 - -### 2.2.1 单验证Peer -功能上讲,一个非验证 peer 是验证 peer 的子集;非验证 peer 上的功能都可以在验证 peer 上启用,所以在最简单的网络上只有一个验证peer组成。这个配置通常使用在开发环境:单个验证 peer 在编辑-编译-调试周期中被启动。 - -![Single Validating Peer](images/top-single-peer.png) - -单个验证 peer 不需要共识,默认情况下使用`noops`插件来处理接收到的交易。这使得在开发中,开发人员能立即收到返回。 - -### 2.2.2 多验证 Peer -生产或测试网络需要有多个验证和非验证 peers 组成。非验证 peer 可以为验证 peer 分担像 API 请求处理或事件处理这样的压力。 - -![Multiple Validating Peers](images/top-multi-peer.png) - -网状网络(每个验证peer需要和其它验证peer都相连)中的验证 peer 来传播信息。一个非验证 peer 连接到附近的,允许它连接的验证 peer。当应用可能直接连接到验证 peer 时,非验证 peer 是可选的。 - -### 2.2.3 多链 -验证和非验证 peer 的各个网络组成一个链。可以根据不同的需求创建不同的链,就像根据不同的目的创建不同的 Web 站点。 - - -## 3. 协议 -fabric的点对点(peer-to-peer)通信是建立在允许双向的基于流的消息[gRPC](http://www.grpc.io/docs/)上的。它使用[Protocol Buffers](https://developers.google.com/protocol-buffers)来序列化peer之间传输的数据结构。Protocol buffers 是语言无关,平台无关并具有可扩展机制来序列化结构化的数据的技术。数据结构,消息和服务是使用 [proto3 language](https://developers.google.com/protocol-buffers/docs/proto3)注释来描述的。 - -### 3.1 消息 -消息在节点之间通过`Message`proto 结构封装来传递的,可以分为 4 种类型:发现(Discovery), 交易(Transaction), 同步(Synchronization)和共识(Consensus)。每种类型在`payload`中定义了多种子类型。 - -``` -message Message { - enum Type { - UNDEFINED = 0; - - DISC_HELLO = 1; - DISC_DISCONNECT = 2; - DISC_GET_PEERS = 3; - DISC_PEERS = 4; - DISC_NEWMSG = 5; - - CHAIN_STATUS = 6; - CHAIN_TRANSACTION = 7; - CHAIN_GET_TRANSACTIONS = 8; - CHAIN_QUERY = 9; - - SYNC_GET_BLOCKS = 11; - SYNC_BLOCKS = 12; - SYNC_BLOCK_ADDED = 13; - - SYNC_STATE_GET_SNAPSHOT = 14; - SYNC_STATE_SNAPSHOT = 15; - SYNC_STATE_GET_DELTAS = 16; - SYNC_STATE_DELTAS = 17; - - RESPONSE = 20; - CONSENSUS = 21; - } - Type type = 1; - bytes payload = 2; - google.protobuf.Timestamp timestamp = 3; -} -``` -`payload`是由不同的消息类型所包含的不同的像`Transaction`或`Response`这样的对象的不透明的字节数组。例如:`type`为`CHAIN_TRANSACTION`那么`payload`就是一个`Transaction`对象。 - -### 3.1.1 发现消息 -在启动时,如果`CORE_PEER_DISCOVERY_ROOTNODE`被指定,那么 peer 就会运行发现协议。`CORE_PEER_DISCOVERY_ROOTNODE`是网络(任意peer)中扮演用来发现所有 peer 的起点角色的另一个 peer 的 IP 地址。协议序列以`payload`是一个包含: - -``` -message HelloMessage { - PeerEndpoint peerEndpoint = 1; - uint64 blockNumber = 2; -} -message PeerEndpoint { - PeerID ID = 1; - string address = 2; - enum Type { - UNDEFINED = 0; - VALIDATOR = 1; - NON_VALIDATOR = 2; - } - Type type = 3; - bytes pkiID = 4; -} - -message PeerID { - string name = 1; -} -``` - -这样的端点的`HelloMessage`对象的`DISC_HELLO`消息开始的。 - - -**域的定义:** - -- `PeerID` 是在启动时或配置文件中定义的 peer 的任意名字 -- `PeerEndpoint` 描述了端点和它是验证还是非验证 peer -- `pkiID` 是 peer 的加密ID -- `address` 以`ip:port`这样的格式表示的 peer 的主机名或IP和端口 -- `blockNumber` 是 peer 的区块链的当前的高度 - -如果收到的`DISC_HELLO` 消息的块的高度比当前 peer 的块的高度高,那么它马上初始化同步协议来追上当前的网络。 - -`DISC_HELLO`之后,peer 会周期性的发送`DISC_GET_PEERS`来发现任意想要加入网络的 peer。收到`DISC_GET_PEERS`后,peer 会发送`payload` -包含`PeerEndpoint`的数组的`DISC_PEERS`作为响应。这是不会使用其它的发现消息类型。 - -### 3.1.2 交易消息 -有三种不同的交易类型:部署(Deploy),调用(Invoke)和查询(Query)。部署交易向链上安装指定的链码,调用和查询交易会调用部署号的链码。另一种需要考虑的类型是创建(Create)交易,其中部署好的链码是可以在链上实例化并寻址的。这种类型在写这份文档时还没有被实现。 - - -### 3.1.2.1 交易的数据结构 - -`CHAIN_TRANSACTION`和`CHAIN_QUERY`类型的消息会在`payload`带有`Transaction`对象: - -``` -message Transaction { - enum Type { - UNDEFINED = 0; - CHAINCODE_DEPLOY = 1; - CHAINCODE_INVOKE = 2; - CHAINCODE_QUERY = 3; - CHAINCODE_TERMINATE = 4; - } - Type type = 1; - string uuid = 5; - bytes chaincodeID = 2; - bytes payloadHash = 3; - - ConfidentialityLevel confidentialityLevel = 7; - bytes nonce = 8; - bytes cert = 9; - bytes signature = 10; - - bytes metadata = 4; - google.protobuf.Timestamp timestamp = 6; -} - -message TransactionPayload { - bytes payload = 1; -} - -enum ConfidentialityLevel { - PUBLIC = 0; - CONFIDENTIAL = 1; -} - -``` - -**域的定义:** -- `type` - 交易的类型, 为1时表示: - - `UNDEFINED` - 为未来的使用所保留. - - `CHAINCODE_DEPLOY` - 代表部署新的链码. - - `CHAINCODE_INVOKE` - 代表一个链码函数被执行并修改了世界状态 - - `CHAINCODE_QUERY` - 代表一个链码函数被执行并可能只读取了世界状态 - - `CHAINCODE_TERMINATE` - 标记的链码不可用,所以链码中的函数将不能被调用 -- `chaincodeID` - 链码源码,路径,构造函数和参数哈希所得到的ID -- `payloadHash` - `TransactionPayload.payload`所定义的哈希字节. -- `metadata` - 应用可能使用的,由自己定义的任意交易相关的元数据 -- `uuid` - 交易的唯一ID -- `timestamp` - peer 收到交易时的时间戳 -- `confidentialityLevel` - 数据保密的级别。当前有两个级别。未来可能会有多个级别。 -- `nonce` - 为安全而使用 -- `cert` - 交易者的证书 -- `signature` - 交易者的签名 -- `TransactionPayload.payload` - 交易的payload所定义的字节。由于payload可以很大,所以交易消息只包含payload的哈希 - -交易安全的详细信息可以在第四节找到 - -### 3.1.2.2 交易规范 -一个交易通常会关联链码定义及其执行环境(像语言和安全上下文)的链码规范。现在,有一个使用Go语言来编写链码的实现。将来可能会添加新的语言。 - -``` -message ChaincodeSpec { - enum Type { - UNDEFINED = 0; - GOLANG = 1; - NODE = 2; - } - Type type = 1; - ChaincodeID chaincodeID = 2; - ChaincodeInput ctorMsg = 3; - int32 timeout = 4; - string secureContext = 5; - ConfidentialityLevel confidentialityLevel = 6; - bytes metadata = 7; -} - -message ChaincodeID { - string path = 1; - string name = 2; -} - -message ChaincodeInput { - string function = 1; - repeated string args = 2; -} -``` - -**域的定义:** -- `chaincodeID` - 链码源码的路径和名字 -- `ctorMsg` - 调用的函数名及参数 -- `timeout` - 执行交易所需的时间(以毫秒表示) -- `confidentialityLevel` - 这个交易的保密级别 -- `secureContext` - 交易者的安全上下文 -- `metadata` - 应用想要传递下去的任何数据 - -当 peer 收到`chaincodeSpec`后以合适的交易消息包装它并广播到网络 - -### 3.1.2.3 部署交易 -部署交易的类型是`CHAINCODE_DEPLOY`,且它的payload包含`ChaincodeDeploymentSpec`对象。 - -``` -message ChaincodeDeploymentSpec { - ChaincodeSpec chaincodeSpec = 1; - google.protobuf.Timestamp effectiveDate = 2; - bytes codePackage = 3; -} -``` -**域的定义:** -- `chaincodeSpec` - 参看上面的3.1.2.2节. -- `effectiveDate` - 链码准备好可被调用的时间 -- `codePackage` - 链码源码的gzip - -当验证 peer 部署链码时,它通常会校验`codePackage`的哈希来保证交易被部署到网络后没有被篡改。 - -### 3.1.2.4 调用交易 - -调用交易的类型是`CHAINCODE_DEPLOY`,且它的payload包含`ChaincodeInvocationSpec`对象。 - -``` -message ChaincodeInvocationSpec { - ChaincodeSpec chaincodeSpec = 1; -} -``` - -### 3.1.2.5 查询交易 -查询交易除了消息类型是`CHAINCODE_QUERY`其它和调用交易一样 - -### 3.1.3 同步消息 -同步协议以3.1.1节描述的,当 peer 知道它自己的区块落后于其它 peer 或和它们不一样后所发起的。peer 广播`SYNC_GET_BLOCKS`,`SYNC_STATE_GET_SNAPSHOT`或`SYNC_STATE_GET_DELTAS`并分别接收`SYNC_BLOCKS`, `SYNC_STATE_SNAPSHOT`或 `SYNC_STATE_DELTAS`。 - -安装的共识插件(如:pbft)决定同步协议是如何被应用的。每个消息是针对具体的状态来设计的: - -**SYNC_GET_BLOCKS** 是一个`SyncBlockRange`对象,包含一个连续区块的范围的`payload`的请求。 - -``` -message SyncBlockRange { - uint64 correlationId = 1; - uint64 start = 2; - uint64 end = 3; -} -``` -接收peer使用包含 `SyncBlocks`对象的`payload`的`SYNC_BLOCKS`信息来响应 - -``` -message SyncBlocks { - SyncBlockRange range = 1; - repeated Block blocks = 2; -} -``` - -`start`和`end`标识包含的区块的开始和结束,返回区块的顺序由`start`和`end`的值定义。如:当`start`=3,`end`=5时区块的顺序将会是3,4,5。当`start`=5,`end`=3时区块的顺序将会是5,4,3。 - - -**SYNC_STATE_GET_SNAPSHOT** 请求当前世界状态的快照。 `payload`是一个`SyncStateSnapshotRequest`对象 - -``` -message SyncStateSnapshotRequest { - uint64 correlationId = 1; -} -``` - -`correlationId`是请求 peer 用来追踪响应消息的。接受 peer 回复`payload`为`SyncStateSnapshot`实例的`SYNC_STATE_SNAPSHOT`信息 - -``` -message SyncStateSnapshot { - bytes delta = 1; - uint64 sequence = 2; - uint64 blockNumber = 3; - SyncStateSnapshotRequest request = 4; -} -``` - -这条消息包含快照或以0开始的快照流序列中的一块。终止消息是len(delta) == 0的块 - -**SYNC_STATE_GET_DELTAS** 请求连续区块的状态变化。默认情况下总账维护500笔交易变化。 delta(j)是block(i)和block(j)之间的状态转变,其中i=j-1。 `payload`包含`SyncStateDeltasRequest`实例 - -``` -message SyncStateDeltasRequest { - SyncBlockRange range = 1; -} -``` -接收 peer 使用包含 `SyncStateDeltas`实例的`payload`的`SYNC_STATE_DELTAS`信息来响应 - -``` -message SyncStateDeltas { - SyncBlockRange range = 1; - repeated bytes deltas = 2; -} -``` -delta可能以顺序(从i到j)或倒序(从j到i)来表示状态转变 - -### 3.1.4 共识消息 -共识处理交易,一个`CONSENSUS`消息是由共识框架接收到`CHAIN_TRANSACTION`消息时在内部初始化的。框架把`CHAIN_TRANSACTION`转换为 `CONSENSUS`然后以相同的`payload`广播到验证 peer。共识插件接收这条消息并根据内部算法来处理。插件可能创建自定义的子类型来管理共识有穷状态机。3.4节会介绍详细信息。 - - -### 3.2 总账 - -总账由两个主要的部分组成,一个是区块链,一个是世界状态。区块链是在总账中的一系列连接好的用来记录交易的区块。世界状态是一个用来存储交易执行状态的键-值(key-value)数据库 - - -### 3.2.1 区块链 - -#### 3.2.1.1 区块 - -区块链是由一个区块链表定义的,每个区块包含它在链中前一个区块的哈希。区块包含的另外两个重要信息是它包含区块执行所有交易后的交易列表和世界状态的哈希 - -``` -message Block { - version = 1; - google.protobuf.Timestamp timestamp = 2; - bytes transactionsHash = 3; - bytes stateHash = 4; - bytes previousBlockHash = 5; - bytes consensusMetadata = 6; - NonHashData nonHashData = 7; -} - -message BlockTransactions { - repeated Transaction transactions = 1; -} -``` - -**域的定义:** -* `version` - 用来追踪协议变化的版本号 -* `timestamp` - 由区块提议者填充的时间戳 -* `transactionsHash` - 区块中交易的merkle root hash -* `stateHash` - 世界状态的merkle root hash -* `previousBlockHash` - 前一个区块的hash -* `consensusMetadata` - 共识可能会引入的一些可选的元数据 -* `nonHashData` - `NonHashData`消息会在计算区块的哈希前设置为nil,但是在数据库中存储为区块的一部分 -* `BlockTransactions.transactions` - 交易消息的数组,由于交易的大小,它们不会被直接包含在区块中 - -#### 3.2.1.2 区块哈希 - -* `previousBlockHash`哈希是通过下面算法计算的 - 1. 使用protocol buffer库把区块消息序列化为字节码 - - 2. 使用[FIPS 202](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf)描述的SHA3 SHAKE256算法来对序列化后的区块消息计算大小为512位的哈希值 - -* `transactionHash`是交易merkle树的根。定义merkle tree实现是一个代办 - -* `stateHash`在3.2.2.1节中定义. - -#### 3.2.1.3 非散列数据(NonHashData) - -NonHashData消息是用来存储不需要所有 peer 都具有相同值的块元数据。他们是建议值。 - -``` -message NonHashData { - google.protobuf.Timestamp localLedgerCommitTimestamp = 1; - repeated TransactionResult transactionResults = 2; -} - -message TransactionResult { - string uuid = 1; - bytes result = 2; - uint32 errorCode = 3; - string error = 4; -} -``` - -* `localLedgerCommitTimestamp` - 标识区块提交到本地总账的时间戳 - -* `TransactionResult` - 交易结果的数组 - -* `TransactionResult.uuid` - 交易的ID - -* `TransactionResult.result` - 交易的返回值 - -* `TransactionResult.errorCode` - 可以用来记录关联交易的错误信息的代码 - -* `TransactionResult.error` - 用来记录关联交易的错误信息的字符串 - - -#### 3.2.1.4 交易执行 - -一个交易定义了它们部署或执行的链码。区块中的所有交易都可以在记录到总账中的区块之前运行。当链码执行时,他们可能会改变世界状态。之后世界状态的哈希会被记录在区块中。 - - -### 3.2.2 世界状态 - -peer 的*世界状态*涉及到所有被部署的链码的*状态*集合。进一步说,链码的状态由键值对集合来表示。所以,逻辑上说,peer 的世界状态也是键值对的集合,其中键由元组`{chaincodeID, ckey}`组成。这里我们使用术语`key`来标识世界状态的键,如:元组`{chaincodeID, ckey}` ,而且我们使用`cKey`来标识链码中的唯一键。 - -为了下面描述的目的,假定`chaincodeID`是有效的utf8字符串,且`ckey`和`value`是一个或多个任意的字节的序列 - -#### 3.2.2.1 世界状态的哈希 -当网络活动时,很多像交易提交和同步 peer 这样的场合可能需要计算 peer 观察到的世界状态的加密-哈希。例如,共识协议可能需要保证网络中*最小*数量的 peer 观察到同样的世界状态。 - -因为计算世界状态的加密-哈希是一个非常昂贵的操作,组织世界状态来使得当它改变时能高效的计算加密-哈希是非常可取的。将来,可以根据不同的负载条件来设计不同的组织形式。 - -由于fabric是被期望在不同的负载条件下都能正常工作,所以需要一个可拔插的机制来支持世界状态的组织。 - -#### 3.2.2.1.1 Bucket-tree - -*Bucket-tree* 是世界状态的组织方式的实现。为了下面描述的目的,世界状态的键被表示成两个组件(`chaincodeID` and `ckey`) 的通过nil字节的级联,如:`key` = `chaincodeID`+`nil`+`cKey`。 - -这个方法的模型是一个*merkle-tree*在*hash table*桶的顶部来计算*世界状态*的加密-哈希 - -这个方法的核心是世界状态的*key-values*被假定存储在由预先决定的桶的数量(`numBuckets`)所组成的哈希表中。一个哈希函数(`hashFunction`) 被用来确定包含给定键的桶数量。注意`hashFunction`不代表SHA3这样的加密-哈希方法,而是决定给定的键的桶的数量的正规的编程语言散列函数。 - -为了对 merkle-tree建模,有序桶扮演了树上的叶子节点-编号最低的桶是树中的最左边的叶子节点。为了构造树的最后第二层,叶子节点的预定义数量 (`maxGroupingAtEachLevel`),从左边开始把每个这样的分组组合在一起,一个节点被当作组中所有叶子节点的共同父节点来插入到最后第二层中。注意最后的父节点的数量可能会少于`maxGroupingAtEachLevel`这个构造方式继续使用在更高的层级上直到树的根节点被构造。 - - - -下面这个表展示的在`{numBuckets=10009 and maxGroupingAtEachLevel=10}`的配置下会得到的树在不同层级上的节点数。 - -| Level | Number of nodes | -| ------------- |:---------------:| -| 0 | 1 | -| 1 | 2 | -| 2 | 11 | -| 3 | 101 | -| 4 | 1001 | -| 5 | 10009 | - -为了计算世界状态的加密-哈希,需要计算每个桶的加密-哈希,并假设它们是merkle-tree的叶子节点的加密-哈希。为了计算桶的加密-哈希,存储在桶中的键值对首先被序列化为字节码并在其上应用加密-哈希函数。为了序列化桶的键值对,所有具有公共chaincodeID前缀的键值对分别序列化并以chaincodeID的升序的方式追加在一起。为了序列化一个chaincodeID的键值对,会涉及到下面的信息: - - 1. chaincodeID的长度(chaincodeID的字节数) - - chaincodeID的utf8字节码 - - chaincodeID的键值对数量 - - 对于每个键值对(以ckey排序) - - ckey的长度 - - ckey的字节码 - - 值的长度 - - 值的字节码 - -对于上面列表的所有数值类型项(如:chaincodeID的长度),使用protobuf的变体编码方式。上面这种编码方式的目的是为了桶中的键值对的字节表示方式不会被任意其他键值对的组合所产生,并减少了序列化字节码的总体大小。 - -例如:考虑具有`chaincodeID1_key1:value1, chaincodeID1_key2:value2, 和 chaincodeID2_key1:value1`这样名字的键值对的桶。序列化后的桶看上去会像:`12 + chaincodeID1 + 2 + 4 + key1 + 6 + value1 + 4 + key2 + 6 + value2 + 12 + chaincodeID2 + 1 + 4 + key1 + 6 + value1` - - -如果桶中没有键值对,那么加密-哈希为`nil`。 - -中间节点和根节点的加密-哈希与标准merkle-tree的计算方法一样,即:应用加密-哈希函数到所有子节点的加密-哈希从左到右级联后得到的字节码。进一步说,如果一个子节点的加密-哈希为`nil`,那么这个子节点的加密-哈希在级联子节点的加密-哈希是就被省略。如果它只有一个子节点,那么它的加密-哈希就是子节点的加密-哈希。最后,根节点的加密-哈希就是世界状态的加密-哈希。 - -上面这种方法在状态中少数键值对改变时计算加密-哈希是有性能优势的。主要的优势包括: - - 那些没有变化的桶的计算会被跳过 - - merkle-tree的宽度和深度可以通过配置`numBuckets`和`maxGroupingAtEachLevel`参数来控制。树的不同深度和宽度对性能和不同的资源都会产生不同的影响。 - -在一个具体的部署中,所有的 peer 都期望使用相同的`numBuckets, maxGroupingAtEachLevel, 和 hashFunction`的配置。进一步说,如果任何一个配置在之后的阶段被改变,那么这些改变需要应用到所有的 peer 中,来保证 peer 节点之间的加密-哈希的比较是有意义的。即使,这可能会导致基于实现的已有数据的迁移。例如:一种实现希望存储树中所有节点最后计算的加密-哈希,那么它就需要被重新计算。 - - -### 3.3 链码(Chaincode) -链码是在交易(参看3.1.2节)被部署时分发到网络上,并被所有验证 peer 通过隔离的沙箱来管理的应用级代码。尽管任意的虚拟技术都可以支持沙箱,现在是通过Docker容器来运行链码的。这节中描述的协议可以启用不同虚拟实现的插入与运行。 - - -### 3.3.1 虚拟机实例化 -一个实现VM接口的虚拟机 - -``` -type VM interface { - build(ctxt context.Context, id string, args []string, env []string, attachstdin bool, attachstdout bool, reader io.Reader) error - start(ctxt context.Context, id string, args []string, env []string, attachstdin bool, attachstdout bool) error - stop(ctxt context.Context, id string, timeout uint, dontkill bool, dontremove bool) error -} -``` - -fabric在处理链码上的部署交易或其他交易时,如果这个链码的VM未启动(崩溃或之前的不活动导致的关闭)时实例化VM。每个链码镜像通过`build`函数构建,通过`start`函数启动,并使用`stop`函数停止。 - -一旦链码容器被启动,它使用gRPC来连接到启动这个链码的验证 peer,并为链码上的调用和查询交易建立通道。 - -### 3.3.2 链码协议 -验证 peer 和它的链码之间是通过gRPC流来通信的。链码容器上有shim层来处理链码与验证 peer 之间的protobuf消息协议。 - -``` -message ChaincodeMessage { - - enum Type { - UNDEFINED = 0; - REGISTER = 1; - REGISTERED = 2; - INIT = 3; - READY = 4; - TRANSACTION = 5; - COMPLETED = 6; - ERROR = 7; - GET_STATE = 8; - PUT_STATE = 9; - DEL_STATE = 10; - INVOKE_CHAINCODE = 11; - INVOKE_QUERY = 12; - RESPONSE = 13; - QUERY = 14; - QUERY_COMPLETED = 15; - QUERY_ERROR = 16; - GET_STATE_BY_RANGE = 17; - } - - Type type = 1; - google.protobuf.Timestamp timestamp = 2; - bytes payload = 3; - string uuid = 4; -} -``` - -**域的定义:** -- `Type` 是消息的类型 -- `payload` 是消息的payload. 每个payload取决于`Type`. -- `uuid` 消息唯一的ID - -消息的类型在下面的小节中描述 - -链码实现被验证 peer 在处理部署,调用或查询交易时调用的`Chaincode`接口 - -``` -type Chaincode interface { - Init(stub *ChaincodeStub, function string, args []string) ([]byte, error) - Invoke(stub *ChaincodeStub, function string, args []string) (error) - Query(stub *ChaincodeStub, function string, args []string) ([]byte, error) -} -``` - -`Init`, `Invoke` 和 `Query`函数使用`function` and `args`参数来支持多种交易。`Init`是构造函数,它只在部署交易时被执行。`Query`函数是不允许修改链码的状态的;它只能读取和计算并以byte数组的形式返回。 - -### 3.3.2.1 链码部署 -当部署时(链码容器已经启动),shim层发送一次性的具有包含`ChaincodeID`的`payload`的`REGISTER`消息给验证 peer。然后 peer 以`REGISTERED`或`ERROR`来响应成功或失败。当收到`ERROR`后shim关闭连接并退出。 - -注册之后,验证 peer 发送具有包含`ChaincodeInput`对象的`INIT`消息。shim使用从`ChaincodeInput`获得的参数来调用`Init`函数,通过像设置持久化状态这样操作来初始化链码。 - -shim根据`Init`函数的返回值,响应`RESPONSE`或`ERROR`消息。如果没有错误,那么链码初始化完成,并准备好接收调用和查询交易。 - -### 3.3.2.2 链码调用 -当处理调用交易时,验证 peer 发送`TRANSACTION`消息给链码容器的shim,由它来调用链码的`Invoke`函数,并传递从`ChaincodeInput`得到的参数。shim响应`RESPONSE`或`ERROR`消息来表示函数完成。如果接收到`ERROR`函数,`payload`包含链码所产生的错误信息。 - -### 3.3.2.3 链码查询 -与调用交易一样,验证 peer 发送`QUERY`消息给链码容器的shim,由它来调用链码的`Query`函数,并传递从`ChaincodeInput`得到的参数。`Query`函数可能会返回状态值或错误,它会把它通过`RESPONSE`或`ERROR`消息来传递给验证 peer。 - -### 3.3.2.4 链码状态 -每个链码可能都定义了它自己的持久化状态变量。例如,一个链码可能创建电视,汽车或股票这样的资产来保存资产属性。当`Invoke`函数处理时,链码可能会更新状态变量,例如改变资产所有者。链码会根据下面这些消息类型类操作状态变量: - -#### PUT_STATE -链码发送一个`payload`包含`PutStateInfo`对象的`PU_STATE`消息来保存键值对。 - -``` -message PutStateInfo { - string key = 1; - bytes value = 2; -} -``` - -#### GET_STATE -链码发送一个由`payload`指定要获取值的键的`GET_STATE`消息。 - -#### DEL_STATE -链码发送一个由`payload`指定要删除值的键的`DEL_STATE`消息。 - -#### GET_STATE_BY_RANGE -链码发送一个`payload`包含`GET_STATE_BY_RANGE`对象的`GET_STATE_BY_RANGE`来获取一个范围内的值。 - -``` -message GetStateByRange { - string startKey = 1; - string endKey = 2; -} -``` - -`startKey`和`endKey`假设是通过字典排序的. 验证 peer 响应一个`payload`是`GetStateByRangeResponse`对象的`RESPONSE`消息 - -``` -message GetStateByRangeResponse { - repeated GetStateByRangeKeyValue keysAndValues = 1; - bool hasMore = 2; - string ID = 3; -} -message GetStateByRangeKeyValue { - string key = 1; - bytes value = 2; -} -``` - -如果相应中`hasMore=true`,这表示有在请求的返回中还有另外的键。链码可以通过发送包含与响应中ID相同的ID的`GetStateByRangeNext`消息来获取下一集合。 - -``` -message GetStateByRangeNext { - string ID = 1; -} -``` - -当链码结束读取范围,它会发送带有ID的`GetStateByRangeClose`消息来期望它关闭。 - -``` -message GetStateByRangeClose { - string ID = 1; -} -``` - -#### INVOKE_CHAINCODE -链码可以通过发送`payload`包含 `ChaincodeSpec`对象的`INVOKE_CHAINCODE`消息给验证 peer 来在相同的交易上下文中调用另一个链码 - -#### QUERY_CHAINCODE -链码可以通过发送`payload`包含 `ChaincodeSpec`对象的`QUERY_CHAINCODE`消息给验证 peer 来在相同的交易上下文中查询另一个链码 - - -### 3.4 插拔式共识框架 - -共识框架定义了每个共识插件都需要实现的接口: - - - `consensus.Consenter`: 允许共识插件从网络上接收消息的接口 - - `consensus.CPI`: 共识编程接口_Consensus Programming Interface_ (`CPI`) 是共识插件用来与栈交互的,这个接口可以分为两部分: - - `consensus.Communicator`: 用来发送(广播或单播)消息到其他的验证 peer - - `consensus.LedgerStack`: 这个接口使得执行框架像总账一样方便 - -就像下面描述的细节一样,`consensus.LedgerStack`封装了其他接口,`consensus.Executor`接口是共识框架的核心部分。换句话说,`consensus.Executor`接口允许一个(批量)交易启动,执行,根据需要回滚,预览和提交。每一个共识插件都需要满足以所有验证 peer 上全序的方式把批量(块)交易(通过`consensus.Executor.CommitTxBatch`)被提交到总账中(参看下面的`consensus.Executor`接口获得详细细节)。 - -当前,共识框架由`consensus`, `controller`和`helper`这三个包组成。使用`controller`和`helper`包的主要原因是防止Go语言的“循环引入”和当插件更新时的最小化代码变化。 - -- `controller` 包规范了验证 peer 所使用的共识插件 -- `helper` 是围绕公式插件的垫片,它是用来与剩下的栈交互的,如为其他 peer 维护消息。 - -这里有2个共识插件提供:`pbft`和`noops`: - -- `obcpbft`包包含实现 *PBFT* [1] 和 *Sieve* 共识协议的共识插件。参看第5节的详细介绍 -- `noops` 是一个为开发和测试提供的''假的''共识插件. 它处理所有共识消息但不提供共识功能,它也是一个好的学习如何开发一个共识插件的简单例子。 - -### 3.4.1 `Consenter` 接口 - -定义: -``` -type Consenter interface { - RecvMsg(msg *pb.Message) error -} -``` -`Consenter`接口是插件对(外部的)客户端请求的入口,当处理共识时,共识消息在内部(如从共识模块)产生。NewConsenter`创建`Consenter`插件。`RecvMsg`以到达共识的顺序来处理进来的交易。 - -阅读下面的`helper.HandleMessage`来理解 peer 是如何和这个接口来交互的。 - -### 3.4.2 `CPI`接口 - -定义: -``` -type CPI interface { - Inquirer - Communicator - SecurityUtils - LedgerStack -} -``` -`CPI` 允许插件和栈交互。它是由`helper.Helper`对象实现的。回想一下这个对象是: - - 1. 在`helper.NewConsensusHandler`被调用时初始化的 - 2. 当它们的插件构造了`consensus.Consenter`对象,那么它对插件的作者是可访问的 - - -### 3.4.3 `Inquirer`接口 - -定义: -``` -type Inquirer interface { - GetNetworkInfo() (self *pb.PeerEndpoint, network []*pb.PeerEndpoint, err error) - GetNetworkHandles() (self *pb.PeerID, network []*pb.PeerID, err error) -} -``` -这个接口是`consensus.CPI`接口的一部分。它是用来获取网络中验证 peer 的(`GetNetworkHandles`)句柄,以及那些验证 peer 的明细(`GetNetworkInfo`): - -注意peers由`pb.PeerID`对象确定。这是一个protobuf消息,当前定义为(注意这个定义很可能会被修改): - -``` -message PeerID { - string name = 1; -} -``` - -### 3.4.4 `Communicator`接口 - -定义: - -``` -type Communicator interface { - Broadcast(msg *pb.Message) error - Unicast(msg *pb.Message, receiverHandle *pb.PeerID) error -} -``` -这个接口是`consensus.CPI`接口的一部分。它是用来与网络上其它 peer 通信的(`helper.Broadcast`, `helper.Unicast`): - -### 3.4.5 `SecurityUtils`接口 - -定义: - -``` -type SecurityUtils interface { - Sign(msg []byte) ([]byte, error) - Verify(peerID *pb.PeerID, signature []byte, message []byte) error -} -``` - -这个接口是`consensus.CPI`接口的一部分。它用来处理消息签名(`Sign`)的加密操作和验证签名(`Verify`) - - -### 3.4.6 `LedgerStack` 接口 - -定义: - -``` -type LedgerStack interface { - Executor - Ledger - RemoteLedgers -} -``` -`CPI`接口的主要成员,`LedgerStack` 组与fabric的其它部分与共识相互作用,如执行交易,查询和更新总账。这个接口支持对本地区块链和状体的查询,更新本地区块链和状态,查询共识网络上其它节点的区块链和状态。它是由`Executor`, `Ledger`和`RemoteLedgers`这三个接口组成的。下面会描述它们。 - -### 3.4.7 `Executor` 接口 - -定义: - -``` -type Executor interface { - BeginTxBatch(id interface{}) error - ExecTXs(id interface{}, txs []*pb.Transaction) ([]byte, []error) - CommitTxBatch(id interface{}, transactions []*pb.Transaction, transactionsResults []*pb.TransactionResult, metadata []byte) error - RollbackTxBatch(id interface{}) error - PreviewCommitTxBatchBlock(id interface{}, transactions []*pb.Transaction, metadata []byte) (*pb.Block, error) -} -``` -executor接口是`LedgerStack`接口最常使用的部分,且是共识网络工作的必要部分。接口允许交易启动,执行,根据需要回滚,预览和提交。这个接口由下面这些方法组成。 - -#### 3.4.7.1 开始批量交易 - -``` -BeginTxBatch(id interface{}) error -``` -这个调用接受任意的,故意含糊的`id`,来使得共识插件可以保证与这个具体的批量相关的交易才会被执行。例如:在pbft实现中,这个`id`是被执行交易的编码过的哈希。 - -#### 3.4.7.2 执行交易 - -``` -ExecTXs(id interface{}, txs []*pb.Transaction) ([]byte, []error) -``` - -这个调用根据总账当前的状态接受一组交易,并返回带有对应着交易组的错误信息组的当前状态的哈希。注意一个交易所产生的错误不影响批量交易的安全提交。当遇到失败所采用的策略取决与共识插件的实现。这个接口调用多次是安全的。 - -#### 3.4.7.3 提交与回滚交易 - -``` -RollbackTxBatch(id interface{}) error -``` - -这个调用中止了批量执行。这会废弃掉对当前状态的操作,并把总账状态回归到之前的状态。批量是从`BeginBatchTx`开始的,如果需要开始一个新的就需要在执行任意交易之前重新创建一个。 - -``` -PreviewCommitTxBatchBlock(id interface{}, transactions []*pb.Transaction, metadata []byte) (*pb.Block, error) -``` - -这个调用是共识插件对非确定性交易执行的测试时最有用的方法。区块返回的哈希表部分会保证,当`CommitTxBatch`被立即调用时的区块是同一个。这个保证会被任意新的交易的执行所打破。 - -``` -CommitTxBatch(id interface{}, transactions []*pb.Transaction, transactionsResults []*pb.TransactionResult, metadata []byte) error -``` - -这个调用提交区块到区块链中。区块必须以全序提交到区块链中,``CommitTxBatch``结束批量交易,在执行或提交任意的交易之前必须先调用`BeginTxBatch`。 - - -### 3.4.8 `Ledger` 接口 - -定义: - -``` -type Ledger interface { - ReadOnlyLedger - UtilLedger - WritableLedger -} -``` - -``Ledger`` 接口是为了允许共识插件询问或可能改变区块链当前状态。它是由下面描述的三个接口组成的 - -#### 3.4.8.1 `ReadOnlyLedger` 接口 - -定义: - -``` -type ReadOnlyLedger interface { - GetBlock(id uint64) (block *pb.Block, err error) - GetCurrentStateHash() (stateHash []byte, err error) - GetBlockchainSize() (uint64, error) -} -``` - -`ReadOnlyLedger` 接口是为了查询总账的本地备份,而不会修改它。它是由下面这些函数组成的。 - -``` -GetBlockchainSize() (uint64, error) -``` - -这个函数返回区块链总账的长度。一般来说,这个函数永远不会失败,在这种不太可能发生情况下,错误被传递给调用者,由它确定是否需要恢复。具有最大区块值的区块的值为`GetBlockchainSize()-1` - -注意在区块链总账的本地副本是腐坏或不完整的情况下,这个调用会返回链中最大的区块值+1。这允许节点在旧的块是腐坏或丢失的情况下能继续操作当前状态/块。 - -``` -GetBlock(id uint64) (block *pb.Block, err error) -``` - -这个调用返回区块链中块的数值`id`。一般来说这个调用是不会失败的,除非请求的区块超出当前区块链的长度,或者底层的区块链被腐坏了。`GetBlock`的失败可能可以通过状态转换机制来取回它。 - - -``` -GetCurrentStateHash() (stateHash []byte, err error) -``` - -这个调用返回总账的当前状态的哈希。一般来说,这个函数永远不会失败,在这种不太可能发生情况下,错误被传递给调用者,由它确定是否需要恢复。 - - -#### 3.4.8.2 `UtilLedger` 接口 - -定义: - -``` -type UtilLedger interface { - HashBlock(block *pb.Block) ([]byte, error) - VerifyBlockchain(start, finish uint64) (uint64, error) -} -``` - -`UtilLedger` 接口定义了一些由本地总账提供的有用的功能。使用mock接口来重载这些功能在测试时非常有用。这个接口由两个函数构成。 -会会 -``` -HashBlock(block *pb.Block) ([]byte, error) -``` - -尽管`*pb.Block`定义了`GetHash`方法,为了mock测试,重载这个方法会非常有用。因此,建议`GetHash`方法不直接调用,而是通过`UtilLedger.HashBlock`接口来调用这个方法。一般来说,这个函数永远不会失败,但是错误还是会传递给调用者,让它决定是否使用适当的恢复。 - -``` -VerifyBlockchain(start, finish uint64) (uint64, error) -``` - -这个方法是用来校验区块链中的大的区域。它会从高的块`start`到低的块`finish`,返回第一个块的`PreviousBlockHash`与块的前一个块的哈希不相符的块编号以及错误信息。注意,它一般会标识最后一个好的块的编号,而不是第一个坏的块的编号。 - - -#### 3.4.8.3 `WritableLedger` 接口 - -定义: - -``` -type WritableLedger interface { - PutBlock(blockNumber uint64, block *pb.Block) error - ApplyStateDelta(id interface{}, delta *statemgmt.StateDelta) error - CommitStateDelta(id interface{}) error - RollbackStateDelta(id interface{}) error - EmptyState() error -} -``` - -`WritableLedger` 接口允许调用者更新区块链。注意这_NOT_ _不是_共识插件的通常用法。当前的状态需要通过`Executor`接口执行交易来修改,新的区块在交易提交时生成。相反的,这个接口主要是用来状态改变和腐化恢复。特别的,这个接口下的函数_永远_不能直接暴露给共识消息,这样会导致打破区块链所承诺的不可修改这一概念。这个结构包含下面这些函数。 - - - - ``` - PutBlock(blockNumber uint64, block *pb.Block) error - ``` - 这个函数根据给定的区块编号把底层区块插入到区块链中。注意这是一个不安全的接口,所以它不会有错误返回或返回。插入一个比当前区块高度更高的区块是被允许的,同样,重写一个已经提交的区块也是被允许的。记住,由于哈希技术使得创建一个链上的更早的块是不可行的,所以这并不影响链的可审计性和不可变性。任何尝试重写区块链的历史的操作都能很容易的被侦测到。这个函数一般只用于状态转移API。 - - - - ``` - ApplyStateDelta(id interface{}, delta *statemgmt.StateDelta) error - ``` - - 这个函数接收状态变化,并把它应用到当前的状态。变化量的应用会使得状态向前或向后转变,这取决于状态变化量的构造,与`Executor`方法一样,`ApplyStateDelta`接受一个同样会被传递给`CommitStateDelta` or `RollbackStateDelta`不透明的接口`id` - - - - ``` - CommitStateDelta(id interface{}) error - ``` - - 这个方法提交在`ApplyStateDelta`中应用的状态变化。这通常是在调用者调用`ApplyStateDelta`后通过校验由`GetCurrentStateHash()`获得的状态哈希之后调用的。这个函数接受与传递给`ApplyStateDelta`一样的`id`。 - - - - ``` - RollbackStateDelta(id interface{}) error - ``` - - 这个函数撤销在`ApplyStateDelta`中应用的状态变化量。这通常是在调用者调用`ApplyStateDelta`后与由`GetCurrentStateHash()`获得的状态哈希校验失败后调用的。这个函数接受与传递给`ApplyStateDelta`一样的`id`。 - - - - - ``` - EmptyState() error - ``` - - 这个函数将会删除整个当前状态,得到原始的空状态。这通常是通过变化量加载整个新的状态时调用的。这一般只对状态转移API有用。 - -### 3.4.9 `RemoteLedgers` 接口 - -定义: - -``` -type RemoteLedgers interface { - GetRemoteBlocks(peerID uint64, start, finish uint64) (<-chan *pb.SyncBlocks, error) - GetRemoteStateSnapshot(peerID uint64) (<-chan *pb.SyncStateSnapshot, error) - GetRemoteStateDeltas(peerID uint64, start, finish uint64) (<-chan *pb.SyncStateDeltas, error) -} -``` - -`RemoteLedgers` 接口的存在主要是为了启用状态转移,和向其它副本询问区块链的状态。和`WritableLedger`接口一样,这不是给正常的操作使用,而是为追赶,错误恢复等操作而设计的。这个接口中的所有函数调用这都有责任来处理超时。这个接口包含下面这些函数: - - - - ``` - GetRemoteBlocks(peerID uint64, start, finish uint64) (<-chan *pb.SyncBlocks, error) - ``` - - 这个函数尝试从由`peerID`指定的 peer 中取出由`start`和`finish`标识的范围中的`*pb.SyncBlocks`流。一般情况下,由于区块链必须是从结束到开始这样的顺序来验证的,所以`start`是比`finish`更高的块编号。由于慢速的结构,其它请求的返回可能出现在这个通道中,所以调用者必须验证返回的是期望的块。第二次以同样的`peerID`来调用这个方法会导致第一次的通道关闭。 - - - - - ``` - GetRemoteStateSnapshot(peerID uint64) (<-chan *pb.SyncStateSnapshot, error) - ``` - - 这个函数尝试从由`peerID`指定的 peer 中取出`*pb.SyncStateSnapshot`流。为了应用结果,首先需要通过`WritableLedger`的`EmptyState`调用来清空存在在状态,然后顺序应用包含在流中的变化量。 - - - - ``` - GetRemoteStateDeltas(peerID uint64, start, finish uint64) (<-chan *pb.SyncStateDeltas, error) - ``` - - 这个函数尝试从由`peerID`指定的 peer 中取出由`start`和`finish`标识的范围中的`*pb.SyncStateDeltas`流。由于慢速的结构,其它请求的返回可能出现在这个通道中,所以调用者必须验证返回的是期望的块变化量。第二次以同样的`peerID`来调用这个方法会导致第一次的通道关闭。 - - -### 3.4.10 `controller`包 - -#### 3.4.10.1 controller.NewConsenter - -签名: - -``` -func NewConsenter(cpi consensus.CPI) (consenter consensus.Consenter) -``` -这个函数读取为`peer`过程指定的`core.yaml`配置文件中的`peer.validator.consensus`的值。键`peer.validator.consensus`的有效值指定运行`noops`还是`pbft`共识插件。(注意,它最终被改变为`noops`或`custom`。在`custom`情况下,验证 peer 将会运行由`consensus/config.yaml`中定义的共识插件) - -插件的作者需要编辑函数体,来保证路由到它们包中正确的构造函数。例如,对于`pbft` 我们指向`pbft.GetPlugin`构造器。 - -这个函数是当设置返回信息处理器的`consenter`域时,被`helper.NewConsensusHandler`调用的。输入参数`cpi`是由`helper.NewHelper`构造器输出的,并实现了`consensus.CPI`接口 - -### 3.4.11 `helper`包 - -#### 3.4.11.1 高层次概述 - -验证 peer 通过`helper.NewConsesusHandler`函数(一个处理器工厂),为每个连接的 peer 建立消息处理器(`helper.ConsensusHandler`)。每个进来的消息都会检查它的类型(`helper.HandleMessage`);如果这是为了共识必须到达的消息,它会传递到 peer 的共识对象(`consensus.Consenter`)。其它的信息会传递到栈中的下一个信息处理器。 - -#### 3.4.11.2 helper.ConsensusHandler - -定义: - -``` -type ConsensusHandler struct { - chatStream peer.ChatStream - consenter consensus.Consenter - coordinator peer.MessageHandlerCoordinator - done chan struct{} - peerHandler peer.MessageHandler -} -``` - -共识中的上下文,我们只关注域`coordinator`和`consenter`。`coordinator`就像名字隐含的那样,它被用来在 peer 的信息处理器之间做协调。例如,当 peer 希望`Broadcast`时,对象被访问。共识需要到达的共识者会接收到消息并处理它们。 - -注意,`fabric/peer/peer.go`定义了`peer.MessageHandler` (接口),和`peer.MessageHandlerCoordinator`(接口)类型。 - -#### 3.4.11.3 helper.NewConsensusHandler - -签名: - -``` -func NewConsensusHandler(coord peer.MessageHandlerCoordinator, stream peer.ChatStream, initiatedStream bool, next peer.MessageHandler) (peer.MessageHandler, error) -``` - -创建一个`helper.ConsensusHandler`对象。为每个`coordinator`设置同样的消息处理器。同时把`consenter`设置为`controller.NewConsenter(NewHelper(coord))` - - -### 3.4.11.4 helper.Helper - -定义: - -``` -type Helper struct { - coordinator peer.MessageHandlerCoordinator -} -``` - -包含验证peer的`coordinator`的引用。对象是否为peer实现了`consensus.CPI`接口。 - -#### 3.4.11.5 helper.NewHelper - -签名: - -``` -func NewHelper(mhc peer.MessageHandlerCoordinator) consensus.CPI -``` - -返回`coordinator`被设置为输入参数`mhc`(`helper.ConsensusHandler`消息处理器的`coordinator`域)的`helper.Helper`对象。这个对象实现了`consensus.CPI`接口,从而允许插件与栈进行交互。 - - -#### 3.4.11.6 helper.HandleMessage - -回忆一下,`helper.NewConsensusHandler`返回的`helper.ConsesusHandler`对象实现了 `peer.MessageHandler` 接口: - -``` -type MessageHandler interface { - RemoteLedger - HandleMessage(msg *pb.Message) error - SendMessage(msg *pb.Message) error - To() (pb.PeerEndpoint, error) - Stop() error -} -``` - -在共识的上下文中,我们只关心`HandleMessage`方法。签名: - -``` -func (handler *ConsensusHandler) HandleMessage(msg *pb.Message) error -``` - -这个函数检查进来的`Message`的`Type`。有四种情况: - - 1. 等于`pb.Message_CONSENSUS`:传递给处理器的`consenter.RecvMsg`函数。 - 2. 等于`pb.Message_CHAIN_TRANSACTION` (如:一个外部部署的请求): 一个响应请求首先被发送给用户,然后把消息传递给`consenter.RecvMsg`函数 - 3. 等于`pb.Message_CHAIN_QUERY` (如:查询): 传递给`helper.doChainQuery`方法来在本地执行 - 4. 其它: 传递给栈中下一个处理器的`HandleMessage`方法 - - -### 3.5 事件 -事件框架提供了生产和消费预定义或自定义的事件的能力。它有3个基础组件: - - 事件流 - - 事件适配器 - - 事件结构 - -#### 3.5.1 事件流 -事件流是用来发送和接收事件的gRPC通道。每个消费者会与事件框架建立事件流,并快速传递它感兴趣的事件。事件生成者通过事件流只发送合适的事件给连接到生产者的消费者。 - -事件流初始化缓冲和超时参数。缓冲保存着几个等待投递的事件,超时参数在缓冲满时有三个选项: - -- 如果超时小于0,丢弃新到来的事件 -- 如果超时等于0,阻塞事件知道缓冲再次可用 -- 如果超时大于0,等待指定的超时时间,如果缓冲还是满的话就丢弃事件 - - -#### 3.5.1.1 事件生产者 -事件生产者暴露函数`Send(e *pb.Event)`来发送事件,其中`Event`可以是预定义的`Block`或`Generic`事件。将来会定义更多的事件来包括其它的fabric元素。 - -``` -message Generic { - string eventType = 1; - bytes payload = 2; -} -``` - -`eventType`和`payload`是由事件生产者任意定义的。例如,JSON数据可能被用在`payload`中。链码或插件发出`Generic`事件来与消费者通讯。 - -#### 3.5.1.2 事件消费者 -事件消费者允许外部应用监听事件。每个事件消费者通过时间流注册事件适配器。消费者框架可以看成是事件流与适配器之间的桥梁。一种典型的事件消费者使用方式: - -``` -adapter = -consumerClient = NewEventsClient(, adapter) -consumerClient.Start() -... -... -consumerClient.Stop() -``` - -#### 3.5.2 事件适配器 -事件适配器封装了三种流交互的切面: - - 返回所有感兴趣的事件列表的接口 - - 当事件消费者框架接受到事件后调用的接口 - - 当事件总线终止时,事件消费者框架会调用的接口 - -引用的实现提供了Golang指定语言绑定 -``` - EventAdapter interface { - GetInterestedEvents() ([]*ehpb.Interest, error) - Recv(msg *ehpb.Event) (bool,error) - Disconnected(err error) - } -``` -把gRPC当成事件总线协议来使用,允许事件消费者框架对于不同的语言的绑定可移植而不影响事件生成者框架。 - -#### 3.5.3 事件框架 - -这节详细描述了事件系统的消息结构。为了简单起见,消息直接使用Golang描述。 - -事件消费者和生产者之间通信的核心消息是事件。 - -``` - message Event { - oneof Event { - //consumer events - Register register = 1; - - //producer events - Block block = 2; - Generic generic = 3; - } - } -``` -每一个上面的定义必须是`Register`, `Block`或`Generic`中的一种。 - -就像之前提到过的一样,消费者通过与生产者建立连接来创建事件总线,并发送`Register`事件。`Register`事件实质上是一组声明消费者感兴趣的事件的`Interest`消息。 - -``` - message Interest { - enum ResponseType { - //don't send events (used to cancel interest) - DONTSEND = 0; - //send protobuf objects - PROTOBUF = 1; - //marshall into JSON structure - JSON = 2; - } - string eventType = 1; - ResponseType responseType = 2; - } -``` - -事件可以通过protobuf结构直接发送,也可以通过指定适当的`responseType`来发送JSON结构。 - -当前,生产者框架可以生成`Block`和`Generic`事件。`Block`是用来封装区块链中区块属性的消息。 - - -## 4. 安全 - -这一节将讨论下面的图所展示的设置描述。特别的,系统是由下面这些实体构成的:成员管理基础架构,如从一个实体集合中区分出不同用户身份的职责(使用系统中任意形式的标识,如:信用卡,身份证),为这个用户注册开户,并生成必要的证书以便通过fabric成功的创建交易,部署或调用链码。 - -![figure-architecture](./images/sec-sec-arch.png) - - * Peers,它们被分为验证 peer 和非验证 peer。验证 peer(也被称为验证器)是为了规范并处理(有效性检查,执行并添加到区块链中)用户消息(交易)提交到网络上。非验证 peer(也被称为 peer)代表用户接受用户交易,并通过一些基本的有效性检查,然后把交易发送到它们附近的验证 peer。peer 维护一个最新的区块链副本,只是为了做验证,而不会执行交易(处理过程也被称为*交易验证*)。 - * 注册到我们的成员服务管理系统的终端用户是在获取被系统认定的*身份*的所有权之后,并将获取到的证书安装到客户端软件后,提交交易到系统。 - * 客户端软件,为了之后能完成注册到我们成员服务和提交交易到系统所需要安装在客户端的软件。 - * 在线钱包,用户信任的用来维护他们证书的实体,并独自根据用户的请求向网络提交交易。在线钱包配置在他们自己的客户端软件中。这个软件通常是轻量级的,它只需有对自己和自己的钱包的请求做授权。也有 peer 为一些用户扮演*在线钱包*的角色,在接下来的会话中,对在线钱包做了详细区分。 - -希望使用fabric的用户,通过提供之前所讨论的身份所有权,在成员管理系统中开立一个账户,新的链码被链码创建者(开发)以开发者的形式通过客户端软件部署交易的手段,公布到区块链网络中。这样的交易是第一次被 peer 或验证器接收到,并流传到整个验证器网络中,这个交易被区块链网络执行并找到自己的位置。用户同样可以通过调用交易调用一个已经部署了的链码 - -下一节提供了由商业目标所驱动的安全性需求的摘要。然后我们游览一下安全组件和它们的操作,以及如何设计来满足安全需求。 - -### 4.1 商业安全需求 -这一节表述与fabric相关的商业安全需求。 - -**身份和角色管理相结合** - -为了充分的支持实际业务的需求,有必要超越确保加密连续性来进行演进。一个可工作的B2B系统必须致力于证明/展示身份或其他属性来开展业务。商业交易和金融机构的消费交互需要明确的映射到账户的所有者。商务合同通常需要与特定的机构和/或拥有交易的其他特定性质的各方保证有从属关系。问责制和不可陷害性是身份管理作为此类系统关键组成部分的两个原因。 - - -问责制意味着系统的用户,个人或公司,谁的胡作非为都可以追溯到并为自己的行为负责。在很多情况下,B2B系统需要它们的会员使用他们的身份(在某些形式)加入到系统中,以确保问责制的实行。问责制和不可陷害性都是B2B系统的核心安全需求,并且他们非常相关。B2B系统需要保证系统的诚实用户不会因为其他用户的交易而被指控。 - -此外,一个B2B系统需要具有可再生性和灵活性,以满足参与者角色和/或从属关系的改变。 - -**交易隐私.** - -B2B系统对交易的隐私有着强烈的需求,如:允许系统的终端用户控制他与环境交互和共享的信息。例如:一家企业在交易型B2B系统上开展业务,要求它的交易得其他企业不可见,而他的行业合作伙伴无权分享机密信息。 - -在fabric中交易隐私是通过下面非授权用户的两个属性来实现的: - -* 交易匿名,交易的所有者隐藏在一个被称为*匿名集*的组建中,在fabric中,它是用户的一个集合。 - -* 交易不可关联,同一用户的两个或多个交易不能被关联起来。 - - -根据上下文,非授权用户可以是系统以外的任何人,或用户的子集。 - -交易隐私与B2B系统的两个或多个成员之间的保密协议的内容强烈相关。任何授权机制的匿名性和不可关联性需要在交易时考虑。 - -**通过身份管理协调交易隐私.** - -就像文档之后描述的那样,这里所采用的方法用来协调身份管理与用户隐私,并使有竞争力的机构可以像下面一样在公共的区块链(用于内部和机构间交易)上快速的交易: - -1. 为交易添加证书来实现“有权限的”区块链 - -2. 使用两层系统: - - 1. 向登记的证颁发机构(CA)注册来获得(相对的) 静态登记证书 (ECerts) - - 2. 通过交易CA获取能如实但伪匿名的代表登记用户的交易证书(TCerts). - -3. 提供对系统中未授权会员隐藏交易内用的机制 - -**审计支持.** - -商业系统偶尔会受到审核。在这种情况下,将给予审计员检查某些交易,某组交易,系统中某些特定用户或系统自己的一些操作的手段。因此,任意与商业伙伴通过合同协议进行交易的系统都应该提供这样的能力。 - -### 4.2 使用成员管理的用户隐私 -成员管理服务是由网络上管理用户身份和隐私的几个基础架构来组成的。这些服务验证用户的身份,在系统中注册用户,并为他/她提供所有作为可用、兼容的参数者来创建和/或调用交易所需要的证书。公开密钥体系(Public Key Infrastructure -,PKI)是一个基于不仅对公共网络上交换的数据的加密而且能确认对方身份的公共密钥加密的。PKI管理密钥和数字证书的生成,发布和废止。数字证书是用来建立用户证书,并对消息签名的。使用证书签名的消息保证信息不被篡改。典型的PKI有一个证书颁发机构(CA),一个登记机构(RA),一个证书数据库,一个证书的存储。RA是对用户进行身份验证,校验数据的合法性,提交凭据或其他证据来支持用户请求一个或多个人反映用户身份或其他属性的可信任机构。CA根据RA的建议为特定的用户发放根CA能直接或分级的认证的数字证书。另外,RA的面向用户的通信和尽职调查的责任可以看作CA的一部分。成员服务由下图展示的实体组成。整套PKI体系的引入加强了B2B系统的强度(如:超过比特币)。 - -![Figure 1](./images/sec-memserv-components.png) - -*根证书颁发机构(根CA):* 它代表PKI体系中的信任锚。数字证书的验证遵循信任链。根CA是PKI层次结构中最上层的CA。 - -*登记机构(RA):* 它是一个可以确定想要加入到带权限区块链的用户的有效性和身份的可信实体。它是负责与用户外的带外通信来验证他/她的身份和作用。它是负责与用户进行频外通信来验证他/她的身份和角色。它创建登记时所需要的注册证书和根信任上的信息。 - -*注册证书颁发机构(ECA):* 负责给通过提供的注册凭证验证的用户颁发注册证书(ECerts) - -*交易认证中心(TCA):* 负责给提供了有效注册证书的用户颁发交易证书(TCerts) - -*TLS证书颁发机构(TLS-CA):* 负责签发允许用户访问其网络的TLS证书和凭证。它验证用户提供的包含该用户的特定信息的,用来签发TLS证书的,证书或证据。 - -*注册证书(ECerts)* -ECerts是长期证书。它们是颁发给所有角色的,如用户,非验证 peer,验证 peer。在给用户颁发的情况下,谁向区块链提交候选人申请谁就拥有TCerts(在下面讨论),ECerts有两种可能的结构和使用模式: - - * Model A: ECerts 包含所有者的身份/注册ID,并可以在交易中为TCert请求提供只用来对名义实体身份做验证。它们包含两个密钥对的公共部分:签名密钥对和加密/密钥协商密钥对。 ECerts是每个人都可以访问。 - - * Model B: ECerts 包含所有者的身份/注册ID,并只为TCert请求提供名义实体的身份验证。它们包含一个签名密钥对的公共部分,即,签名验证公钥的公共部分。作为依赖方,ECerts最好只由TCA和审计人员访问。他们对交易是不可见的,因此(不像TCerts)签名密钥对不在这一层级发挥不可抵赖的作用。 - -*交易证书(TCerts)* -TCerts是每个交易的短期证书。它们是由TCA根据授权的用户请求颁发的。它们安全的给一个交易授权,并可以被配置为隐藏谁参与了交易或选择性地暴露这样身份注册ID这样的信息。他们包含签名密钥对的公共部分,并可以被配置为包含一个密钥协议的密钥对的公共部分。他们仅颁发给用户。它们唯一的关联到所有者,它们可以被配置为这个关联只有TCA知道知道(和授权审核员)。TCert可以配置成不携带用户的身份信息。它们使得用户不仅以匿名方式参与到系统中,而且阻止了交易之间的关联性。 - -然而,审计能力和问责制的要求TCA能够获取给定身份的TCert,或者获取指定TCert的所有者。有关TCerts如何在部署和调用交易中使用的详细信息参见4.3节,交易安全是在基础设施层面提供的。 - -TCerts可容纳的加密或密钥协议的公共密钥(以及数字签名的验证公钥)。 -如果配备好TCert,那么就需要注册证书不能包含加密或密钥协议的公钥。 - -这样的密钥协议的公钥,Key_Agreement_TCertPub_Key,可以由交易认证机构(TCA)使用与生成Signature_Verification_TCertPub_Key同样的方法,使用TCertIndex + 1 而不是TCertIndex来作为索引个值来生成,其中TCertIndex是由TCA为了恢复而隐藏在TCert中的。 - -交易证书(TCert)的结构如下所述: -* TCertID – 交易证书ID(为了避免通过隐藏的注册ID发生的意外可关联性,最好由TCA随机生成). -* Hidden Enrollment ID: AES_EncryptK(enrollmentID), 其中密钥K = [HMAC(Pre-K, TCertID)]256位截断其中为每个K定义三个不同的密钥分配方案:(a), (b) and (c)。 -* Hidden Private Keys Extraction: AES_EncryptTCertOwner_EncryptKey(TCertIndex || 已知的填充/校验检查向量) 其中||表示连接,其中各个批次具有被加到计数器的唯一(每个批次)的时间戳/随机偏移量(这个实现中初始化为1)来生成TCertIndex。该计数器可以通过每次增加2来适应TCA生成公钥,并由这两种类型的私钥的TCert所有者来恢复,如签名密钥对和密钥协商密钥对。 -* Sign Verification Public Key – TCert签名验证的公共密钥。 -* Key Agreement Public Key – TCert密钥协商的公钥。 -* Validity period – 该交易证书可用于交易的外/外部签名的时间窗口。 - -这里至少有三种方式来配置考虑了隐藏注册ID域密钥的分配方案: - -*(a)* Pre-K在注册期间发给用户,peer 和审计员,并对TCA和授权的审计员可用。它可能,例如由Kchain派生(会在这个规范的后面描述)或为了链码的保密性使用独立的key(s)。 - -*(b)* Pre-K对验证器,TCA和授权的审计员可用。K是在验证器成功响应用户的查询交易(通过TLS)后可用给的。查询交易可以使用与调用交易相同的格式。对应下面的例1,如果查询用户又有部署交易的ACL中的一张TCert,那么就可以得到创建这个部署交易的用户的注册ID(enrollmentID)。对应下面的例2,如果查询所使用TCert的注册ID(enrollmentID)与部署交易中访问控制域的其中一个隶属关系/角色匹配,那么就可以得到创建这个部署交易的用户的注册ID(enrollmentID)。 - -*Example 1:* - -![Example 1](./images/sec-example-1.png) - -*Example 2:* - -![Example 2](./images/sec-example-2.png) - -*(c)* -Pre-K对TCA和授权的审计员可用。对于批量中的所有TCert,TCert特有的K可以和TCert一起分发给TCert的所有者(通过TLS)。这样就通过K的TCert所有者启用目标释放(TCert所有者的注册ID的可信通知)。这样的目标释放可以使用预定收件人的密钥协商公钥和/或PKchain其中SKchain就像规范的后面描述的那样对验证器可用。这样目标释放给其它合同的参与者也可以被纳入到这个交易或在频外完成。 - - -如果TCert与上述的ECert模型A的结合使用,那么使用K不发送给TCert的所有者的方案(c)就足够了。 -如果TCert与上述的ECert模型A的结合使用,那么TCert中的密钥协商的公钥域可能就不需要了。 - -交易认证中心(TCA)以批量的方式返回TCert,每个批量包含不是每个TCert都有的,但是和TCert的批量一起传递到客户端的KeyDF_Key(Key-Derivation-Function Key) (通用TLS)。KeyDF_Key允许TCert的拥有者派生出真正用于从AES_EncryptTCertOwner_EncryptKey(TCertIndex || 已知的填充/校验检查向量)的TCertIndex恢复的TCertOwner_EncryptKey。 - -*TLS证书(TLS-Certs)* -TLS-Certs 是用于系统/组件到系统/组件间通讯所使用的证书。他们包含所有者的身份信息,使用是为了保证网络基本的安全。 - -成员管理的这个实现提供下面描述的基础功能:ECerts是没有到期/废止的;TCert的过期是由验证周期的时间窗口提供的。TCerts是没有废止的。ECA,TCA和TLS CA证书是自签名的,其中TLS CA提供信任锚点。 - - -#### 4.2.1 用户/客户端注册过程 - -下面这个图高度概括了用户注册过程,它具有离线和在线阶段。 - -![Registration](./images/sec-registration-high-level.png) - -*离线处理:* 在第一步中,每个用户/非验证 peer /验证 peer 有权在线下将较强的识别凭证(身份证明)到导入到注册机构(RA)。这需要在频外给RA提供为用户创建(存储)账号的证据凭证。第二步,RA返回对应的用户名/密码和信任锚点(这个实现中是TLS-CA Cert)给用户。如果用户访问了本地客户端,那么这是客户端可以以TLS-CA证书作为信任锚点来提供安全保障的一种方法。 - -*在线阶段:* 第三步,用户连接客户端来请求注册到系统中。用户发送它的用户名和密码给客户端。客户端代表用户发送请求给PKI框架。第四步,接受包,第五步,包含其中一些对应于由客户端私有/秘密密钥的若干证书。一旦客户端验证包中所有加密材料是正确/有效的,他就把证书存储在本地并通知用户。这时候用户注册就完成了。 - -![Figure 4](./images/sec-registration-detailed.png) - -图4展示了注册的详细过程。PKI框架具有RA, ECA, -TCA和TLS-CA这些实体。第一步只收,RA调用“AddEntry”函数为它的数据库输入(用户名/密码)。这时候用户已正式注册到系统数据库中。客户端需要TLS-CA证书(当作信任锚点)来验证与服务器之间的TLS握手是正确的。第四步,客户端发送包含注册公钥和像用户名,密码这样的附加身份信息的注册请求到ECA(通过TLS备案层协议)。ECA验证这个用户是否真实存在于数据库。一旦它确认用户有权限提交他/她的注册公钥,那么ECA就会验证它。这个注册信息是一次性的。ECA会更新它的数据库来标识这条注册信息(用户名,密码)不能再被使用。ECA构造,签名并送回一张包含用户注册公钥的(步骤5)注册证书(ECert)。它同样会发送将来会用到(客户端需要向TCA证明他/她的ECert使用争取的ECA创建的)的ECA证书(ECA-Cert))。(尽管ECA-Cert在最初的实现中是自签名的,TCA,TLS-CA和ECA是共址)第六步,客户端验证ECert中的公钥是最初由客户端提交的(即ECA没有作弊)。它同样验证ECert中的所有期望的信息存在且形式正确。 - -同样的,在第七步,客户端发送包含它的公钥和身份的注册信息到TLS-CA。TLS-CA验证该用户在数据库中真实存在。TLS-CA生成,签名包含用户TLS公钥的一张TLS-Cert(步骤8)。TLS-CA发送TLS-Cert和它的证书(TLS-CA Cert)。第九步类似于第六步,客户端验证TLS Cert中的公钥是最初由客户端提交的,TLS Cert中的信息是完整且形式正确。在第十步,客户端在本地存储中保存这两张证书的所有证书。这时候用户就注册完成了。 - - -在这个版本的实现中验证器的注册过程和 peer 的是一样的。尽管,不同的实现可能使得验证器直接通过在线过程来注册。 - -![Figure 5](./images/sec-request-tcerts-deployment.png) -![Figure 6](./images/sec-request-tcerts-invocation.png) - -*客户端:* 请求TCert批量需要包含(另外计数),ECert和使用ECert私钥签名的请求(其中ECert的私钥使用本地存储获取的) - -*TCA为批量生成TCerts:* 生成密钥派生函数的密钥,KeyDF_Key, 当作HMAC(TCA_KDF_Key, EnrollPub_Key). 为每张TCert生成公钥(使用TCertPub_Key = EnrollPub_Key + ExpansionValue G, 其中384位的ExpansionValue = HMAC(Expansion_Key, TCertIndex) 和384位的Expansion_Key = HMAC(KeyDF_Key, “2”)). 生成每个AES_EncryptTCertOwner_EncryptKey(TCertIndex || 已知的填充/校验检查向量), 其中|| 表示连接,且TCertOwner_EncryptKey被当作[HMAC(KeyDF_Key, -“1”)]派生256位截断. - -*客户端:* 为部署,调用和查询,根据TCert来生成TCert的私钥:KeyDF_Key和ECert的私钥需要从本地存储中获取。KeyDF_Key是用来派生被当作[HMAC(KeyDF_Key, “1”)]256位截断的TCertOwner_EncryptKey;TCertOwner_EncryptKey是用来对TCert中的 AES_EncryptTCertOwner_EncryptKey(TCertIndex || -已知的填充/校验检查向量)域解密的;TCertIndex是用来派生TCert的私钥的: TCertPriv_Key = (EnrollPriv_Key + ExpansionValue)模n,其中384位的ExpansionValue = HMAC(Expansion_Key, TCertIndex),384位的Expansion_Key = HMAC(KeyDF_Key, “2”)。 - -#### 4.2.2 过期和废止证书 -实际是支持交易证书过期的。一张交易证书能使用的时间窗是由‘validity period’标识的。实现过期支持的挑战在于系统的分布式特性。也就是说,所有验证实体必须共享相同的信息;即,与交易相关的有效期验证需要保证一致性。为了保证有效期的验证在所有的验证器间保持一致,有效期标识这一概念被引入。这个标识扮演着逻辑时钟,使得系统可以唯一识别有效期。在创世纪时,链的“当前有效期”由TCA初始化。至关重要的是,此有效期标识符给出随时间单调增加的值,这使得它规定了有效期间总次序。 - -对于指定类型的交易,系统交易有效周期标识是用来一起向区块链公布有效期满的。系统交易涉及已经在创世纪块被定义和作为基础设施的一部分的合同。有效周期标识是由TCA周期性的调用链码来更新的。注意,只有TCA允许更新有效期。TCA通过给定义了有效期区间的‘not-before’和‘not-after’这两个域设置合适的整数值来为每个交易证书设置有效期。 - -TCert过期: -在处理TCert时,验证器从状态表中读取与总账中的‘current validity period’相关的值来验证与交易相关的外部证书目前是否有效。状态表中的当前值需要落在TCert的‘not-before’和‘not-after’这两个子域所定义的区间中。如果满足,那么验证器就继续处理交易。如果当前值没有在这个区间中,那么TCert已经过期或还没生效,那么验证器就停止处理交易。 - -ECert过期: -注册证书与交易证书具有不同的有效期长度。 - -废止是由证书废止列表(CRLs)来支持的,CRLs鉴定废止的证书。CRLs的改变,增量的差异通过区块链来公布 - -### 4.3 基础设施层面提供的交易安全 - -fabric中的交易是通过提交用户-消息来引入到总账中的。就像之前章节讨论的那样,这些信息具有指定的结构,且允许用户部署新的链码,调用已经存在的链码,或查询已经存在的链码的状态。因此交易的方式被规范,公布和处理在整个系统提供的隐私和安全中起着重要的作用。 - -一方面我们的成员服务通过检查交易是由系统的有效用户创建的来提供验证交易的手段,为了把用户身份和交易撇清,但是在特定条件下又需要追踪特定个体的交易(执法,审计)。也就是说,成员服务提供结合用户隐私与问责制和不可抵赖性来提供交易认证机制。 - -另一方面,fabric的成员服务不能单独提供完整的用户活动隐私。首先fabric提供完整的隐私保护条款,隐私保护认证机制需要通过交易保密协同。很明显,如果认为链码的内容可能会泄漏创建者的信息,那么这就打破了链码创建者的隐私要求。第一小节讨论交易的保密性。 - - - -为链码的调用强制访问控制是一个重要的安全要求。fabric暴露给应用程序(例如,链码创建者)这意味着当应用利用fabric的成员服务是,需要应用自己调用访问控制。4.4节详细阐述了这一点。 - - - -重放攻击是链码安全的另一个重要方面,作为恶意用户可能复制一个之前的,已经加入到区块链中的交易,并向网络重放它来篡改它的操作。这是第4.3.3节的话题。 - -本节的其余部分介绍了基础设施中的安全机制是如何纳入到交易的生命周期中,并分别详细介绍每一个安全机制。 - -#### 4.3.1 交易安全的生命周期 -交易在客户端创建。客户端可以是普通的客户端,或更专用的应用,即,通过区块链处理(服务器)或调用(客户端)具体链码的软件部分。这样的应用是建立在平台(客户端)上的,并在4.4节中详细介绍。 - -新链码的开发者可以通过这些fabric的基础设施来新部署交易: -* 希望交易符合保密/安全的版本和类型 -* 希望访问部分链码的用户有适当的(读)访问权限 - -* 链码规范 -* 代码元数据,包含的信息需要在链码执行时传递给它(即,配置参数),和 -* 附加在交易结构上的并只在应用部署链码时使用的交易元数据 - -具有保密限制的链码的调用和查询交易都是用类似的方式创建。交易者提供需要执行的链码的标识,要调用的函数的名称及其参数。可选的,调用者可以传递在链码执行的时候所需要提供的代码调用元数据给交易创建函数。交易元数据是调用者的应用程序或调用者本身为了它自己的目的所使用的另外一个域。 - -最后,交易在客户端,通过它们的创建者的证书签名,并发送给验证器网络。 -验证器接受私密交易,并通过下列阶段传递它们: -* *预验证*阶段,验证器根据根证书颁发机构来验证交易证书,验证交易(静态的)中包含交易证书签名,并验证交易是否为重放(参见,下面关于重放攻击的详细信息)。 -* *共识*阶段, 验证器把这笔交易加入到交易的全序列表中(最终包含在总账中) -* *预执行*阶段, 验证交易/注册证书是否在当前的有效期中 - 解密交易(如果交易是加密的),并验证交易明文的形式正确(即,符合调用访问控制,包含TCert形式正确) - 在当前处理块的事务中,也执行了简单的重放攻击检查。 -* *执行*阶段, (解密的) 链码和相关的代码元数据被传递给容器,并执行。 -* *提交* 阶段, (解密的)更新的链码的状态和交易本身被提交到总账中。 - - -#### 4.3.2 交易保密性 - -在开发人员的要求下,交易机密性要求链码的原文,即代码,描述,是不能被未授权的实体(即,未被开发人员授权的用户或 peer)访问或推导(assuming a computational attacker)出来。对于后者,*部署*和*调用*交易的内容始终被隐藏对链码的保密需求是至关重要的。本着同样的精神,未授权方,不应该能联系链码(调用交易)与链码本身(部署交易)之间的调用关系或他们之间的调用。 - - -任何候选的解决方案的附加要求是,满足并支持底层的成员服务的隐私和安全规定。此外,在fabric中他不应该阻止任何链码函数的调用访问控制,或在应用上实现强制的访问控制机制(参看4.4小结)。 - -下面提供了以用户的粒度来设置的交易机密性机制的规范。最后小结提供了一些如何在验证器的层次来扩展这个功能的方针。当前版本所支持的特性和他的安全条款可以在4.7节中找到。 - - -目标是达到允许任意的子集实体被允许或限制访问链码的下面所展示的部分: -1. 链码函数头,即,包含在链码中函数的原型 - - -2. 链码[调用&] 状态,即, 当一个或多个函数被调用时,连续更新的特定链码的状态。 -3. 所有上面所说的 - -注意,这样的设计为应用提供利用fabric的成员管理基础设施和公钥基础设施来建立自己的访问控制策略和执法机制的能力。 - -##### 4.3.2.1 针对用户的保密 - -为了支持细粒度的保密控制,即,为链码创建者定义的用户的子集,限制链码的明文读权限,一条绑定到单个长周期的加密密钥对的链(PKchain, SKchain)。 - -尽管这个密钥对的初始化是通过每条链的PKI来存储和维护的,在之后的版本中,这个限制将会去除。链(和相关的密钥对)可以由任意带有*特定*(管理)权限的用户通过区块链来触发(参看4.3.2.2小节) - -**搭建**. 在注册阶段, 用户获取(像之前一样)一张注册证书,为用户ui标记为Certui,其中每个验证器vj获取的注册证书标记为Certvj。注册会给用户或验证器发放下面这些证书: - -1. 用户: - - a. 声明并授予自己签名密钥对(spku, ssku) - - b. 申明并授予他们加密密钥对(epku, esku), - - c. 获取链PKchain的加密(公共)密钥 - -2. 验证器: - - a. 声明并授予他们签名密钥对(spkv, sskv) - - b. 申明并授予他们加密密钥对 (epkv, eskv), - - c. 获取链SKchain的解密(秘密)密钥 - -因此,注册证书包含两个密钥对的公共部分: -* 一个签名密钥对[为验证器标记为(spkvj,sskvj),为用户标记为(spkui, sskui)] 和 -* 一个加密密钥对[为验证器标记为(epkvj,eskvj),为用户标记为(epkui, eskui)] - -链,验证器和用户注册公钥是所有人都可以访问的。 - -除了注册证书,用户希望通过交易证书的方式匿名的参与到交易中。用户的简单交易证书ui被标记为TCertui。交易证书包含的签名密钥对的公共部分标记为(tpkui,tskui)。 - -下面的章节概括性的描述了如何以用户粒度的方式提供访问控制。 - -**部署交易的结构.** -下图描绘了典型的启用了保密性的部署交易的结构。 - -![FirstRelease-deploy](./images/sec-usrconf-deploy.png) - -注意,部署交易由几部分组成: -* *基本信息*部分: 包含交易管理员的详细信息,即这个交易对应于哪个链(链接的),交易的类型(设置''deplTrans''),实现的保密协议的版本号,创建者的身份(由注册证书的交易证书来表达),和主要为了防止重放攻击的Nonce。 -* *代码信息*部分: 包含链码的源码,函数头信息。就像下图所展示的那样,有一个对称密钥(KC)用于链码的源代码,另一个对称密钥(KH)用于函数原型。链码的创建者会对明文代码做签名,使得信函不能脱离交易,也不能被其他东西替代。 -* *链验证器*部分: 为了(i)解密链码的源码(KC),(ii)解密函数头,和(iii)当链码根据(KS)调用时加密状态。尤其是链码的创建者为他部署的链码生产加密密钥对(PKC, SKC)。它然后使用PKC加密所有与链码相关的密钥: -
[(''code'',KC) ,(''headr'',KH),(''code-state'',KS), SigTCertuc(\*)]PKc,
并把 -where appropriate key material is passed to the - In particular, the chain-code creator - generates an encryption key-pair for the chain-code it deploys - (PKC, SKC). It then uses PKC - to encrypt all the keys associated to the chain-code: -
[(''code'',KC) ,(''headr'',KH),(''code-state'',KS), SigTCertuc(\*)]PKc,
私钥SKC通过链指定的公钥: -
[(''chaincode'',SKC), SigTCertuc(*)]PKchain.
-传递给验证器。 -* *合同用户*部分: 合同用户的公共密钥,即具有部分链码读权限的用户,根据他们的访问权限加密密钥: - - 1. SKc使得用户能读取与这段链码相关的任意信息(调用,状态,等) - - 2. KC使用户只能读取合同代码 - - 3. KH 使用户只能读取头信息 - - 4. KS使用户只能读取与合同相关的状态 - - 最后给用户发放一个合同的公钥PKc,使得他们可以根据合同加密信息,从而验证器(or any in possession of SKc)可以读取它。每个合同用户的交易证书被添加到交易中,并跟随在用户信息之后。这可以使得用户可以很容易的搜索到有他们参与的交易。注意,为了信函可以在本地不保存任何状态的情况下也能通过分析总账来获取这笔交易,部署交易也会添加信息到链码创建者uc。 - -整个交易由链码的创建者的证书签名,即:由后者决定使用注册还是交易证书。 -两个值得注意的要点: -* 交易中的信息是以加密的方式存储的,即,code-functions, -* code-hdrs在使用TCert加密整个交易之前会用想用的TCert签名,或使用不同的TCert或ECert(如果交易的部署需要带上用户的身份。一个绑定到底层交易的载体需要包含在签名信息中,即,交易的TCert的哈希是签名的,因此mix\&match攻击是不可能的。我们在4.4节中详细讨论这样的攻击,在这种情况下,攻击者不能从他看到的交易中分离出对应的密文,即,代码信息,并在另一个交易中使用它。很明显,这样会打乱整个系统的操作,链码首先有用户A创建,现在还属于恶意用户B(可能没有权限读取它) -* 为了给用户提供交叉验证的能力,会给他们访问正确密钥的权限,即给其他用户相同的密钥,使用密钥K对交易加密成密文,伴随着对K的承诺,而这一承诺值开放给所有在合同中有权访问K的用户,和链验证器。 - - 在这种情况下,谁有权访问该密钥,谁就可以验证密钥是否正确传递给它。为了避免混乱,这部分在上图中省略了。 - - -**调用交易的结构.** -下图结构化描述了,交易调用链码会触发使用用户指定的参数来执行链码中的函数 - -![FirstRelease-deploy](./images/sec-usrconf-invoke.png) - -调用交易和部署交易一样由一个*基本信息*, *代码信息*,*链验证器*和一个*合同用户*,并使用一张调用者的交易证书对所有进行签名。 - -- 基本信息 与部署交易中对应部分遵循相同的结构。唯一的不同是交易类型被设置为''InvocTx'',链码的标识符或名字是通过链指定的加密(公共)密钥来加密的。 - -- 代码信息 部署交易中的对应结构具有相同展现。在部署交易中作为代码有效载荷,现在由函数调用明细(调用函数的名字,对应的参数),由应用提供的代码元数据和交易创建者(调用者 - u)的证书,TCertu。在部署交易的情况下,代码有效载荷和是通过调用者u的交易证书TCertu签名的。在部署交易的情况下,代码元数据,交易数据是由应用提供来使得信函可以实现他自己的访问控制机制和角色(详见4.4节)。 - -- 最后,合同用户和链验证器部分提供密钥和有效荷载是使用调用者的密钥加密的,并分别链加密密钥。在收到此类交易,验证器解密 [code-name]PKchain使用链指定的密钥SKchain ,并获取被调用的链码身份。给定的信封,验证器从本地的获取链码的解密密钥SKc,并使用他来解密链验证器的信息,使用对称密钥 - KI对调用交易的有效荷载加密。给定信函,验证器解密代码信息,并使用指定的参数和附加的代码元数据(参看4.4节的代码元数据详细信息)执行链码。当链码执行后,链码的状态可能就更新了。 - 加密所使用的状态特定的密钥Ks在链码部署的时候就定义了。尤其是,在当前版本中Ks 和KiTx被设计成一样的(参看4.7节)。 - -**查询交易的结构.** -查询交易和调用交易具有同样的格式。唯一的区别是查询交易对链码的状态没有影响,且不需要在执行完成之后获取(解密的)并/或更新(加密的)状态。 - -##### 4.3.2.2 针对验证器的保密 -这节阐述了如何处理当前链中的不同(或子集)集合的验证器下的一些交易的执行。本节中抑制IP限制,将在接下的几个星期中进行扩展。 - - -#### 4.3.3 防重放攻击 -在重放攻击中,攻击者“重放”他在网络上“窃听”或在区块链''看到''的消息 -由于这样会导致整个验证实体重做计算密集型的动作(链码调用)和/或影响对应的链码的状态,同时它在攻击侧又只需要很少或没有资源,所以重放攻击在这里是一个比较大的问题。如果交易是一个支付交易,那么问题就更大了,重放可能会导致在不需要付款人的参与下,多于一次的支付。 -当前系统使用以下方式来防止重放攻击: -* 在系统中记录交易的哈希。这个方法要求验证器为每个交易维护一个哈希日志,发布到网络上,并把每个新来的交易与本地存储的交易记录做对比。很明显这样的方法是不能扩展到大网络的,也很容易导致验证器花了比真正做交易还多的时间在检查交易是不是重放上。 -* 利用每个用户身份维护的状态(Ethereum).Ethereum保存一些状态,即,对每个身份/伪匿名维护他们自己的计数器(初始化为1)。每次用户使用他的身份/伪匿名发送交易是,他都把他的本地计数器加一,并把结果加入到交易中。交易随后使用用户的身份签名,并发送到网络上。当收到交易时,验证器检查计数器并与本地存储的做比较;如果值是一样的,那就增加这个身份在本地的计数器,并接受交易。否则把交易当作无效或重放的而拒绝掉。尽管这样的方法在有限个用户身份/伪匿名(即,不太多)下工作良好。它最终在用户每次交易都使用不同的标识(交易证书),用户的伪匿名与交易数量成正比时无法扩展。 - -其他资产管理系统,即比特币,虽然没有直接处理重放攻击,但它防止了重放。在管理(数字)资产的系统中,状态是基于每个资产来维护的,即,验证器只保存谁拥有什么的记录。因为交易的重放根据协议(因为只能由资产/硬币旧的所有者衍生出来)可以直接认为无效的,所以防重放攻击是这种方式的直接结果。尽管这合适资产管理系统,但是这并不表示在更一般的资产管理中需要比特币系统。 - -在fabric中,防重放攻击使用混合方法。 -这就是,用户在交易中添加一个依赖于交易是匿名(通过交易证书签名)或不匿名(通过长期的注册证书签名)来生成的nonce。更具体的: -* 用户通过注册证书来提交的交易需要包含nonce。其中nonce是在之前使用同一证书的交易中的nonce函数(即计数器或哈希)。包含在每张注册证书的第一次交易中的nonce可以是系统预定义的(即,包含在创始块中)或由用户指定。在第一种情况中,创世区块需要包含nonceall,即,一个固定的数字和nonce被用户与身份IDA一起用来为他的第一笔注册证书签名的交易将会 -
nonceround0IDA <- hash(IDA, nonceall),
-其中IDA出现在注册证书中。从该点之后的这个用户关于注册证书的连续交易需要包含下面这样的nonce -
nonceroundiIDA <- hash(nonceround{i-1}IDA),
-这表示第i次交易的nonce需要使用这样证书第{i-1}次交易的nonce的哈希。验证器持续处理他们收到的只要其满足上述条件的交易。一旦交易格式验证成功,验证器就使用nonce更新他们的数据库。 - - **存储开销**: - - 1. 在用户侧:只有最近使用的nonce - - 2. 在验证器侧: O(n), 其中n是用户的数量 -* 用户使用交易证书提交的交易需要包含一个随机的nonce,这样就保证两个交易不会产生同样的哈希。如果交易证书没有过期的话,验证器就向本地数据库存储这笔交易的哈希。为了防止存储大量的哈希,交易证书的有效期被利用。特别是验证器为当前或未来有效周期来维护一个接受交易哈希的更新记录。 - - **存储开销** (这里只影响验证器): O(m), 其中m近似于有效期内的交易和对应的有效标识的数量(见下方) - -### 4.4 应用的访问控制功能 - -应用是运行在区块链客户端软件上的一个具有特定功能的软件。如餐桌预订。应用软件有一个开发版本,使后者可以生成和管理一些这个应用所服务的行业所需要的链码,而且,客户端版本可以允许应用的终端用户调用这些链码。应用可以选择是否对终端用户屏蔽区块链。 - -本节介绍应用中如何使用链码来实现自己的访问控制策略,并提供如何使用成员服务来达到相同的目的。 - -这个报告可以根据应用分为调用访问控制,和读取访问控制。 - - -#### 4.4.1 调用访问控制 -为了允许应用在应用层安全的实现自己的访问问控制,fabric需要提供特定的支持。在下面的章节中,我们详细的说明的fabric为了达到这个目的而给应用提供的工具,并为应用如何来使用它们使得后者能安全的执行访问控制提供方针。 - -**来自基础设施的支持.** -把链码的创建者标记为 *uc*,为了安全的实现应用层自己的调用访问控制,fabric必须需要提供特定的支持。 -更具体的,fabric层提供下面的访问能力: - -1. 客户端-应用可以请求fabric使用指定的客户端拥有的交易证书或注册证书来签名和验证任何消息; 这是由Certificate Handler interface来处理的。 - -2. 客户端-应用可以请求fabric一个*绑定*将身份验证数据绑定到底层的交易传输的应用程序;这是由Certificate Handler interface来处理的。 - -3. 为了支持交易格式,允许指定被传递给链码在部署和调用时间的应用的元数据;后者被标记为代码元数据。 - -**Certificate Handler**接口允许使用底层证书的密钥对来对任意消息进行签名和验证。证书可以是TCert或ECert。 - -``` -// CertificateHandler exposes methods to deal with an ECert/TCert -type CertificateHandler interface { - - // GetCertificate returns the certificate's DER - GetCertificate() []byte - - // Sign signs msg using the signing key corresponding to the certificate - Sign(msg []byte) ([]byte, error) - - // Verify verifies msg using the verifying key corresponding to the certificate - Verify(signature []byte, msg []byte) error - - // GetTransactionHandler returns a new transaction handler relative to this certificate - GetTransactionHandler() (TransactionHandler, error) -} -``` -**Transaction Handler**借口允许创建交易和访问可利用的底层*绑定*来链接应用数据到底层交易。绑定是在网络传输协议引入的概念(参见,https://tools.ietf.org/html/rfc5056)记作*通道绑定*,*允许应用在网络层两端的建立安全通道,与在高层的认证绑定和在低层是一样的。 -这允许应用代理保护低层会话,这具有很多性能优势。* -交易绑定提供识别fabric层次交易的身份,这就是应用数据要加入到总账的容器。 - -``` -// TransactionHandler represents a single transaction that can be uniquely determined or identified by the output of the GetBinding method. -// This transaction is linked to a single Certificate (TCert or ECert). -type TransactionHandler interface { - - // GetCertificateHandler returns the certificate handler relative to the certificate mapped to this transaction - GetCertificateHandler() (CertificateHandler, error) - - // GetBinding returns a binding to the underlying transaction (container) - GetBinding() ([]byte, error) - - // NewChaincodeDeployTransaction is used to deploy chaincode - NewChaincodeDeployTransaction(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string) (*obc.Transaction, error) - - // NewChaincodeExecute is used to execute chaincode's functions - NewChaincodeExecute(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) - - // NewChaincodeQuery is used to query chaincode's functions - NewChaincodeQuery(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) -} -``` -对于版本1,*绑定*由*hash*(TCert, Nonce)组成,其中TCert是给整个交易签名的交易证书,Nonce是交易所使用的nonce。 - -**Client**接口更通用,提供之前接口实例的手段。 - -``` -type Client interface { - - ... - - // GetEnrollmentCertHandler returns a CertificateHandler whose certificate is the enrollment certificate - GetEnrollmentCertificateHandler() (CertificateHandler, error) - - // GetTCertHandlerNext returns a CertificateHandler whose certificate is the next available TCert - GetTCertificateHandlerNext() (CertificateHandler, error) - - // GetTCertHandlerFromDER returns a CertificateHandler whose certificate is the one passed - GetTCertificateHandlerFromDER(der []byte) (CertificateHandler, error) - -} -``` - -为了向链码调用控制提供应用级别的的访问控制列表,fabric的交易和链码指定的格式需要存储在应用特定元数据的额外的域。 -这个域在图1中通过元数据展示出来。这个域的内容是由应用在交易创建的时候决定的。fabric成把它当作非结构化的字节流。 - - -``` - -message ChaincodeSpec { - - ... - - ConfidentialityLevel confidentialityLevel; - bytes metadata; - - ... -} - - -message Transaction { - ... - - bytes payload; - bytes metadata; - - ... -} -``` - -为了帮助链码执行,在链码调用的时候,验证器为链码提供额外信息,如元数据和绑定。 - -**应用调用访问控制.** -这一节描述应用如何使用fabric提供的手段在它的链码函数上实现它自己的访问控制。 -这里考虑的情况包括: - -1. **C**: 是只包含一个函数的链码,如,被成为*hello* - -2. **uc**: 是**C**的部署; - -3. **ui**: 是被授权调用**C**的用户。用户uc希望只有ui可以调用函数*hello* - -*链码部署:* 在部署的时候,uc具有被部署交易元数据的完全控制权,可硬存储一个ACL的列表(每个函数一个),或一个应用所需要的角色的列表。存储在ACL中的格式取决于部署的交易,链码需要在执行时解析元数据。 -为了定义每个列表/角色,uc可以使用ui的任意TCerts/Certs(或,如果可接受,其他分配了权限或角色的用户)。把它记作TCertui。 -开发者和授权用户之间的TCerts和 Certs交换实在频外渠道进行的。 - -假设应用的uc需要调用 *hello*函数,某个消息*M*就被授权给授权的调用者(在我们的例子中是ui)。 -可以区分为以下两种情况: - -1. *M*是链码的其中一个函数参数; - -2. *M*是调用信息本事,如函数名,函数参数。 - -*链码调用:* -为了调用C, ui的应用需要使用TCert/ECert对*M*签名,用来识别ui在相关的部署交易的元数据中的参与身份。即,TCertui。更具体的,ui的客户端应用做一下步骤: - -1. Certui, *cHandler*获取CertificateHandler - -2. 获取新的TransactionHandler来执行交易, *txHandler*相对与他的下一个有效的TCert或他的ECert - -3. 通过调用*txHandler.getBinding()*来得到*txHandler*的绑定 - -4. 通过调用*cHandler.Sign('*M* || txBinding')*来对*'*M* || txBinding'*签名, *sigma*是签名函数的输出。 - -5. 通过调用来发布一个新的执行交易,*txHandler.NewChaincodeExecute(...)*. 现在, *sigma*可以以一个传递给函数(情形1)参数或payload的元数据段的一部分(情形2)的身份包含在交易中。 - -*链码处理:* -验证器, 从ui处接受到的执行交易将提供以下信息: - -1. 执行交易的*绑定*,他可以在验证端独立的执行; - -2. 执行交易的*元数据*(交易中的代码元数据); - -3. 部署交易的*元数据*(对应部署交易的代码元数据组建). - -注意*sigma*是被调用函数参数的一部分,或者是存储在调用交易的代码元数据内部的(被客户端应用合理的格式化)。 -应用ACL包含在代码元数据段中,在执行时同样被传递给链码。 -函数*hello*负责检查*sigma*的确是通过TCertui在'*M* || *txBinding'*上的有效签名。 - -#### 4.4.2 读访问控制 -这节描述fabric基础设施如何支持应用在用户层面执行它自己的读访问控制策略。和调用访问控制的情况一样,第一部分描述了可以被应用程序为实现此目的利用的基础设施的功能,接下来介绍应用使用这些工具的方法。 - -为了说明这个问题,我们使用和指点一样的例子,即: - -1. **C**: 是只包含一个函数的链码,如,被成为*hello* - -2. **uA**: 是**C**的部署者,也被成为应用; - -3. **ur**: 是被授权调用**C**的用户。用户uA希望只有ur可以读取函数*hello* - -**来自基础设施的支持.** -为了让**uA**在应用层安全的实现自己的读取访问控制我们的基础设施需要像下面描述的那样来支持代码的部署和调用交易格式。 - -![SecRelease-RACappDepl title="Deployment transaction format supporting application-level read access control."](./images/sec-usrconf-deploy-interm.png) - -![SecRelease-RACappInv title="Invocation transaction format supporting application-level read access control."](./images/sec-usrconf-invoke-interm.png) - -更具体的fabric层需要提供下面这些功能: - -1. 为数据只能通过验证(基础设施)侧解密,提供最低限度的加密功能;这意味着基础设施在我们的未来版本中应该更倾向于使用非对称加密方案来加密交易。更具体的,在链中使用在上图中标记为 Kchain 的非对称密钥对。具体参看交易保密小节 - -2. 客户端-引用可以请求基础设施,基于客户端侧使用特定的公共加密密钥或客户端的长期解密密钥来加密/解密信息。 - -3. 交易格式提供应用存储额外的交易元数据的能力,这些元数据可以在后者请求后传递给客户端应用。交易元数据相对于代码元数据,在执行时是没有加密或传递给链码的。因为验证器是不负责检查他们的有效性的,所以把它们当作字节列表。 - -**应用读访问控制.** -应用可以请求并获取访问用户**ur**的公共加密密钥,我们把它标记为**PKur**。可选的,**ur** 可能提供 **uA**的一张证书给应用,使应用可以利用,标记为TCertur。如:为了跟踪用户关于应用的链码的交易。TCertur和PKur实在频外渠道交换的。 - -部署时,应用 **uA**执行下面步骤: - -1. 使用底层基础设施来加密**C**的信息,应用使用PKur来访问**ur**。标记Cur为得到的密文。 - -2. (可选) Cur可以和TCertur连接 - -3. 保密交易被构造为''Tx-metadata''来传递 - -在调用的时候,在 ur节点上的客户端-应用可以获取部署交易来得到**C**的内容。 -这只需要得到相关联的部署交易的 **tx-metadata**域,并触发区块链基础设施客户端为Cur提供的解密函数。注意,为ur正确加密**C**是应用的责任。 -此外,使用**tx-metadata**域可以一般性的满足应用需求。即,调用者可以利用调用交易的同一域来传递信息给应用的开发者。 - -**Important Note:** -要注意的是验证器在整个执行链码过程中**不提供**任何解密预测。 -对payload解密由基础设施自己负责(以及它附近的代码元数据域)。并提供他们给部署/执行的容器。 - -### 4.5 在线钱包服务 -这一节描述了钱包服务的安全设计,这是一个用户可以注册,移动他们的秘密材料到,办理交易的节点。 -由于钱包服务是一个用户秘密材料所有权的服务,所以要杜绝没有安全授权机制的恶意钱包服务可以成功模拟客户。 -因此,我们强调的是,设计一种**值得信赖**的,只有在代表用户的客户端同意的情况下,钱包服务才能执行交易。 -这里有两种终端用户注册到在线钱包服务的情况: - -1. 当用户注册到注册机构并获得他/她的 ``,但是没有安装客户端来触发完整的注册过程。 - -2. 用户已经安装客户端并完成注册阶段 - -首先,用户与在线钱包服务交互,允许他们进行身份验证的钱包服务发布证书。即用户给定用户名和密码,其中用户名在成员服务中识别用户,标记为AccPub,密码是关联的秘密,标记为AccSec,这是由用户和服务分享的。 - -为了通过在线钱包服务注册,用户必须提供下面请求对象到钱包服务: - - - AccountRequest /* account request of u \*/ - { - OBCSecCtx , /* credentials associated to network \*/ - AccPubu, /* account identifier of u \*/ - AccSecProofu /* proof of AccSecu\*/ - } - -OBCSecCtx指向用户证书,它依赖于注册过程中的阶段。可以是用户的注册ID和密码,`` 或他的注册证书和关联的密钥(ECertu, sku), 其中 sku是用户签名和解密密钥的简化标记。 -OBCSecCtx需要给在线钱包服务必要的信息来注册用户和发布需要的TCerts。 - -对于后续的请求,用户u需要提供给钱包服务的请求与下面这个格式类似。 - - TransactionRequest /* account request of u \*/ - { - TxDetails, /* specifications for the new transaction \*/ - AccPubu, /* account identifier of u \*/ - AccSecProofu /* proof of AccSecu \*/ - } - -这里,TxDetails指向在线服务代表用户构造交易所需要的信息,如类型,和用户指定的交易的内容。 - -AccSecProofu是对应请求中剩下的域的使用共享密钥的HMAC。 -Nonce-based方法与我们在fabric中一样可以防止重放攻击。 - -TLS连接可以用在每种服务器端认证的情况,在网络层对请求加密(保密,防止重放攻击,等) - - -### 4.6 网络安全(TLS) -TLS CA需要给(非验证)peer,验证器,和单独的客户端(或具有存储私钥的游览器)发放TLS证书的能力。最好,这些证书可以使用之前的类型来区分。 -各个类型的CA(如TLS CA, ECA, TCA)的TLS证书有可以通过中间CA(如,一个根CA的下属CA)发放。这里没有特定流量分析的问题,任意给定的TLS连接都可以相互验证,除了请求TLS CA的TLS证书的时候。 - -在当前的实现中,唯一的信任锚点是TLS CA的自签名证书来适应与所有三个(共址)服务器(即TLS CA,TCA和ECA)进行通信的单个端口限制。因此,与TLS CA的TLS握手来与TLS CA建立连接,所得到的会话密钥会传递给共址的TCA和ECA。因此,TCA和ECA的自签名证书的有效性的信任继承自对TLS CA的信任。在不提高TLS CA在其他CA之上的实现中,信任锚点需要由TLS CA和其他CA都认证的根CA替代。 - - -### 4.7 当前版本的限制 -这一小节列出了当前版本的fabric的限制。 -具体的关注点是客户端操作和交易保密性设计,如4.7.1和4.7.2所述。 - - - 客户端注册和交易的创建是由受信任不会模拟用户的非验证 peer 来完全执行。参看4.7.1节得到更多j信息。 - - 链码只能被系统的成员实体访问是保密性的最低要求,即,注册到我们成员服务的验证器和用户,其它的都不能访问。后者包含可以访问到存储区域维护的总账,或者可以看到在验证器网络上公布的交易。第一个发布版本在4.7.2小节中详细介绍。 - - 代码为注册CA(ECA)和交易CA(TCA)使用自签名的证书 - - 防重放攻击机制还不可用 - - 调用访问控制可以在应用层强制执行: - 安全性的保证取决于应用对基础设施工具的正确使用。这说明如果应用忽略了fabric提供的交易绑定*绑定*安全交易的处理可能在存在风险。 - -#### 4.7.1 简化客户端 - -客户端的注册和交易的创建是由非验证 peer 以在线钱包的角色全部执行的。特别地,终端用户利用他们的注册证书向非验证 peer 开立账户,并且使用这些证书来进一步授权 peer 建立代表用户的交易。 -需要注意的是,这样的设计不会为 peer 代表用户提交的交易提供安全**授权**,如恶意 peer 可以模拟用户。 -网上钱包的涉及安全问题设计规范的详细信息,可以在4.5节找到。 -目前用户可以注册和执行交易的 peer 数量是一。 - -#### 4.7.2 简化交易保密 - -**免责声明:** 当前版本的交易保密是最小的,这被用来作为中间步骤来达到允许在未来版本中的细粒度(调用)的访问控制的执行设计。 - -在当前的格式,交易的保密仅仅在链层面提供,即,保存在总账中的交易内容对链的所有成员,如,验证器和用户,都是可读的。于此同时,不是系统的成员的应用审计人员,可以给予被动的观察区块链数据的手段。同时保证给予他们只是为了与被审计应用程序相关的交易。状态通过一种加密,同时不破坏底层共识网络的正常运行的方式来满足这样的审计要求 - -更具体的,当前使用对称密钥加密来提供交易保密性。 -在这种背景下,一个最主要的挑战是特定于区块链的设置,验证器需要在区块链的状态上打成共识,即,除了交易本身,还包括个人合同或链码的状态更新。 -虽然对于非机密链码这是微不足道的,对于机密链码,需要设计状态的加密机制,使得所得的密文语义安全,然而,如果明文状态是相同的那么他们就相等。 - -为了克服这一难题,fabric利用了密钥的层级,使用相同的密钥进行加密来降低密文数。同时,由于部分这些密钥被用于IV的生成,这使得验证方执行相同的事务时产生完全相同的密文(这是必要的,以保持不可知到底层共识算法),并通过只披露给审计实体最相关的密钥来提供控制审计的可能性。 - -**方法描述:** -成员服务为总账生成对称密钥 (Kchain),这是在注册到区块链系统所有实体时发布的,如,客户端和验证实体已通过链的成员服务发放证书。 -在注册阶段,用户获取(像之前一样)一张注册证书,为用户ui记作Certui,每个验证器vj获取它的被记作Certvj的证书。 - -实体注册将得到提高,如下所示。除了注册证书,用户希望以匿名方式参与交易发放交易证书。 -为了简化我们把用户 ui 的交易证书记作 TCertui。 -交易证书包含签名密钥对的公共部分记作 (tpkui,tskui)。 - -为了防止密码分析和执行保密,下面的密钥层级被用来生成和验证保密的交易: -为了提交保密交易(Tx)到总账,客户端首先选择一个nonce(N),这是需要提交区块链的所有交易中是唯一的,并通过以Kchain作为密钥,nonce作为输入的HMAC函数生成一个交易对称密钥(KTx))KTx= HMAC(Kchain, N)。 -对于KTx,客户端生成两个AES密钥: -KTxCID当作HMAC(KTx, c1), KTxP 当作 HMAC(KTx, c2)) 分别加密链码名称或标识CID和代码(或payload)P. -c1, c2 是公共常量。nonce,加密的链码ID(ECID)和加密的Payload(EP)被添加到交易Tx结构中,即最终签名和认证的。 -下面的图显示了如何产生用于客户端的事务的加密密钥。这张图中的剪头表示HMAC的应用,源由密钥锁定和使用在箭头中的数量作为参数。部署/调用交易的密钥键分别用d/I表示。 - - -![FirstRelease-clientSide](./images/sec-firstrel-1.png) - -为了验证客户端提交到区块链的保密交易Tx,验证实体首先通过和之前一样的Kchain和Tx.Nonce再生成KTxCID和KTxP来解密ECID和EP。一旦链码和Payload被恢复就可以处理交易了。 - -![FirstRelease-validatorSide](./images/sec-firstrel-2.png) - -当V验证一个机密事务,相应的链码可以访问和修改链码的状态。V保持链码的状态加密。为了做到这一点,V生成如上图所示的对称密钥 -。让iTX是一个之前由保密交易dTx部署的保密的交易调用一个函数(注意iTx可以是dTx本身)在这种情况下,例如,dTx具有初始化链码状态的设置函数。然后V像下面一样生成两个对称密钥KIV和Kstate: - -1. 计算KdTx如,对应部署交易的交易密钥和Nstate = HMAC(Kdtx ,hash(Ni))其中Ni是在调用交易中出现的nonce, *hash*是哈希函数 -2. 它设Kstate = HMAC(KdTx, c3 || Nstate),截断用来加密底层密码; c3 是一个常数 -3. 它设KIV = HMAC(KdTx, c4 || Nstate); c4 是一个常数 - -为了加密状态变量S,验证器首先生成IV像 HMAC(KIV, crtstate)正确截断,其中 crtstate是计数器值,并在每次同样链码调用时请求状态更新时增加。当链码执行终止是计数器丢弃。IV产生之后,V认证加密(即,GSM模式)S的值连接Nstate(实际上,Nstate只需要认证而不需要加密)。在所得的密文(CT), Nstate和IV被追加。为了解密加密状态CT|| Nstate',验证器首次生成对称密钥KdTX' ,Kstate',然后解密CT。 - -IV的生成: 任何底层共识算法是不可知的,所有的验证各方需要一种方法以产生相同的确切密文。为了做到这一点,需要验证使用相同的IV。重用具有相同的对称密钥相同的IV完全打破了底层密码的安全性。因此,前面所描述的方法制备。特别是,V首先通过计算HMAC(KdTX, c4 || Nstate )派生的IV生成密钥KIV,其中c4是一个常数,并为(dTx, -iTx)保存计数器crtstate初始设置为0。然后,每次必须生成一个新的密文,验证器通过计算HMAC(KIV, crtstate)作为输出生成新的IV,然后为crtstate增加1。 - -上述密钥层次结构的另一个好处是控制了审计的能力。 -例如,当发布Kchain会提供对整个供应链的读取权限,当只为交易的(dTx,iTx)发布Kstate访问只授予由iTx更新的状态,等等 - - -下图展示一个部署和调用交易在目前在代码中的形式。 - -![FirstRelease-deploy](./images/sec-firstrel-depl.png) - -![FirstRelease-deploy](./images/sec-firstrel-inv.png) - - -可以注意到,部署和调用交易由两部分组成: - -* *基本信息*部分: 包含交易管理细节,如,把这个交易链接到的(被链接到的),交易的类型(被设置为''deploymTx''或''invocTx''),保密策略实现的版本号,它的创建者标识(由TCert,Cert表达)和一个nonce(主要为了防止重放攻击) - -* *代码信息*部分: 包含在链码的源代码的信息。本质上是链码标识符/名称和源代码的部署交易,而对调用链码是是被调用函数名称和它的参数。就像在两张图中展示的代码信息那样他们最终是使用链指定的对称密钥Kchain加密的。 - -## 5. 拜占庭共识 -``obcpbft``包是[PBFT](http://dl.acm.org/citation.cfm?id=571640 "PBFT")共识协议[1]的实现,其中提供了验证器之间的共识,虽然验证器的阈作为_Byzantine_,即,恶意的或不可预测的方式失败。在默认的配置中,PBFT容忍t - -fabric API 设计涵盖的类别如下,虽然当前版本的其中一些实现不完整。[REST API(#62-REST的API)节将说明API当前支持。 - - -* 身份 - 注册来获得或吊销一张证书 -* Address - 交易的源或目的 -* Transaction - 总账上的执行单元 -* Chaincode - 总账上运行的程序 -* Blockchain - 总账的内容 -* Network - 区块链 peer 网络的信息 -* Storage - 文件或文档的外部存储 -* Event Stream - 区块链上订阅/发布事件 - -## 6.1 REST Service -REST服务可以(通过配置)在验证和非验证 peer 被启用,但是建议在生产环境中只启用非验证 peer 的REST服务。 - -``` -func StartOpenchainRESTServer(server *oc.ServerOpenchain, devops *oc.Devops) -``` - -这个函数读取`core.yaml``peer`处理的配置文件中的`rest.address`。`rest.address`键定义了 peer 的HTTP REST服务默认监听的地址和端口。 - -假定REST服务接收来已经认证的终端用户的应用请求。 - -## 6.2 REST API - -您可以通过您所选择的任何工具与REST API的工作。例如,curl命令行实用程序或一个基于浏览器的客户端,如Firefox的REST客户端或Chrome Postman。同样,可以通过 [Swagger](http://swagger.io/) 直接触发REST请求。为了获得REST API Swagger描述,点击 [这里](https://github.com/hyperledger/fabric/blob/master/core/rest/rest_api.json)。目前可用的API总结于以下部分。 - - -### 6.2.1 REST Endpoints - -* [Block](#6211-block-api) - * GET /chain/blocks/{block-id} -* [Blockchain](#6212-blockchain-api) - * GET /chain -* [Chaincode](#6213-chaincode-api) - * POST /chaincode -* [Network](#6214-network-api) - * GET /network/peers -* [Registrar](#6215-registrar-api-member-services) - * POST /registrar - * GET /registrar/{enrollmentID} - * DELETE /registrar/{enrollmentID} - * GET /registrar/{enrollmentID}/ecert - * GET /registrar/{enrollmentID}/tcert -* [Transactions](#6216-transactions-api) - * GET /transactions/{UUID} - -#### 6.2.1.1 块API - -* **GET /chain/blocks/{block-id}** - -使用块API来从区块链中检索各个块的内容。返回的块信息结构是在[3.2.1.1](#3211-block)节中定义 - -块检索请求: -``` -GET host:port/chain/blocks/173 -``` - -块检索响应: -``` -{ - "transactions": [ - { - "type": 3, - "chaincodeID": "EgRteWNj", - "payload": "Ch4IARIGEgRteWNjGhIKBmludm9rZRIBYRIBYhICMTA=", - "uuid": "f5978e82-6d8c-47d1-adec-f18b794f570e", - "timestamp": { - "seconds": 1453758316, - "nanos": 206716775 - }, - "cert": "MIIB/zCCAYWgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMTI1MjE0MTE3WhcNMTYwNDI0MjE0MTE3WjArMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQ4wDAYDVQQDEwVsdWthczB2MBAGByqGSM49AgEGBSuBBAAiA2IABC/BBkt8izf6Ew8UDd62EdWFikJhyCPY5VO9Wxq9JVzt3D6nubx2jO5JdfWt49q8V1Aythia50MZEDpmKhtM6z7LHOU1RxuxdjcYDOvkNJo6pX144U4N1J8/D3A+97qZpKN/MH0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDA9BgYqAwQFBgcBAf8EMABNbPHZ0e/2EToi0H8mkouuUDwurgBYuUB+vZfeMewBre3wXG0irzMtfwHlfECRDDAKBggqhkjOPQQDAwNoADBlAjAoote5zYFv91lHzpbEwTfJL/+r+CG7oMVFUFuoSlvBSCObK2bDIbNkW4VQ+ZC9GTsCMQC5GCgy2oZdHw/x7XYzG2BiqmRkLRTiCS7vYCVJXLivU65P984HopxW0cEqeFM9co0=", - "signature": "MGUCMCIJaCT3YRsjXt4TzwfmD9hg9pxYnV13kWgf7e1hAW5Nar//05kFtpVlq83X+YtcmAIxAK0IQlCgS6nqQzZEGCLd9r7cg1AkQOT/RgoWB8zcaVjh3bCmgYHsoPAPgMsi3TJktg==" - } - ], - "stateHash": "7ftCvPeHIpsvSavxUoZM0u7o67MPU81ImOJIO7ZdMoH2mjnAaAAafYy9MIH3HjrWM1/Zla/Q6LsLzIjuYdYdlQ==", - "previousBlockHash": "lT0InRg4Cvk4cKykWpCRKWDZ9YNYMzuHdUzsaeTeAcH3HdfriLEcTuxrFJ76W4jrWVvTBdI1etxuIV9AO6UF4Q==", - "nonHashData": { - "localLedgerCommitTimestamp": { - "seconds": 1453758316, - "nanos": 250834782 - } - } -} -``` - -#### 6.2.1.2 区块链API - -* **GET /chain** - -使用链API来检索区块链的当前状态。返回区块链信息消息被定义如下。 - -``` -message BlockchainInfo { - uint64 height = 1; - bytes currentBlockHash = 2; - bytes previousBlockHash = 3; -} -``` - -* `height` - 区块链中块的数量,包括创始区块 - -* `currentBlockHash` - 当前或最后区块的哈希 - -* `previousBlockHash` - 前一区块的哈希 - -区块链检索请求: -``` -GET host:port/chain -``` - -区块链检索响应: -``` -{ - "height": 174, - "currentBlockHash": "lIfbDax2NZMU3rG3cDR11OGicPLp1yebIkia33Zte9AnfqvffK6tsHRyKwsw0hZFZkCGIa9wHVkOGyFTcFxM5w==", - "previousBlockHash": "Vlz6Dv5OSy0OZpJvijrU1cmY2cNS5Ar3xX5DxAi/seaHHRPdssrljDeppDLzGx6ZVyayt8Ru6jO+E68IwMrXLQ==" -} -``` - -#### 6.2.1.3 链码API - -* **POST /chaincode** - -使用链码API来部署,调用和查询链码 -部署请求需要客户端提供`path`参数,执行文件系统中链码的目录。部署请求的响应要么是包含成功的链码部署确认消息要么是包含失败的原因的错误。 -它还含有所生成的链码的`name`域在消息中,这是在随后的调用和查询交易中使用的已部署链码的唯一标识。 - -要部署链码,需要提供ChaincodeSpec的payload,在[3.1.2.2](#3122-transaction-specification)节中定义。 - -部署请求: -``` -POST host:port/chaincode - -{ - "jsonrpc": "2.0", - "method": "deploy", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "path":"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" - }, - "ctorMsg": { - "function":"init", - "args":["a", "1000", "b", "2000"] - } - }, - "id": "1" -} -``` - -部署响应: -``` -{ - "jsonrpc": "2.0", - "result": { - "status": "OK", - "message": "52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" - }, - "id": 1 -} -``` - -当启用安全时,修改所需的payload包括传递的登录用户注册ID的`secureContext`元素如下: - -启用安全的部署请求: -``` -POST host:port/chaincode - -{ - "jsonrpc": "2.0", - "method": "deploy", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "path":"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" - }, - "ctorMsg": { - "function":"init", - "args":["a", "1000", "b", "2000"] - }, - "secureContext": "lukas" - }, - "id": "1" -} -``` - -该调用请求要求客户端提供一个`name`参数,这是之前从部署交易响应得到的。调用请求的响应要么是包含成功执行的确认消息,要么是包含失败的原因的错误。 - -要调用链码,需要提供ChaincodeSpec的payload,在[3.1.2.2](#3122-transaction-specification)节中定义 - -调用请求: -``` -POST host:port/chaincode - -{ - "jsonrpc": "2.0", - "method": "invoke", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" - }, - "ctorMsg": { - "function":"invoke", - "args":["a", "b", "100"] - } - }, - "id": "3" -} -``` - -调用响应: -``` -{ - "jsonrpc": "2.0", - "result": { - "status": "OK", - "message": "5a4540e5-902b-422d-a6ab-e70ab36a2e6d" - }, - "id": 3 -} -``` - -当启用安全时,修改所需的payload包括传递的登录用户注册ID的`secureContext`元素如下: - - -启用安全的调用请求: -``` -{ - "jsonrpc": "2.0", - "method": "invoke", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" - }, - "ctorMsg": { - "function":"invoke", - "args":["a", "b", "100"] - }, - "secureContext": "lukas" - }, - "id": "3" -} -``` - -查询请求需要在客户端提供一个`name`参数,这是之前在部署交易响应中得到了。查询请求的响应取决于链码的实现。响应要么是包含成功执行的确认消息,要么是包含失败的原因的错误。在成功执行的情况下,响应将包含链码请求的状态变量的值 - -要查询链码,需要提供ChaincodeSpec的payload,在[3.1.2.2](#3122-transaction-specification)节中定义。 - -查询请求: -``` -POST host:port/chaincode/ - -{ - "jsonrpc": "2.0", - "method": "query", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" - }, - "ctorMsg": { - "function":"query", - "args":["a"] - } - }, - "id": "5" -} -``` - -查询响应: -``` -{ - "jsonrpc": "2.0", - "result": { - "status": "OK", - "message": "-400" - }, - "id": 5 -} -``` - - -当启用安全时,修改所需的payload包括传递的登录用户注册ID的`secureContext`元素如下: - - - -启用安全的查询请求: -``` -{ - "jsonrpc": "2.0", - "method": "query", - "params": { - "type": "GOLANG", - "chaincodeID":{ - "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" - }, - "ctorMsg": { - "function":"query", - "args":["a"] - }, - "secureContext": "lukas" - }, - "id": "5" -} -``` - -#### 6.2.1.4 网络API - -使用网络API来获取组成区块链 fabric 的 peer 节点的网络信息 - -/network/peers 端点返回的目标 peer 节点的所有现有的网络连接的列表。该列表包括验证和非验证 peer。peer 的列表被返回类型`PeersMessage`是包含`PeerEndpoint`的数组,在第[3.1.1](#311-discovery-messages发现的消息)定义。 - - -``` -message PeersMessage { - repeated PeerEndpoint peers = 1; -} -``` - -网络请求: -``` -GET host:port/network/peers -``` - -网络响应: -``` -{ - "peers": [ - { - "ID": { - "name": "vp1" - }, - "address": "172.17.0.4:7051", - "type": 1, - "pkiID": "rUA+vX2jVCXev6JsXDNgNBMX03IV9mHRPWo6h6SI0KLMypBJLd+JoGGlqFgi+eq/" - }, - { - "ID": { - "name": "vp3" - }, - "address": "172.17.0.5:7051", - "type": 1, - "pkiID": "OBduaZJ72gmM+B9wp3aErQlofE0ulQfXfTHh377ruJjOpsUn0MyvsJELUTHpAbHI" - }, - { - "ID": { - "name": "vp2" - }, - "address": "172.17.0.6:7051", - "type": 1, - "pkiID": "GhtP0Y+o/XVmRNXGF6pcm9KLNTfCZp+XahTBqVRmaIumJZnBpom4ACayVbg4Q/Eb" - } - ] -} -``` - -#### 6.2.1.5 注册API (成员服务) - -* **POST /registrar** -* **GET /registrar/{enrollmentID}** -* **DELETE /registrar/{enrollmentID}** -* **GET /registrar/{enrollmentID}/ecert** -* **GET /registrar/{enrollmentID}/tcert** - -使用注册API来管理的证书颁发机构(CA)的最终用户注册。这些API端点用于注册与CA用户,确定指定用户是否已注册,并从本地存储中删除任何目标用户的登录令牌,防止他们执行任何进一步的交易。注册API也用于从系统中检索用户注册和交易证书。 - -`/registrar`端点使用与CA注册用户所需的秘密payload定义如下。注册请求的响应可以是一个成功的注册的确认或包含失败的原因的错误。 - -``` -message Secret { - string enrollId = 1; - string enrollSecret = 2; -} -``` - -* `enrollId` - 在证书颁发机构的注册ID -* `enrollSecret` - 在证书颁发机构的密码 - -注册请求: -``` -POST host:port/registrar - -{ - "enrollId": "lukas", - "enrollSecret": "NPKYL39uKbkj" -} -``` - -注册响应: -``` -{ - "OK": "Login successful for user 'lukas'." -} -``` - -`GET /registrar/{enrollmentID}`端点用于确认一个给定的用户是否与CA注册如果是,确认将被反悔。否则,将导致授权错误。 - -注册验证请求: -``` -GET host:port/registrar/jim -``` - -注册验证返回: -``` -{ - "OK": "User jim is already logged in." -} -``` - -注册验证请求: -``` -GET host:port/registrar/alex -``` - -注册验证返回: -``` -{ - "Error": "User alex must log in." -} -``` - -`DELETE /registrar/{enrollmentID}` 端点用于删除一个目标用户的登录令牌。如果登录令牌成功删除,确认将被反悔。否则,将导致授权错误。此端点不需要payload。 - -删除注册请求: -``` -DELETE host:port/registrar/lukas -``` - -删除注册返回: -``` -{ - "OK": "Deleted login token and directory for user lukas." -} -``` - -`GET /registrar/{enrollmentID}/ecert` -端点用于检索从本地存储给定用户的登记证书。如果目标用户已与CA注册,响应将包括注册证书的URL-encoded版本。如果目标用户尚未注册,将返回一个错误。如果客户希望使用检索后返回的注册证书,请记住,它必须是URL-decoded。 - -注册证书检索请求: -``` -GET host:port/registrar/jim/ecert -``` - -注册证书检索响应: -``` -{ - "OK": "-----BEGIN+CERTIFICATE-----%0AMIIBzTCCAVSgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwNPQkMwHhcNMTYwMTIxMDYzNjEwWhcNMTYwNDIw%0AMDYzNjEwWjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNP%0AQkMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARSLgjGD0omuJKYrJF5ClyYb3sGEGTU%0AH1mombSAOJ6GAOKEULt4L919sbSSChs0AEvTX7UDf4KNaKTrKrqo4khCoboMg1VS%0AXVTTPrJ%2BOxSJTXFZCohVgbhWh6ZZX2tfb7%2BjUDBOMA4GA1UdDwEB%2FwQEAwIHgDAM%0ABgNVHRMBAf8EAjAAMA0GA1UdDgQGBAQBAgMEMA8GA1UdIwQIMAaABAECAwQwDgYG%0AUQMEBQYHAQH%2FBAE0MAoGCCqGSM49BAMDA2cAMGQCMGz2RR0NsJOhxbo0CeVts2C5%0A%2BsAkKQ7v1Llbg78A1pyC5uBmoBvSnv5Dd0w2yOmj7QIwY%2Bn5pkLiwisxWurkHfiD%0AxizmN6vWQ8uhTd3PTdJiEEckjHKiq9pwD%2FGMt%2BWjP7zF%0A-----END+CERTIFICATE-----%0A" -} -``` - -`/registrar/{enrollmentID}/tcert`端点检索已与证书机关登记给定用户的交易证书。如果用户已注册,确认消息将包含URL-encoded交易证书的列表被返回。否则,将会导致一个错误。交易证书的所需数量由可选的'count'查询参数指定。返回交易证书的默认数量为1;500是可以与单个请求中检索证书的最大数量。如果客户端希望使用取回后的交易证书,请记住,他们必须是URL-decoded。 - -交易证书检索请求: -``` -GET host:port/registrar/jim/tcert -``` - -交易证书检索响应: -``` -{ - "OK": [ - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQfwJORRED9RAsmSl%2FEowq1STBb%0A%2FoFteymZ96RUr%2BsKmF9PNrrUNvFZFhvukxZZjqhEcGiQqFyRf%2FBnVN%2BbtRzMo38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwSRWQFmErr0SmQO9AFP4GJYzQ%0APQMmcsCjKiJf%2Bw1df%2FLnXunCsCUlf%2FalIUaeSrT7MAoGCCqGSM49BAMDA0gAMEUC%0AIQC%2FnE71FBJd0hwNTLXWmlCJff4Yi0J%2BnDi%2BYnujp%2Fn9nQIgYWg0m0QFzddyJ0%2FF%0AKzIZEJlKgZTt8ZTlGg3BBrgl7qY%3D%0A-----END+CERTIFICATE-----%0A" - ] -} -``` - -交易证书检索请求: -``` -GET host:port/registrar/jim/tcert?count=5 -``` - -交易证书检索响应: -``` -{ - "OK": [ - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", - "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A" - ] -} -``` - -#### 6.2.1.6 交易API - -* **GET /transactions/{UUID}** - -使用交易API来从区块链中检索匹配UUID的单个交易。返回的交易消息在[3.1.2.1](#3121-transaction-data-structure)小节定义 - -交易检索请求: -``` -GET host:port/transactions/f5978e82-6d8c-47d1-adec-f18b794f570e -``` - -交易检索响应: -``` -{ - "type": 3, - "chaincodeID": "EgRteWNj", - "payload": "Ch4IARIGEgRteWNjGhIKBmludm9rZRIBYRIBYhICMTA=", - "uuid": "f5978e82-6d8c-47d1-adec-f18b794f570e", - "timestamp": { - "seconds": 1453758316, - "nanos": 206716775 - }, - "cert": "MIIB/zCCAYWgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMTI1MjE0MTE3WhcNMTYwNDI0MjE0MTE3WjArMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQ4wDAYDVQQDEwVsdWthczB2MBAGByqGSM49AgEGBSuBBAAiA2IABC/BBkt8izf6Ew8UDd62EdWFikJhyCPY5VO9Wxq9JVzt3D6nubx2jO5JdfWt49q8V1Aythia50MZEDpmKhtM6z7LHOU1RxuxdjcYDOvkNJo6pX144U4N1J8/D3A+97qZpKN/MH0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDA9BgYqAwQFBgcBAf8EMABNbPHZ0e/2EToi0H8mkouuUDwurgBYuUB+vZfeMewBre3wXG0irzMtfwHlfECRDDAKBggqhkjOPQQDAwNoADBlAjAoote5zYFv91lHzpbEwTfJL/+r+CG7oMVFUFuoSlvBSCObK2bDIbNkW4VQ+ZC9GTsCMQC5GCgy2oZdHw/x7XYzG2BiqmRkLRTiCS7vYCVJXLivU65P984HopxW0cEqeFM9co0=", - "signature": "MGUCMCIJaCT3YRsjXt4TzwfmD9hg9pxYnV13kWgf7e1hAW5Nar//05kFtpVlq83X+YtcmAIxAK0IQlCgS6nqQzZEGCLd9r7cg1AkQOT/RgoWB8zcaVjh3bCmgYHsoPAPgMsi3TJktg==" -} -``` - -## 6.3 CLI - -CLI包括可用的API的一个子集,使开发人员能够快速测试和调试链码或查询交易状态。CLI由Golang实现和可在多个操作系统上操作。当前可用的CLI命令归纳在下面的部分: - -### 6.3.1 CLI命令 - -To see what CLI commands are currently available in the implementation, execute the following: - -要查看当前可用的CLI命令,执行如下命令 - - cd $GOPATH/src/github.com/hyperledger/fabric/peer - ./peer - -你可以获得和下面类似的响应: - -``` - Usage: - peer [command] - - Available Commands: - peer Run the peer. - status Status of the peer. - stop Stop the peer. - login Login user on CLI. - vm VM functionality on the fabric. - chaincode chaincode specific commands. - help Help about any command - - Flags: - -h, --help[=false]: help - - - Use "peer [command] --help" for more information about a command. -``` - -Some of the available command line arguments for the `peer` command are listed below: - -* `-c` - 构造函数: 用来为部署触发初始化链码状态的函数 - -* `-l` - 语言: 指定链码的实现语言,目前只支持Golang - -* `-n` - 名字: 部署交易返回的链码的标识。在后续的调用和查询交易中必须使用 - -* `-p` - 路径: 链码在本地文件系统中的标识。在部署交易时必须提供。 - -* `-u` - 用户名: 调用交易的登入的用户的注册ID - -上述所有命令并非完全在当前版本中实现。如下所述全面支持的命令是有助于链码的开发和调试的。 - -所有 peer 节点的设置都被列在`core.yaml`这个`peer`处理的配置文件中,可能通过命令行的环境变量而被修改。如,设置`peer.id`或 `peer.ddressAutoDetect`,只需要传递`CORE_PEER_ID=vp1`和`CORE_PEER_ADDRESSAUTODETECT=true`给命令行。 - -#### 6.3.1.1 peer - -`peer`CLI命令在开发和生产环境中都会执行 peer 处理。开发模式会在本地运行单个 peer 节点和本地的链码部署。这使得在链码开修改和调试代码,不需要启动一个完整的网络。在开发模式启动 peer 的一个例子: - -``` -./peer peer --peer-chaincodedev -``` - -在生产环境中启动peer进程,像下面一样修改上面的命令: - -``` -./peer peer -``` - -#### 6.3.1.2 登录 - -登录的CLI命令会登入一个已经在CA注册的用户。要通过CLI登录,发出以下命令,其中`username`是注册用户的注册ID。 -``` -./peer login -``` - -下面的例子演示了用户`jim`登录过程。 -``` -./peer login jim -``` - -该命令会提示输入密码,密码必须为此用户使用证书颁发机构注册登记的密码相匹配。如果输入的密码不正确的密码匹配,将导致一个错误。 - - -``` -22:21:31.246 [main] login -> INFO 001 CLI client login... -22:21:31.247 [main] login -> INFO 002 Local data store for client loginToken: /var/hyperledger/production/client/ -Enter password for user 'jim': ************ -22:21:40.183 [main] login -> INFO 003 Logging in user 'jim' on CLI interface... -22:21:40.623 [main] login -> INFO 004 Storing login token for user 'jim'. -22:21:40.624 [main] login -> INFO 005 Login successful for user 'jim'. -``` - -您也可以与`-p`参数来提供用户的密码。下面是一个例子。 - -``` -./peer login jim -p 123456 -``` - -#### 6.3.1.3 链码部署 - -`deploy`CLI命令为链码和接下来的部署包到验证 peer 创建 docker 镜像。如下面的例子。 - -``` -./peer chaincode deploy -p github.com/hyperledger/fabric/example/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' -``` - -启用安全性时,命令必须修改来通过`-u`参数传递用户登录的注册ID。下面是一个例子 - -``` -./peer chaincode deploy -u jim -p github.com/hyperledger/fabric/example/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' -``` - -#### 6.3.1.4 链码调用 - -`invoke`CLI命令执行目标来代码中的指定函数。如下: - -``` -./peer chaincode invoke -n -c '{"Function": "invoke", "Args": ["a", "b", "10"]}' -``` - -启用安全性时,命令必须修改来通过`-u`参数传递用户登录的注册ID。下面是一个例子 - -``` -./peer chaincode invoke -u jim -n -c '{"Function": "invoke", "Args": ["a", "b", "10"]}' -``` - -#### 6.3.1.5 链码查询 - -`query`CLI命令在目标链码上触发指定的查询。返回的响应取决于链码实现。下面是一个例子。 - -``` -./peer chaincode query -l golang -n -c '{"Function": "query", "Args": ["a"]}' -``` - -启用安全性时,命令必须修改来通过`-u`参数传递用户登录的注册ID。下面是一个例子 - -``` -./peer chaincode query -u jim -l golang -n -c '{"Function": "query", "Args": ["a"]}' -``` - - -## 7. 应用模型 - -### 7.1 应用的组成 - --- - - - -
-一个遵循MVC-B架构的应用– Model, View, Control, BlockChain. -

- -

    -
  • VIEW LOGIC – 与控制逻辑集成的移动或WEB 用户界面。
  • -
  • CONTROL LOGIC – 协调用户界面、数据模型和交易与链码的API
  • -
  • DATA MODEL – 应用数据模型– 管理包括文档和大文件这样的非链(off-chain)数据
  • -
  • BLOCKCHAIN LOGIC – 区块链逻辑是控制逻辑和数据模型在区块链领域的扩展,链码(chaincode)加强了控制逻辑,区块链上的交易加强了数据模型。
  • -
-

- -例如,使用 Node.js 的一个 Bluemix PaaS 的应用程序可能有一个 Web 前端用户界面或与 Cloudant 数据服务后端模型中的原生移动应用。控制逻辑可以被 1 或多个链码交互以处理对区块链交易。 - -

- -### 7.2 应用样例 - - -## 8. 未来发展方向 -### 8.1 企业集成 -### 8.2 性能与可扩展性 -### 8.3 附加的共识插件 -### 8.4 附加的语言 - - -## 9. References -- [1] Miguel Castro, Barbara Liskov: Practical Byzantine fault tolerance and proactive recovery. ACM Trans. Comput. Syst. 20(4): 398-461 (2002) - -- [2] Christian Cachin, Rachid Guerraoui, Luís E. T. Rodrigues: Introduction to Reliable and Secure Distributed Programming (2. ed.). Springer 2011, ISBN 978-3-642-15259-7, pp. I-XIX, 1-367 - -- [3] Tushar Deepak Chandra, Vassos Hadzilacos, Sam Toueg: The Weakest Failure Detector for Solving Consensus. J. ACM 43(4): 685-722 (1996) - -- [4] Cynthia Dwork, Nancy A. Lynch, Larry J. Stockmeyer: Consensus in the presence of partial synchrony. J. ACM 35(2): 288-323 (1988) - -- [5] Manos Kapritsos, Yang Wang, Vivien Quéma, Allen Clement, Lorenzo Alvisi, Mike Dahlin: All about Eve: Execute-Verify Replication for Multi-Core Servers. OSDI 2012: 237-250 - -- [6] Pierre-Louis Aublin, Rachid Guerraoui, Nikola Knezevic, Vivien Quéma, Marko Vukolic: The Next 700 BFT Protocols. ACM Trans. Comput. Syst. 32(4): 12:1-12:45 (2015) - -- [7] Christian Cachin, Simon Schubert, Marko Vukolić: [Non-determinism in Byzantine Fault-Tolerant Replication](http://arxiv.org/abs/1603.07351) - diff --git a/docs/pythonsdk.md b/docs/pythonsdk.md deleted file mode 100644 index dda1cfda740..00000000000 --- a/docs/pythonsdk.md +++ /dev/null @@ -1,12 +0,0 @@ -# Python SDK - -[WIP] -...coming soon - -In the meantime, refer to the [Hyperledger Fabric SDK design doc](https://docs.google.com/document/d/1R5RtIBMW9fZpli37E5Li5_Q9ve3BnQ4q3gWmGZj6Sv4/edit#heading=h.z6ne0og04bp5) -for more details on the APIs and specifications. - -OR - -Refer to the [fabric-sdk-py](https://github.com/hyperledger/fabric-sdk-py) -repository in the Hyperledger community. diff --git a/docs/quality.md b/docs/quality.md deleted file mode 100644 index c5eab2498d4..00000000000 --- a/docs/quality.md +++ /dev/null @@ -1,4 +0,0 @@ -# Quality - -[WIP] -...coming soon diff --git a/docs/questions.md b/docs/questions.md deleted file mode 100644 index ef84cda1cfe..00000000000 --- a/docs/questions.md +++ /dev/null @@ -1,10 +0,0 @@ -# Still Have Questions? -We try to maintain a comprehensive set of documentation for various -audiences. However, we realize that often there are questions that remain -unanswered. For any technical questions relating to the Hyperledger Fabric -project not answered in this documentation, please use -[StackOverflow](http://stackoverflow.com/questions/tagged/hyperledger). If you -need help finding things, please don't hesitate to send a note to the -[mailing list](http://lists.hyperledger.org/mailman/listinfo/hyperledger-fabric), -or ask on [RocketChat]((https://chat.hyperledger.org/)) (an alternative to -Slack). diff --git a/docs/readwrite.md b/docs/readwrite.md deleted file mode 100644 index c634bbd05e5..00000000000 --- a/docs/readwrite.md +++ /dev/null @@ -1,127 +0,0 @@ -### Read-Write set semantics - -This documents discusses the details of the current implementation about the -semantics of read-write sets. - -##### Transaction simulation and read-write set -During simulation of a transaction at an `endorser`, a read-write set is prepared -for the transaction. The `read set` contains a list of unique keys and their -committed versions that the transaction reads during simulation. The `write set` -contains a list of unique keys (though there can be overlap with the keys present -in the read set) and their new values that the transaction writes. A delete -marker is set (in the place of new value) for the key if the update performed -by the transaction is to delete the key. - -Further, if the transaction writes a value multiple times for a key, only the -last written value is retained. Also, if a transaction reads a value for a key, -the value in the committed state is returned even if the transaction has updated -the value for the key before issuing the read. In another words, Read-your-writes -semantics are not supported. - -As noted earlier, the versions of the keys are recorded only in the read set; -the write set just contains the list of unique keys and their latest values set -by the transaction. - -There could be various schemes for implementing versions. The minimal requirement -for a versioning scheme is to produce non-repeating identifiers for a given key. -For instance, using monotonically increasing numbers for versions can be one such scheme. -In the current implementation, we use a blockchain height based versioning scheme -in which the height of the committing transaction is used as the latest version for -all the keys modified by the transaction. In this scheme, the height of a transaction -is represented by a tuple (txNumber is the height of the -transaction within the block). This scheme has many advantages over the incremental -number scheme - primarily, it enables other components such as statedb, transaction -simulation and validation for making efficient design choices. - -Following is an illustration of an example read-write set prepared by simulation -of a hypothetical transaction. For the sake of simplicity, in the illustrations, -we use the incremental numbers for representing the versions. - -``` - - - - - - - - - - -``` - -Additionally, if the transaction performs a range query during simulation, the -range query as well as its results will be added to the read-write set as `query-info`. - -##### Transaction validation and updating world state using read-write set -A `committer` uses the read set portion of the read-write set for checking the -validity of a transaction and the write set portion of the read-write set for -updating the versions and the values of the affected keys. - -In the validation phase, a transaction is considered `valid` if the version of -each key present in the read set of the transaction matches the version for the -same key in the world state - assuming all the preceding `valid` transactions -(including the preceding transactions in the same block) are committed -(*committed-state*). An additional validation is performed if the read-write set -also contains one or more query-info. - -This additional validation should ensure that no key has been -inserted/deleted/updated in the super range (i.e., union of the ranges) of the -results captured in the query-info(s). In other words, if we re-execute any of -the range queries (that the transaction performed during simulation) during -validation on the committed-state, it should yield the same results that were -observed by the transaction at the time of simulation. This check ensures that -if a transaction observes phantom items during commit, the transaction should be -marked as invalid. Note that the this phantom protection is limited to range -queries (i.e., `GetStateByRange` function in the chaincode) and not yet -implemented for other queries (i.e., `GetQueryResult` function in the chaincode). -Other queries are at risk of phantoms, and should therefore only be used in -read-only transactions that are not submitted to ordering, unless the application -can guarantee the stability of the result set between simulation and validation/commit time. - -If a transaction passes the validity check, the committer uses the write set for -updating the world state. In the update phase, for each key present in the write -set, the value in the world state for the same key is set to the value as specified -in the write set. Further, the version of the key in the world state is changed -to reflect the latest version. - -##### Example simulation and validation -This section helps with understanding the semantics through an example scenario. -For the purpose of this example, the presence of a key, `k`, in the world state is -represented by a tuple `(k,ver,val)` where `ver` is the latest version of the -key `k` having `val` as its value. - -Now, consider a set of five transactions `T1, T2, T3, T4, and T5`, all simulated -on the same snapshot of the world state. The following snippet shows the snapshot of -the world state against which the transactions are simulated and the sequence of -read and write activities performed by each of these transactions. - -``` -World state: (k1,1,v1), (k2,1,v2), (k3,1,v3), (k4,1,v4), (k5,1,v5) -T1 -> Write(k1, v1'), Write(k2, v2') -T2 -> Read(k1), Write(k3, v3') -T3 -> Write(k2, v2'') -T4 -> Write(k2, v2'''), read(k2) -T5 -> Write(k6, v6'), read(k5) -``` -Now, assume that these transactions are ordered in the sequence of T1,..,T5 -(could be contained in a single block or different blocks) - -1. `T1` passes validation because it does not perform any read. Further, the -tuple of keys `k1` and `k2` in the world state are updated to `(k1,2,v1'), (k2,2,v2')` - -2. `T2` fails validation because it reads a key, `k1`, which was modified by a preceding transaction - `T1` - -3. `T3` passes the validation because it does not perform a read. Further the -tuple of the key, `k2`, in the world state is updated to `(k2,3,v2'')` - -4. `T4` fails the validation because it reads a key, `k2`, which was modified by a preceding transaction `T1` - -5. `T5` passes validation because it reads a key, `k5,` which was not modified -by any of the preceding transactions - -#### Transactions with multiple read-write sets -Not yet supported (https://jira.hyperledger.org/browse/FAB-445) diff --git a/docs/recipes.md b/docs/recipes.md deleted file mode 100644 index 3be28ab6fc8..00000000000 --- a/docs/recipes.md +++ /dev/null @@ -1,7 +0,0 @@ -# Recipe Book - -[WIP] -...coming soon - -Intended to contain best practices and configurations for MSP, networks, ordering -service, channels, ACL, stress, policies, chaincode development, functions, etc... diff --git a/docs/releases.md b/docs/releases.md deleted file mode 100644 index 51ba90eadfc..00000000000 --- a/docs/releases.md +++ /dev/null @@ -1,62 +0,0 @@ - - -[v0.6-preview](https://github.com/hyperledger/fabric/tree/v0.6) September 16, 2016 - -A developer preview release of the Hyperledger Fabric intended -to exercise the release logistics and stabilize a set of capabilities for -developers to try out. This will be the last release under the original -architecture. All subsequent releases will deliver on the -[v1.0 architecture](TODO). - -Key enhancements: - -* 8de58ed - NodeSDK doc changes -- FAB-146 -* 62d866d - Add flow control to SYNC_STATE_SNAPSHOT -* 4d97069 - Adding TLS changes to SDK -* e9d3ac2 - Node-SDK: add support for fabric events(block, chaincode, transactional) -* 7ed9533 - Allow deploying Java chaincode from remote git repositories -* 4bf9b93 - Move Docker-Compose files into their own folder -* ce9fcdc - Print ChaincodeName when deploy with CLI -* 4fa1360 - Upgrade go protobuf from 3-beta to 3 -* 4b13232 - Table implementation in java shim with example -* df741bc - Add support for dynamically registering a user with attributes -* 4203ea8 - Check for duplicates when adding peers to the chain -* 518f3c9 - Update docker openjdk image -* 47053cd - Add GetTxID function to Stub interface (FAB-306) -* ac182fa - Remove deprecated devops REST API -* ad4645d - Support hyperledger fabric build on ppc64le platform -* 21a4a8a - SDK now properly adding a peer with an invalid URL -* 1d8114f - Fix setting of watermark on restore from crash -* a98c59a - Upgrade go protobuff from 3-beta to 3 -* 937039c - DEVENV: Provide strong feedback when provisioning fails -* d74b1c5 - Make pbft broadcast timeout configurable -* 97ed71f - Java shim/chaincode project reorg, separate java docker env -* a76dd3d - Start container with HostConfig was deprecated since v1.10 and removed since v1.12 -* 8b63a26 - Add ability to unregister for events -* 3f5b2fa - Add automatic peer command detection -* 6daedfd - Re-enable sending of chaincode events -* b39c93a - Update Cobra and pflag vendor libraries -* dad7a9d - Reassign port numbers to 7050-7060 range - -[v0.5-developer-preview](https://github.com/hyperledger-archives/fabric/tree/v0.5-developer-preview) -June 17, 2016 - -A developer preview release of the Hyperledger Fabric intended -to exercise the release logistics and stabilize a set of capabilities for -developers to try out. - -Key features: - -Permissioned blockchain with immediate finality -Chaincode (aka smart contract) execution environments -Docker container (user chaincode) -In-process with peer (system chaincode) -Pluggable consensus with PBFT, NOOPS (development mode), SIEVE (prototype) -Event framework supports pre-defined and custom events -Client SDK (Node.js), basic REST APIs and CLIs -Known Key Bugs and work in progress - -* 1895 - Client SDK interfaces may crash if wrong parameter specified -* 1901 - Slow response after a few hours of stress testing -* 1911 - Missing peer event listener on the client SDK -* 889 - The attributes in the TCert are not encrypted. This work is still on-going diff --git a/docs/requirements.txt b/docs/requirements.txt index da829ff4f2d..9d3e4e1d8e6 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,14 @@ python-markdown-math==0.2 + +alabaster==0.7.8 +Babel==2.3.4 +docutils==0.12 +imagesize==0.7.1 +Jinja2==2.8 +MarkupSafe==0.23 +Pygments==2.1.3 +pytz==2016.4 +six==1.10.0 +snowballstemmer==1.2.1 +Sphinx==1.4.4 +sphinx-rtd-theme==0.1.9 diff --git a/docs/sampleapp.md b/docs/sampleapp.md deleted file mode 100644 index 57a4ae49184..00000000000 --- a/docs/sampleapp.md +++ /dev/null @@ -1,6 +0,0 @@ -# Sample Application - -[WIP] -...coming soon - -In the meantime, refer to the [Asset transfer through SDK](asset_sdk.md) topic. diff --git a/docs/security_model.md b/docs/security_model.md deleted file mode 100644 index bbe21ce9688..00000000000 --- a/docs/security_model.md +++ /dev/null @@ -1,13 +0,0 @@ -# Security Model - -[WIP] - -Hyperledger Fabric allows for different organizations and participants in a common network -to utilize their own certificate authority, and as a byproduct, implement varying -cryptographic algorithms for signing/verifying/identity attestation. This is done through an MSP -process running on both the ordering service and channel levels. - -Membership service provider (MSP): A set of cryptographic mechanisms and protocols -for issuing and validating certificates and identities throughout the blockchain network. -Identities issued in the scope of a membership service provider can be evaluated -within that membership service provider’s rules validation policies. diff --git a/docs/smartcontract.md b/docs/smartcontract.md deleted file mode 100644 index 0b20938007a..00000000000 --- a/docs/smartcontract.md +++ /dev/null @@ -1,12 +0,0 @@ -# Chaincode - -[WIP] - -The widely-used term, smart contract, is referred to as "chaincode" in Hyperledger Fabric. - -Self-executing logic that encodes the rules for specific types of -network transactions. Chaincode (currently written in Go or Java) is installed and -instantiated onto a channel's peers by an appropriately authorized member. End users then -invoke chaincode through a client-side application that interfaces with a -network peer. Chaincode runs network transactions, which if validated, are -appended to the shared ledger and modify world state. diff --git a/docs/source/API/AttributesUsage.rst b/docs/source/API/AttributesUsage.rst new file mode 100644 index 00000000000..d773d4694f6 --- /dev/null +++ b/docs/source/API/AttributesUsage.rst @@ -0,0 +1,287 @@ +Attributes usage +================ + +Overview +-------- + +The Attributes feature allows chaincode to make use of extended data in +a transaction certificate. These attributes are certified by the +Attributes Certificate Authority (ACA) so the chaincode can trust in the +authenticity of the attributes' values. + +To view complete documentation about attributes design please read +`'Attributes support' <../tech/attributes.md>`__. + +Use case: Authorizable counter +------------------------------ + +A common use case for the Attributes feature is Attributes Based Access +Control (ABAC) which allows specific permissions to be granted to a +chaincode invoker based on attribute values carried in the invoker's +certificate. + +`'Authorizable +counter' <../../examples/chaincode/go/authorizable_counter/authorizable_counter.go>`__ +is a simple example of ABAC, in this case only invokers whose "position" +attribute has the value 'Software Engineer' will be able to increment +the counter. On the other hand any invoker will be able to read the +counter value. + +In order to implement this example we used +`'VerifyAttribyte' `__ +function to check the attribute value from the chaincode code. + +:: + + isOk, _ := stub.VerifyAttribute("position", []byte("Software Engineer")) // Here the ABAC API is called to verify the attribute, just if the value is verified the counter will be incremented. + if isOk { + // Increment counter code + } + +The same behavior can be achieved by making use of `'Attribute +support' `__ +API, in this case an attribute handler must be instantiated. + +:: + + attributesHandler, _ := attr.NewAttributesHandlerImpl(stub) + isOk, _ := attributesHandler.VerifyAttribute("position", []byte("Software Engineer")) + if isOk { + // Increment counter code + } + +If attributes are accessed more than once, using ``attributeHandler`` is +more efficient since the handler makes use of a cache to store values +and keys. + +In order to get the attribute value, in place of just verifying it, the +following code can be used: + +:: + + attributesHandler, _ := attr.NewAttributesHandlerImpl(stub) + value, _ := attributesHandler.GetValue("position") + +Enabling attributes +------------------- + +To make use of this feature the following property has to be set in the +membersrvc.yaml file: + +- aca.enabled = true + +Another way is using environment variables: + +:: + + MEMBERSRVC_CA_ACA_ENABLED=true ./membersrvc + +Enabling attributes encryption\* +-------------------------------- + +In order to make use of attributes encryption the following property has +to be set in the membersrvc.yaml file: + +- tca.attribute-encryption.enabled = true + +Or using environment variables: + +:: + + MEMBERSRVC_CA_ACA_ENABLED=true MEMBERSRVC_CA_TCA_ATTRIBUTE-ENCRYPTION_ENABLED=true ./membersrvc + +Deploy API making use of attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CLI +^^^ + +:: + + $ ./peer chaincode deploy --help + Deploy the specified chaincode to the network. + + Usage: + peer chaincode deploy [flags] + + Global Flags: + -a, --attributes="[]": User attributes for the chaincode in JSON format + -c, --ctor="{}": Constructor message for the chaincode in JSON format + -l, --lang="golang": Language the chaincode is written in + --logging-level="": Default logging level and overrides, see core.yaml for full syntax + -n, --name="": Name of the chaincode returned by the deploy transaction + -p, --path="": Path to chaincode + --test.coverprofile="coverage.cov": Done + -t, --tid="": Name of a custom ID generation algorithm (hashing and decoding) e.g. sha256base64 + -u, --username="": Username for chaincode operations when security is enabled + -v, --version[=false]: Display current version of fabric peer server + +To deploy a chaincode with attributes "company" and "position" it should +be written in the following way: + +:: + + ./peer chaincode deploy -u userName -n mycc -c '{"Function":"init", "Args": []}' -a '["position", "company"]' + +Or: + +:: + + ./peer chaincode deploy -u userName -n mycc -c '{"Args": ["init"]}' -a '["position", "company"]' + +REST +^^^^ + +:: + + POST host:port/chaincode + + { + "jsonrpc": "2.0", + "method": "deploy", + "params": { + "type": 1, + "chaincodeID":{ + "name": "mycc" + }, + "input": { + "function":"init", + "args":[] + } + "attributes": ["position", "company"] + }, + "id": 1 + } + +Invoke API making use of attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CLI +^^^ + +:: + + $ ./peer chaincode invoke --help + Invoke the specified chaincode. + + Usage: + peer chaincode invoke [flags] + + Global Flags: + -a, --attributes="[]": User attributes for the chaincode in JSON format + -c, --ctor="{}": Constructor message for the chaincode in JSON format + -l, --lang="golang": Language the chaincode is written in + --logging-level="": Default logging level and overrides, see core.yaml for full syntax + -n, --name="": Name of the chaincode returned by the deploy transaction + -p, --path="": Path to chaincode + --test.coverprofile="coverage.cov": Done + -t, --tid="": Name of a custom ID generation algorithm (hashing and decoding) e.g. sha256base64 + -u, --username="": Username for chaincode operations when security is enabled + -v, --version[=false]: Display current version of fabric peer server + +To invoke "autorizable counter" with attributes "company" and "position" +it should be written as follows: + +:: + + ./peer chaincode invoke -u userName -n mycc -c '{"Function":"increment", "Args": []}' -a '["position", "company"]' + +Or: + +:: + + ./peer chaincode invoke -u userName -n mycc -c '{"Args": ["increment"]}' -a '["position", "company"]' + +REST +^^^^ + +:: + + POST host:port/chaincode + + { + "jsonrpc": "2.0", + "method": "invoke", + "params": { + "type": 1, + "chaincodeID":{ + "name": "mycc" + }, + "ctorMsg": { + "function":"increment", + "args":[] + } + "attributes": ["position", "company"] + }, + "id": 1 + } + +Query API making use of attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CLI +^^^ + +:: + + $ ./peer chaincode query --help + Query using the specified chaincode. + + Usage: + peer chaincode query [flags] + + Flags: + -x, --hex[=false]: If true, output the query value byte array in hexadecimal. Incompatible with --raw + -r, --raw[=false]: If true, output the query value as raw bytes, otherwise format as a printable string + + + Global Flags: + -a, --attributes="[]": User attributes for the chaincode in JSON format + -c, --ctor="{}": Constructor message for the chaincode in JSON format + -l, --lang="golang": Language the chaincode is written in + --logging-level="": Default logging level and overrides, see core.yaml for full syntax + -n, --name="": Name of the chaincode returned by the deploy transaction + -p, --path="": Path to chaincode + --test.coverprofile="coverage.cov": Done + -t, --tid="": Name of a custom ID generation algorithm (hashing and decoding) e.g. sha256base64 + -u, --username="": Username for chaincode operations when security is enabled + -v, --version[=false]: Display current version of fabric peer server + +To query "autorizable counter" with attributes "company" and "position" +it should be written in this way: + +:: + + ./peer chaincode query -u userName -n mycc -c '{"Function":"read", "Args": []}' -a '["position", "company"]' + +Or: + +:: + + ./peer chaincode query -u userName -n mycc -c '{"Args": ["read"]}' -a '["position", "company"]' + +REST +^^^^ + +:: + + POST host:port/chaincode + + { + "jsonrpc": "2.0", + "method": "query", + "params": { + "type": 1, + "chaincodeID":{ + "name": "mycc" + }, + "ctorMsg": { + "function":"read", + "args":[] + } + "attributes": ["position", "company"] + }, + "id": 1 + } + +- Attributes encryption is not yet available. diff --git a/docs/source/API/CLI.rst b/docs/source/API/CLI.rst new file mode 100644 index 00000000000..4280e0531e1 --- /dev/null +++ b/docs/source/API/CLI.rst @@ -0,0 +1,84 @@ +Command-line Interface (CLI) +============================ + +To view the currently available CLI commands, execute the following: + +:: + + cd /opt/gopath/src/github.com/hyperledger/fabric + build/bin/peer + +You will see output similar to the example below (**NOTE:** rootcommand +below is hardcoded in +`main.go `__. +Currently, the build will create a *peer* executable file). + +:: + + Usage: + peer [flags] + peer [command] + + Available Commands: + version Print fabric peer version. + node node specific commands. + network network specific commands. + chaincode chaincode specific commands. + help Help about any command + + Flags: + -h, --help[=false]: help for peer + --logging-level="": Default logging level and overrides, see core.yaml for full syntax + --test.coverprofile="coverage.cov": Done + -v, --version[=false]: Show current version number of fabric peer server + + + Use "peer [command] --help" for more information about a command. + +The ``peer`` command supports several subcommands and flags, as shown +above. To facilitate its use in scripted applications, the ``peer`` +command always produces a non-zero return code in the event of command +failure. Upon success, many of the subcommands produce a result on +**stdout** as shown in the table below: + +Command \| **stdout** result in the event of success --- \| --- +``version`` \| String form of ``peer.version`` defined in +`core.yaml `__ +``node start`` \| N/A ``node status`` \| String form of +`StatusCode `__ +``node stop`` \| String form of +`StatusCode `__ +``network login`` \| N/A ``network list`` \| The list of network +connections to the peer node. ``chaincode deploy`` \| The chaincode +container name (hash) required for subsequent ``chaincode invoke`` and +``chaincode query`` commands ``chaincode invoke`` \| The transaction ID +(UUID) ``chaincode query`` \| By default, the query result is formatted +as a printable string. Command line options support writing this value +as raw bytes (-r, --raw), or formatted as the hexadecimal representation +of the raw bytes (-x, --hex). If the query response is empty then +nothing is output. + +Deploy a Chaincode +------------------ + +Deploy creates the docker image for the chaincode and subsequently +deploys the package to the validating peer. An example is below. + +:: + + peer chaincode deploy -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' + +Or: + +:: + + peer chaincode deploy -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args": ["init", "a","100", "b", "200"]}' + +The response to the chaincode deploy command will contain the chaincode +identifier (hash) which will be required on subsequent +``chaincode invoke`` and ``chaincode query`` commands in order to +uniquely identify the deployed chaincode. + +**Note:** If your GOPATH environment variable contains more than one +element, the chaincode must be found in the first one or deployment will +fail. diff --git a/docs/source/API/ChaincodeAPI.rst b/docs/source/API/ChaincodeAPI.rst new file mode 100644 index 00000000000..1b066c5a162 --- /dev/null +++ b/docs/source/API/ChaincodeAPI.rst @@ -0,0 +1,18 @@ +Chaincode APIs +============== + +When the ``Init``, ``Invoke`` or ``Query`` function of a chaincode is +called, the fabric passes the ``stub *shim.ChaincodeStub`` parameter. +This ``stub`` can be used to call APIs to access to the ledger services, +transaction context, or to invoke other chaincodes. + +The current APIs are defined in the `shim +package `__, +generated by ``godoc``. However, it includes functions from +`chaincode.pb.go `__ +such as ``func (*Column) XXX_OneofFuncs`` that are not intended as +public API. The best is to look at the function definitions in +`chaincode.go `__ +and `chaincode +samples `__ +for usage. diff --git a/docs/API/Samples/Sample_1.js b/docs/source/API/Samples/Sample_1.js similarity index 100% rename from docs/API/Samples/Sample_1.js rename to docs/source/API/Samples/Sample_1.js diff --git a/docs/API/Samples/Sample_1.zip b/docs/source/API/Samples/Sample_1.zip similarity index 100% rename from docs/API/Samples/Sample_1.zip rename to docs/source/API/Samples/Sample_1.zip diff --git a/docs/source/CONTRIBUTING.rst b/docs/source/CONTRIBUTING.rst new file mode 100644 index 00000000000..e183eaeeff0 --- /dev/null +++ b/docs/source/CONTRIBUTING.rst @@ -0,0 +1,244 @@ +Contributions Welcome! +====================== + +We welcome contributions to the Hyperledger Project in many forms, and +there's always plenty to do! + +First things first, please review the Hyperledger Project's `Code of +Conduct `__ +before participating. It is important that we keep things civil. + +Getting a Linux Foundation account +---------------------------------- + +In order to participate in the development of the Hyperledger Fabric +project, you will need a `Linux Foundation +account `__. You will need to use your LF ID to +access to all the Hyperledger community development tools, including +`Gerrit `__, +`Jira `__ and the +`Wiki `__ (for editing, only). + +Setting up your SSH key +~~~~~~~~~~~~~~~~~~~~~~~ + +For Gerrit, before you can submit any change set for review, you will +need to register your public SSH key. Login to +`Gerrit `__ with your +`LFID `__, and click on your name in the upper +right-hand corner of your browser window and then click 'Settings'. In +the left-hand margin, you should see a link for 'SSH Public Keys'. +Copy-n-paste your `public SSH +key `__ into +the window and press 'Add'. + +Getting help +------------ + +If you are looking for something to work on, or need some expert +assistance in debugging a problem or working out a fix to an issue, our +`community `__ is always eager to +help. We hang out on +`Chat `__, IRC +(#hyperledger on freenode.net) and the `mailing +lists `__. Most of us don't bite :grin: +and will be glad to help. The only silly question is the one you don't +ask. Questions are in fact a great way to help improve the project as +they highlight where our documentation could be clearer. + +Requirements and Use Cases +-------------------------- + +We have a `Requirements +WG `__ +that is documenting use cases and from those use cases deriving +requirements. If you are interested in contributing to this effort, +please feel free to join the discussion in +`chat `__. + +Reporting bugs +-------------- + +If you are a user and you find a bug, please submit an issue using +`JIRA `__. Please try to provide +sufficient information for someone else to reproduce the issue. One of +the project's maintainers should respond to your issue within 24 hours. +If not, please bump the issue with a comment and request that it be +reviewed. You can also post to the ``#fabric-maintainers`` channel in +`chat `__. + +Fixing issues and working stories +--------------------------------- + +Review the `issues +list `__ and find +something that interests you. You could also check the +`"help-wanted" `__ +list. It is wise to start with something relatively straight forward and +achievable, and that no one is already assigned. If no one is assigned, +then assign the issue to yourself. Please be considerate and rescind the +assignment if you cannot finish in a reasonable time, or add a comment +saying that you are still actively working the issue if you need a +little more time. + +Working with a local clone and Gerrit +------------------------------------- + +We are using +`Gerrit `__ to +manage code contributions. If you are unfamiliar, please review this +`document `__ before proceeding. + +After you have familiarized yourself with ``Gerrit``, and maybe played +around with the ``lf-sandbox`` +`project `__, +you should be ready to set up your local development +`environment `__. + +Next, try `building the project `__ in your local +development environment to ensure that everything is set up correctly. + +`Logging control `__ describes how to tweak +the logging levels of various components within the Fabric. Finally, +every source file needs to include a `license +header `__: modified to include a copyright +statement for the principle author(s). + +What makes a good change request? +--------------------------------- + +- One change at a time. Not five, not three, not ten. One and only one. + Why? Because it limits the blast area of the change. If we have a + regression, it is much easier to identify the culprit commit than if + we have some composite change that impacts more of the code. + +- Include a link to the JIRA story for the change. Why? Because a) we + want to track our velocity to better judge what we think we can + deliver and when and b) because we can justify the change more + effectively. In many cases, there should be some discussion around a + proposed change and we want to link back to that from the change + itself. + +- Include unit and integration tests (or changes to existing tests) + with every change. This does not mean just happy path testing, + either. It also means negative testing of any defensive code that it + correctly catches input errors. When you write code, you are + responsible to test it and provide the tests that demonstrate that + your change does what it claims. Why? Because without this we have no + clue whether our current code base actually works. + +- Unit tests should have NO external dependencies. You should be able + to run unit tests in place with ``go test`` or equivalent for the + language. Any test that requires some external dependency (e.g. needs + to be scripted to run another component) needs appropriate mocking. + Anything else is not unit testing, it is integration testing by + definition. Why? Because many open source developers do Test Driven + Development. They place a watch on the directory that invokes the + tests automagically as the code is changed. This is far more + efficient than having to run a whole build between code changes. + +- Minimize the lines of code per CR. Why? Maintainers have day jobs, + too. If you send a 1,000 or 2,000 LOC change, how long do you think + it takes to review all of that code? Keep your changes to < 200-300 + LOC if possible. If you have a larger change, decompose it into + multiple independent changess. If you are adding a bunch of new + functions to fulfill the requirements of a new capability, add them + separately with their tests, and then write the code that uses them + to deliver the capability. Of course, there are always exceptions. If + you add a small change and then add 300 LOC of tests, you will be + forgiven;-) If you need to make a change that has broad impact or a + bunch of generated code (protobufs, etc.). Again, there can be + exceptions. + +- Write a meaningful commit message. Include a meaningful 50 (or less) + character title, followed by a blank line, followed my a more + comprehensive description of the change. Be sure to include the JIRA + identifier corresponding to the change (e.g. [FAB-1234]). This can be + in the title but should also be in the body of the commit message. + +e.g. + +:: + + [FAB-1234] fix foobar() panic + + Fix [FAB-1234] added a check to ensure that when foobar(foo string) is called, + that there is a non-empty string argument. + +Finally, be responsive. Don't let a change request fester with review +comments such that it gets to a point that it requires a rebase. It only +further delays getting it merged and adds more work for you - to +remediate the merge conflicts. + +Coding guidelines +----------------- + +Be sure to check out the language-specific `style +guides `__ before making any changes. This +will ensure a smoother review. + +Communication +-------------- + +We use `RocketChat `__ for communication +and Google Hangouts™ for screen sharing between developers. Our +development planning and prioritization is done in +`JIRA `__, and we take longer running +discussions/decisions to the `mailing +list `__. + +Maintainers +----------- + +The project's `maintainers `__ are responsible for +reviewing and merging all patches submitted for review and they guide +the over-all technical direction of the project within the guidelines +established by the Hyperledger Project's Technical Steering Committee +(TSC). + +Becoming a maintainer +~~~~~~~~~~~~~~~~~~~~~ + +This project is managed under an open governance model as described in +our `charter `__. Projects or +sub-projects will be lead by a set of maintainers. New sub-projects can +designate an initial set of maintainers that will be approved by the +top-level project's existing maintainers when the project is first +approved. The project's maintainers will, from time-to-time, consider +adding or removing a maintainer. An existing maintainer can submit a +change set to the `MAINTAINERS.md `__ file. If there are +less than eight maintainers, a majority of the existing maintainers on +that project are required to merge the change set. If there are more +than eight existing maintainers, then if five or more of the maintainers +concur with the proposal, the change set is then merged and the +individual is added to (or alternatively, removed from) the maintainers +group. explicit resignation, some infraction of the `code of +conduct `__ +or consistently demonstrating poor judgement. + +Legal stuff +----------- + +**Note:** Each source file must include a license header for the Apache +Software License 2.0. A template of that header can be found +`here `__. + +We have tried to make it as easy as possible to make contributions. This +applies to how we handle the legal aspects of contribution. We use the +same approach—the `Developer's Certificate of Origin 1.1 +(DCO) `__—that the Linux® Kernel +`community `__ uses +to manage code contributions. + +We simply ask that when submitting a patch for review, the developer +must include a sign-off statement in the commit message. + +Here is an example Signed-off-by line, which indicates that the +submitter accepts the DCO: + +:: + + Signed-off-by: John Doe + +You can include this automatically when you commit a change to your +local git repository using ``git commit -s``. diff --git a/docs/source/FAQ/architecture_FAQ.rst b/docs/source/FAQ/architecture_FAQ.rst new file mode 100644 index 00000000000..b082597f190 --- /dev/null +++ b/docs/source/FAQ/architecture_FAQ.rst @@ -0,0 +1,365 @@ +V1 Network and Architecture +=========================== + +Network +------- + +**Network architecture**: + +Q. In the design document, clients are supposed to be able to connect to +all peers (endorsers and consenters). But in reality, the blockchain +peers may be hosted in private, restricted and secure network, for +example, the participants are likely to host their peer in each internal +network. In this case, how can clients connect to all peers? + +A. Clients only need to connect to as many peers as are required for +endorsement. We expect 'clients' will more likely be application servers +running close to a peer, which has connection to the peer network, +rather than end user clients. There has been discussion of a 'submitting +peer' pattern where your peer could act on behalf of your client to +connect to other peers to gather endorsements and submit to ordering. +This is not in plan for v1 but may get re-visited in future releases. + +Security & Access Control +------------------------- + +**Reliance on External Application Server**: + +Q. Security (data integrity) — Reliance on an external application +server is a single-point of control over data that could be compromised +easily. Write operations flow through through the application server +and/or directly to the primary data store. These systems have no concept +of consensus and thus represent a single-point of control and therefore +vulnerability. + +A. More question context is needed - which external application server +is in question? + +Q. I hear that within a channel "everyone sees all the data." Does this +mean "every endorser sees all the data" or do all users of the chaincode +(non-endorsers) also see all the data? My understanding was that every +endorser will see all the data, but ACLs in chaincode can ensure that +users get selective visibility. Has there been a change to this? If so, +where can I find documentation? I can't find any documentation on access +control. + +A. A channel is comprised of a subset of the committing peers in a +network that are authorized to maintain the ledger (and see the data) +for a certain set of chaincodes. Endorsers are a subset of Committer +peers that simulate and endorse a given transaction on the channel, but +the transaction results will ultimately get sent to all committing peers +on the channel. Access control can still be enforced within chaincode +running on the channel, using similar ACL control mechanisms that were +in v0.5/0.6 chaincode. The ACL control options within chaincode do need +to be better documented. + +**Application-level Data access control**: + +Q. In the business process, fine grained access control is required, not +only by use or role, but also the state, or content of the data (e.g., +only the owner of the document can update it). Currently it is all +responsibility of the chaincode to implement such ALC. Is there any +design abstract for this? + +A. This aspect will remain the same as 0.5/0.6, see above question. + +Q. How is access control enforced at the direct query to CouchDB? What +is the granularity? + +A. Docker configuration enforces that only the peer container can +connect to CouchDB. All queries should go through peer chaincode, where +chaincode enforces the access control. + +Q. Even if there are multiple private chains, the Orderers can see all +the transactions, which means they are the single point of trust. This +is not acceptable in some use cases. Are there any plans to make +orderers decentralized? + +A. This is generally true. The orderers do receive a higher degree of +trust, and they must necessarily see all channels and their membership. +I would point out, however, that the orderers only see the information +which passes through them. Certain pieces of the transaction, such as +the proposal, can be configured not to go through ordering. Similarly, +any data which is referenced by hash or encrypted would be opaque to the +orderers. Clients can hash/encrypt the data that they submit to ledger. + +Q. This is not acceptable in some use cases. Is there any plans to make +orderers decentralized? + +A. I'm not sure I understand this portion of the question. There are +other ordering protocols in the works, like SBFT, which allow further +decentralization by allowing for more parties to take part because of +the Byzantine fault tolerance. But, this does not really solve the +confidentiality problem, in fact, distributing it makes it worse as +there are more potential information leakage points. + +A. I would point out that ordering does not necessarily need to be +centralized. A single peer could participate with many different +ordering networks. (This is not necessarily targeted for v1, but the +architecture does explicitly intend this). + +Q. Is encryption of transaction and ledger removed from V1? + +A. V1 does not have encryption at fabric level. The data at rest can be +encrypted via file system encryption, and the data in transit is +encrypted via TLS. In v1 it is possible to set up private channels so +that you can share a ledger (and corresponding transactions) with the +subset of network participants that are allowed to see the data. The +submitting party now has full control - they can encrypt the complete +set of data before submitting to ledger, encrypt sensitive portions +only, or not encrypt if complete transparency/queryability is the goal. + +Application-side Programming Model +---------------------------------- + +**Processing capacity of client**: + +Q. In the current design, client needs to send tx, collect endorsement +result, check endorsement policy and broadcast endowment. These tasks +are acceptable for the powerful clients such as server, but may be +beyond the processing capacity of weaker ones, such as mobile app, IOT +edge device. Is there any consideration for this scenario? + +A. We expect 'clients' will more likely be application servers that are +serving the actual end user base. That being said, there has been +discussion of a 'submitting peer' pattern where your peer could act on +behalf of your client to connect to other peers to gather endorsements +and submit to ordering. This is not in plan for v1 but may get +re-visited in future releases. + +**Transaction execution result**: + +Q. Transaction execution is asynchronous in blockchain. We cannot get +the tx result for now, which is a big problem in the solution +development. Any plan to fetch the output result? + +A. The output of the transaction execution is provided to the client by +the endorser. Ultimately the transaction output will get validated or +invalidated by the committing peers, and the client becomes aware of the +outcome via an event. + +Monitoring +---------- + +**More Monitoring Metrics are expected from the Docker Image**: + +Q. (phrased as a requirement) Provide basic information about deployed +chaincode on the chain, such as chaincode ID, its deployed time, etc. +For each chain code, with proper permission, provide invoke/query +metrics data such as TPS, consensus latency (average, 50%, 85%), broken +down into different chaincode API (function). Provide storage usage +information on peer node. + +A. Agreed, much work remains around serviceability in general, +monitoring is one piece of that. The specific feedback here has been +added to: https://jira.hyperledger.org/browse/FAB-2174 - As an +administrator, I need better runtime monitoring capabilities for the +fabric + +Backward Compatibility +---------------------- + +**Chaincode Stub Interface**: + +Q. (phrased as a requirement) It's preferred to minimize changes to +chaincode stub API 1. Removal of Table API causes backward compatibility +issues to existing chaincode 2. Need RangeQuery for the world state to +maintain backward compatibility of chaincode + +A. There is general agreement that chaincode API should be as stable as +possible. That being said, 0.5/0.6 was a developer preview to gather +feedback, and community feedback around API experiences must be taken +into consideration for v1 release. There were many complaints and +frustrations around the table API limitations, since it added overhead +but didn't enable typical table queries. v1 provides a broader and +richer set of APIs that solutions have called for, including +``GetStateByRange()``, ``GetStateByPartialCompositeKey()``, +``GetHistoryForKey()`` against the default/embedded Key/Value data +store. Also there is a beta option to use CouchDB JSON document store +that enables rich query via a new ``GetQueryResult()`` API. The new rich +query is intended to be used for read-only queries, but it can also be +used in chaincode read-write transactions if the application layer can +guarantee the stability of the query result set between transaction +simulation and validation/commit phases (no phantoms). + +**REST API**: + +Q. (phrased as a requirement) It's preferred to maintain REST API and +hopefully make it more secure, in order to use existing tools via REST +API (e.g., JMeter, Postman, etc.) + +A. SDK resolves security concerns of 0.5/0.6 REST API. SDK itself will +likely provide the REST API interface going forward (rather than the +peer). This is not yet available but planned for v1 or shortly +thereafter. + +**Database / Data Store** + +Q. How ACL is enforced at block data? + +A. In v1 a member of the channel has access to the data on that +channel's ledger. Access can be controlled within chaincode, and data +can be encrypted before submitting to ledger. See questions in Security +section above. + +**ACID-Compliant Transactions**: + +Q. (phrased as a requirement) ACID-compliant transactions. While the +overall Hyperledger system is eventually consistent, having a local +datastore that is ACID compliant will simplify +integration/implementation. + +A. v1 architecture separates execution (transaction simulation) and +validation/commit phases. Upon commit, the transaction is indeed atomic, +consistent, isolated (serializable), and durable. But clients working +with endorsers and the chaincode needs to be designed with the +understanding that the transaction is a proposal only, until such time +that it is sent to peers for commitment. See NCAP document for more +details: +https://github.com/hyperledger/fabric/blob/master/proposals/r1/Next-Consensus-Architecture-Proposal.md + +Q. (phrased as a requirement) Query the historical data + +A. New chaincode API in v1 ``GetHistoryForKey()`` will return history of +values for a key. + +Q. (phrased as a requirement) Too much burden on chaincode to implement +data access layer (such as DAO) to wrap KVS. + +A. v1 provides a broader and richer set of APIs that solutions have +called for, including ``GetStateByRange()``, +``GetStateByPartialCompositeKey()``, ``GetHistoryForKey()`` against the +default/embedded Key/Value data store. Also there is a beta option to +use CouchDB JSON document store that enables rich query via a new +GetQueryResult() API. The new rich query is intended to be used for +read-only queries, but it can also be used in chaincode read-write +transactions if the application layer can guarantee the stability of the +query result set between transaction simulation and validation/commit +phases (no phantoms). Research is investigating even richer data +experience for future releases. Additionally, the new Composer offering +is intended to make it simpler for developers to work with the fabric. + +**Data integrity constraint**: + +Q. Data integrity constraint is an important requirement from customer. +For example, the balance of user bank account should always be +non-negative. Is there any plan for data integrity constraint? + +A. Chaincode is the appropriate place to enforce data constraints. + +Q. How to guarantee the query result is correct, when the peer being +queried is just recovering from failure and in the middle of the state +transfer? + +A. New blocks are always being added to the blockchain, whether the peer +is catching up or doing normal processing. The client can query multiple +peers, compare their block heights, compare their query results, and +favor the peers at the higher block heights. + +**The Missing/Altered Data Problem**: + +Q. (phrased as a requirement) Describe the minimal query results vs full +set, how we can only do error detection. If we search for Shanghai, and +get five results, and can verify the hashcode, that means that at a +minimum there are five assets from Shanghai. However, there may in fact +be more, but they may have been edited to say the location is Beijing. +For those we can only detect that they are wrong, but we cannot correct +them back to Shanghai. + +A. Is this a question about past state, or malicious tampering of data? +If the former, there has been talk of solutions to sync data to a data +warehouse for historical queries and analysis. If the latter, there is +future work planned to audit the validity of the blockchain data, for +example recalculate and compare hashes to prove/audit the data integrity +of the blockchain. + +Q. (phrased as a requirement) No support for tables and range queries. +Only simple GetState and PutState. + +A. There were many complaints and frustrations around the table API +limitations in 0.5/0.6, since it added overhead but didn't enable +typical table queries. v1 provides a broader and richer set of APIs that +solutions have called for, including ``GetStateByRange()``, +``GetStateByPartialCompositeKey()``, ``GetHistoryForKey()`` against the +default/embedded Key/Value data store. Also there is a beta option to +use CouchDB JSON document store that enables rich query via a new +GetQueryResult() API. The new rich query is intended to be used for +read-only queries, but it can also be used in chaincode read-write +transactions if the application layer can guarantee the stability of the +query result set between transaction simulation and validation/commit +phases (no phantoms). + +Q. (phrased as a requirement) Request for a Trusted Storage Service to +store large files that are not appropriate to store in the world state +and to replicate across all the peers. + +A. In traditional systems, it is very common to have a separate object +storage to manage large object files aside from the DBMS. A common +approach today is to only store the hash values of the files in the +ledger and have the files managed somewhere else. There are three main +problems for this approach. 1. the developer has to handle the +interaction between the ledger and the object storage. 2. there is no +good way to guarantee the consistency of the content between the ledger +and the object storage. 3. the object storage has to be well secured, +and protected by the access control in the same manner as the data on +blockchain. Therefore, trusted storage service, that is integrated with +blockchain is desired. + +Additional issues when most of the data is stored in an external data +store, and the hash-codes used for verification and the linked-list data +structures are stored in in the blockchain. This leads to the following +problems: + +2.1. Primary Data Store Schema/Behavior Changes — In order to track an +asset and recall historical values, the whole point of provenance, the +primary data store, which is external to blockchain, will need to store +all historical versions of the documents. Without this, historical hash +values stored on the blockchain are meaningless for navigating +provenance. + +2.2. Query-ability —The blockchain serves two purposes in the provenance +solution as it stands today: data integrity and storing the graph of +historical hash values of an asset. This means that for many types of +queries, such as tell me all locations an asset has been at, the +application server must perform data fusion between the lineage data, +which is a sequence of document hashes, and the primary data store, +which has been supplemented to store the document hashes necessary for +quickly retrieving the documents referenced by the provenance graph’s +hashes stored in the blockchain. + +2.3. Data duplication — In part to overcome the query-ability +challenges, some additional data should be duplicated in the primary +data store. For example, to be able to easily traverse the history of an +asset, it is helpful to store the hash of the previous document in the +primary data store so that the application server is not required to +perform data fusion between the data stored in the blockchain and the +primary data store to show the provenance of an asset, such as all +locations it has been at. + +It sounds like new v1 rich query and history APIs will help, but will +not entirely address the requirement here. Please net out the specific +remaining requirements for consideration post-v1. + +**Data Integration with Graph DB**: + +Q. Blockchain Integration Challenges for Provenance MVP. + +1. Manipulating/querying the opaque linked-list data structure stored in + the values of the Hyperledger key-value store is not possible in a + generic way. Custom chaincode that is able to interpret the opaque + data structure is required. 1.1. Thoughts: In graph databases, such + as Neo4J, there are typically three data stores used to represent the + various parts of a graph: 1) Nodes: a key-value store with the node + id as the key, 2) Properties, and 3) Relationships. The most basic + solution would be to allow us to use multiple key-value stores as + part of the chaincode, but of course if we do that we might as well + just focus on integrating an existing graph database. One good + example of a graph database that in fact already uses rocksdb and is + written in go is Dgraph. However, this data structure is not + well-optimized for forward edge-chaining traversals, such as we want + to use for traversing history. +2. Related to the thoughts mentioned in point 1, we really need a good + way to do efficient graph edge/version traversal. Typical graph + systems are optimized for answering questions such as "tell me the + set of all friends of my friends" This only chains two edge + traversals. We are mostly interested in much longer edge traversals. diff --git a/docs/source/FAQ/chaincode_FAQ.rst b/docs/source/FAQ/chaincode_FAQ.rst new file mode 100644 index 00000000000..fe51964c98e --- /dev/null +++ b/docs/source/FAQ/chaincode_FAQ.rst @@ -0,0 +1,58 @@ +Chaincode (Smart Contracts and Digital Assets) +---------------------------------------------- + +* Does the fabric implementation support smart contract logic? + +Yes. Chaincode is the fabric’s interpretation of the smart contract +method/algorithm, with additional features. + +A chaincode is programmatic code deployed on the network, where it is +executed and validated by chain validators together during the consensus +process. Developers can use chaincodes to develop business contracts, +asset definitions, and collectively-managed decentralized applications. + +* How do I create a business contract using the fabric? + +There are generally two ways to develop business contracts: the first way is to +code individual contracts into standalone instances of chaincode; the +second way, and probably the more efficient way, is to use chaincode to +create decentralized applications that manage the life cycle of one or +multiple types of business contracts, and let end users instantiate +instances of contracts within these applications. + +* How do I create assets using the fabric? + +Users can use chaincode (for business rules) and membership service (for digital tokens) to +design assets, as well as the logic that manages them. + +There are two popular approaches to defining assets in most blockchain +solutions: the stateless UTXO model, where account balances are encoded +into past transaction records; and the account model, where account +balances are kept in state storage space on the ledger. + +Each approach carries its own benefits and drawbacks. This blockchain +fabric does not advocate either one over the other. Instead, one of our +first requirements was to ensure that both approaches can be easily +implemented with tools available in the fabric. + +* Which languages are supported for writing chaincode? + +Chaincode can be written in any programming language and executed in containers +inside the fabric context layer. We are also looking into developing a +templating language (such as Apache Velocity) that can either get +compiled into chaincode or have its interpreter embedded into a +chaincode container. + +The fabric's first fully supported chaincode language is Golang, and +support for JavaScript and Java is planned for 2016. Support for +additional languages and the development of a fabric-specific templating +language have been discussed, and more details will be released in the +near future. + +* Does the fabric have native currency? + +No. However, if you really need a native currency for your chain network, you can develop your own +native currency with chaincode. One common attribute of native currency +is that some amount will get transacted (the chaincode defining that +currency will get called) every time a transaction is processed on its +chain. diff --git a/docs/source/FAQ/confidentiality_FAQ.rst b/docs/source/FAQ/confidentiality_FAQ.rst new file mode 100644 index 00000000000..c17b4a2b5b1 --- /dev/null +++ b/docs/source/FAQ/confidentiality_FAQ.rst @@ -0,0 +1,28 @@ +Confidentiality +=============== + + * How is the confidentiality of transactions and business logic achieved? + +The security module works in conjunction with the membership service +module to provide access control service to any data recorded and +business logic deployed on a chain network. + +When a code is deployed on a chain network, whether it is used to define +a business contract or an asset, its creator can put access control on +it so that only transactions issued by authorized entities will be +processed and validated by chain validators. + +Raw transaction records are permanently stored in the ledger. While the +contents of non-confidential transactions are open to all participants, +the contents of confidential transactions are encrypted with secret keys +known only to their originators, validators, and authorized auditors. +Only holders of the secret keys can interpret transaction contents. + +* What if none of the stakeholders of a business contract are +validators? + +In some business scenarios, full confidentiality of contract +logic may be required – such that only contract counterparties and +auditors can access and interpret their chaincode. Under these +scenarios, counter parties would need to spin off a new child chain with +only themselves as validators. diff --git a/docs/source/FAQ/consensus_FAQ.rst b/docs/source/FAQ/consensus_FAQ.rst new file mode 100644 index 00000000000..929db98f1be --- /dev/null +++ b/docs/source/FAQ/consensus_FAQ.rst @@ -0,0 +1,10 @@ +Consensus Algorithm +------------------- + +Which Consensus Algorithm is used in Fabric? + +The fabric is built on a pluggable architecture such that developers can configure +their deployment with the consensus module that best suits their needs. +The initial release package will offer three consensus implementations +for users to select from: 1) No-op (consensus ignored); and 2) Batch +PBFT. diff --git a/docs/source/FAQ/identity_management_FAQ.rst b/docs/source/FAQ/identity_management_FAQ.rst new file mode 100644 index 00000000000..476e22e72bd --- /dev/null +++ b/docs/source/FAQ/identity_management_FAQ.rst @@ -0,0 +1,35 @@ +Identity Management (Membership Service) +---------------------------------------- + +* What is unique about the fabric's Membership Service module? + +One of the things that makes the Membership Service module stand out from +the pack is our implementation of the latest advances in cryptography. + +In addition to ensuring private, auditable transactions, our Membership +Service module introduces the concept of enrollment and transaction +certificates. This innovation ensures that only verified owners can +create asset tokens, allowing an infinite number of transaction +certificates to be issued through parent enrollment certificates while +guaranteeing the private keys of asset tokens can be regenerated if +lost. + +Issuers also have the ability revoke transaction certificates or +designate them to expire within a certain timeframe, allowing greater +control over the asset tokens they have issued. + +Like most other modules on Fabric, you can always replace the +default module with another membership service option should the need +arise. + +* Does its Membership Service make Fabric a centralized +solution? + +No. The only role of the Membership Service module is to issue digital +certificates to validated entities that want to participate in the +network. It does not execute transactions nor is it aware of how or when +these certificates are used in any particular network. + +However, because certificates are the way networks regulate and manage +their users, the module serves a central regulatory and organizational +role. diff --git a/docs/source/FAQ/usage_FAQ.rst b/docs/source/FAQ/usage_FAQ.rst new file mode 100644 index 00000000000..977aa61c0ff --- /dev/null +++ b/docs/source/FAQ/usage_FAQ.rst @@ -0,0 +1,48 @@ +Usage +----- + +* What are the expected performance figures for the fabric? + +The performance of any chain network depends on several factors: proximity +of the validating nodes, number of validators, encryption method, +transaction message size, security level set, business logic running, +and the consensus algorithm deployed, among others. + +The current performance goal for the fabric is to achieve 100,000 +transactions per second in a standard production environment of about 15 +validating nodes running in close proximity. The team is committed to +continuously improving the performance and the scalability of the +system. + +* Do I have to own a validating node to transact on a chain +network? + +No. You can still transact on a chain network by owning a +non-validating node (NV-node). + +Although transactions initiated by NV-nodes will eventually be forwarded +to their validating peers for consensus processing, NV-nodes establish +their own connections to the membership service module and can therefore +package transactions independently. This allows NV-node owners to +independently register and manage certificates, a powerful feature that +empowers NV-node owners to create custom-built applications for their +clients while managing their client certificates. + +In addition, NV-nodes retain full copies of the ledger, enabling local +queries of the ledger data. + +* What does the error string "state may be inconsistent, cannot +query" as a query result mean? + +Sometimes, a validating peer will be out +of sync with the rest of the network. Although determining this +condition is not always possible, validating peers make a best effort +determination to detect it, and internally mark themselves as out of +date. + +When under this condition, rather than reply with out of date or +potentially incorrect data, the peer will reply to chaincode queries +with the error string "state may be inconsistent, cannot query". + +In the future, more sophisticated reporting mechanisms may be introduced +such as returning the stale value and a flag that the value is stale. diff --git a/docs/Gerrit/best-practices.md b/docs/source/Gerrit/best-practices.md similarity index 100% rename from docs/Gerrit/best-practices.md rename to docs/source/Gerrit/best-practices.md diff --git a/docs/Gerrit/changes.md b/docs/source/Gerrit/changes.md similarity index 100% rename from docs/Gerrit/changes.md rename to docs/source/Gerrit/changes.md diff --git a/docs/Gerrit/gerrit.md b/docs/source/Gerrit/gerrit.md similarity index 100% rename from docs/Gerrit/gerrit.md rename to docs/source/Gerrit/gerrit.md diff --git a/docs/Gerrit/lf-account.md b/docs/source/Gerrit/lf-account.md similarity index 100% rename from docs/Gerrit/lf-account.md rename to docs/source/Gerrit/lf-account.md diff --git a/docs/Gerrit/reviewing.md b/docs/source/Gerrit/reviewing.md similarity index 100% rename from docs/Gerrit/reviewing.md rename to docs/source/Gerrit/reviewing.md diff --git a/docs/source/MAINTAINERS.rst b/docs/source/MAINTAINERS.rst new file mode 100644 index 00000000000..2d1447c998d --- /dev/null +++ b/docs/source/MAINTAINERS.rst @@ -0,0 +1,30 @@ +Maintainers +----------- + ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Name | Gerrit | GitHub | Slack | email | ++===========================+=====================+==================+================+================================+ +| Binh Nguyen | binhn | binhn | binhn | binhn@us.ibm.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Chris Ferris | ChristopherFerris | christo4ferris | cbf | chris.ferris@gmail.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Gabor Hosszu | hgabre | gabre | hgabor | gabor@digitalasset.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Gari Singh | mastersingh24 | mastersingh24 | garisingh | gari.r.singh@gmail.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Greg Haskins | greg.haskins | ghaskins | ghaskins | gregory.haskins@gmail.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Jason Yellick | jyellick | jyellick | jyellick | jyellick@us.ibm.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Jim Zhang | jimthematrix | jimthematrix | jzhang | jim\_the\_matrix@hotmail.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Jonathan Levi | JonathanLevi | JonathanLevi | JonathanLevi | jonathan@hacera.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Sheehan Anderson | sheehan | srderson | sheehan | sranderson@gmail.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Srinivasan Muralidharan | muralisr | muralisrini | muralisr | muralisr@us.ibm.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Tamas Blummer | TamasBlummer | tamasblummer | tamas | tamas@digitalasset.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ +| Yacov Manevich | yacovm | yacovm | yacovm | yacovm@il.ibm.com | ++---------------------------+---------------------+------------------+----------------+--------------------------------+ diff --git a/docs/source/Setup/Chaincode-setup.rst b/docs/source/Setup/Chaincode-setup.rst new file mode 100644 index 00000000000..ec189b3818f --- /dev/null +++ b/docs/source/Setup/Chaincode-setup.rst @@ -0,0 +1,746 @@ +Writing, Building, and Running Chaincode in a Development Environment +--------------------------------------------------------------------- + +Chaincode developers need a way to test and debug their chaincode +without having to set up a complete peer network. By default, when you +want to interact with chaincode, you need to first ``Deploy`` it using +the CLI, REST API, gRPC API, or SDK. Upon receiving this request, the +peer node would typically spin up a Docker container with the relevant +chaincode. This can make things rather complicated for debugging +chaincode under development, because of the turnaround time with the +``launch chaincode - debug docker container - fix problem - launch chaincode - lather - rinse - repeat`` +cycle. As such, the fabric peer has a ``--peer-chaincodedev`` flag that +can be passed on start-up to instruct the peer node not to deploy the +chaincode as a Docker container. + +The following instructions apply to *developing* chaincode in Go or +Java. They do not apply to running in a production environment. However, +if *developing* chaincode in Java, please see the `Java chaincode +setup `__ +instructions first, to be sure your environment is properly configured. + +**Note:** We have added support for `System +chaincode `__. + +Choices +------- + +Once again, you have the choice of using one of the following +approaches: + +- `Option 1 <#option-1-vagrant-development-environment>`__ using the + **Vagrant** `development + environment `__ + that is used for developing the fabric itself +- `Option 2 <#option-2-docker-for-mac-or-windows>`__ using Docker for + Mac or Windows +- `Option 3 <#option-3-docker-toolbox>`__ using Docker toolbox + +By using options *2* or *3*, above, you avoid having to build everything +from scratch, and there's no need to keep a clone of the fabric GitHub +repos current/up-to-date. Instead, you can simply pull and run the +``fabric-peer`` and ``fabric-membersrvc`` images directly from +DockerHub. + +You will need multiple terminal windows - essentially one for each +component. One runs the validating peer; another runs the chaincode; the +third runs the CLI or REST API commands to execute transactions. +Finally, when running with security enabled, an additional fourth window +is required to run the **Certificate Authority (CA)** server. Detailed +instructions are provided in the sections below. + +Option 1 Vagrant development environment +---------------------------------------- + +Security Setup (optional) +~~~~~~~~~~~~~~~~~~~~~~~~~ + +From the ``devenv`` subdirectory of your fabric workspace environment, +``ssh`` into Vagrant: + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric/devenv + vagrant ssh + +To set up the local development environment with security enabled, you +must first build and run the **Certificate Authority (CA)** server: + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric + make membersrvc && membersrvc + +Running the above commands builds and runs the CA server with the +default setup, which is defined in the +`membersrvc.yaml `__ +configuration file. The default configuration includes multiple users +who are already registered with the CA; these users are listed in the +``eca.users`` section of the configuration file. To register additional +users with the CA for testing, modify the ``eca.users`` section of the +`membersrvc.yaml `__ +file to include additional ``enrollmentID`` and ``enrollmentPW`` pairs. +Note the integer that precedes the ``enrollmentPW``. That integer +indicates the role of the user, where 1 = client, 2 = non-validating +peer, 4 = validating peer, and 8 = auditor. + +Running the validating peer +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In a **new** terminal window, from the ``devenv`` subdirectory of your +fabric workspace environment, ``ssh`` into Vagrant: + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric/devenv + vagrant ssh + +Build and run the peer process. + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric + make peer + peer node start --peer-chaincodedev + +Alternatively, rather than tweaking the ``core.yaml`` and rebuilding, +you can enable security and privacy on the peer with environment +variables: + +:: + + CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer node start --peer-chaincodedev + +Now, you are ready to start `running the +chaincode <#running-the-chaincode>`__. + +Option 2 Docker for Mac or Windows +---------------------------------- + +If you would prefer to simply run the fabric components as built and +published by the Hyperledger project on your Mac or Windows +laptop/server using the Docker for +`Mac `__ or +`Windows `__ +platform, following these steps. If using `Docker +Toolbox `__, please skip to +`Option 3 <#option-3-docker-toolbox>`__, below. + +Pull images from DockerHub +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +First, pull the latest images published by the Hyperledger fabric +project from DockerHub. + +:: + + docker pull hyperledger/fabric-peer:latest + docker pull hyperledger/fabric-membersrvc:latest + +Running the Peer and CA +~~~~~~~~~~~~~~~~~~~~~~~ + +To run the fabric-peer and fabric-membersrvc images, we'll use `Docker +Compose `__. It significantly +simplifies things. To do that, we'll create a docker-compose.yml file +with a description of the two services we'll be running. Here's the +docker-compose.yml to launch the two processes: + +:: + + membersrvc: + image: hyperledger/fabric-membersrvc + ports: + - "7054:7054" + command: membersrvc + vp0: + image: hyperledger/fabric-peer + ports: + - "7050:7050" + - "7051:7051" + - "7053:7053" + environment: + - CORE_PEER_ADDRESSAUTODETECT=true + - CORE_VM_ENDPOINT=unix:///var/run/docker.sock + - CORE_LOGGING_LEVEL=DEBUG + - CORE_PEER_ID=vp0 + - CORE_PEER_PKI_ECA_PADDR=membersrvc:7054 + - CORE_PEER_PKI_TCA_PADDR=membersrvc:7054 + - CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054 + - CORE_SECURITY_ENABLED=true + - CORE_SECURITY_ENROLLID=test_vp0 + - CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT + links: + - membersrvc + command: sh -c "sleep 5; peer node start --peer-chaincodedev" + +Save that in a directory with the name ``docker-compose.yml``. Then, run +``docker-compose up`` to start the two processes. + +Now, you are ready to start `running the +chaincode <#running-the-chaincode>`__. + +Option 3 Docker Toolbox +----------------------- + +If you are using `Docker +Toolbox `__, please follow +these instructions. + +Pull images from DockerHub +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +First, pull the latest images published by the Hyperledger fabric +project from DockerHub. + +:: + + docker pull hyperledger/fabric-peer:latest + docker pull hyperledger/fabric-membersrvc:latest + +Running the Peer and CA +~~~~~~~~~~~~~~~~~~~~~~~ + +To run the fabric-peer and fabric-membersrvc images, we'll use `Docker +Compose `__. It significantly +simplifies things. To do that, we'll create a docker-compose.yml file +with a description of the two services we'll be running. Here's the +docker-compose.yml to launch the two processes: + +:: + + membersrvc: + image: hyperledger/fabric-membersrvc + command: membersrvc + vp0: + image: hyperledger/fabric-peer + environment: + - CORE_PEER_ADDRESSAUTODETECT=true + - CORE_VM_ENDPOINT=http://172.17.0.1:2375 + - CORE_LOGGING_LEVEL=DEBUG + - CORE_PEER_ID=vp0 + - CORE_PEER_PKI_ECA_PADDR=membersrvc:7054 + - CORE_PEER_PKI_TCA_PADDR=membersrvc:7054 + - CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054 + - CORE_SECURITY_ENABLED=true + - CORE_SECURITY_ENROLLID=test_vp0 + - CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT + links: + - membersrvc + command: sh -c "sleep 5; peer node start --peer-chaincodedev" + +Save that in a directory with the name ``docker-compose.yml``. Then, run +``docker-compose up`` to start the two processes. + +Running the chaincode +--------------------- + +Start a **new** terminal window. + +Vagrant +~~~~~~~ + +If you are using `Option +1 <#option-1-vagrant-development-environment>`__, you'll need to ``ssh`` +to Vagrant. Otherwise, `skip <#not-vagrant>`__ this step. + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric/devenv + vagrant ssh + +Next, we'll build the **chaincode\_example02** code, which is provided +in the Hyperledger fabric source code repository. If you are using +`Option 1 <#option-1-vagrant-development-environment>`__, then you can +do this from your clone of the fabric repository. + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 + go build + +Not Vagrant +~~~~~~~~~~~ + +If you are using either `Option +2 <#option-2-docker-for-mac-or-windows>`__ or `Option +3 <#option-3-docker-toolbox>`__, you'll need to download the sample +chaincode. The chaincode project must be placed somewhere under the +``src`` directory in your local ``$GOPATH`` as shown below. + +:: + + mkdir -p $GOPATH/src/github.com/chaincode_example02/ + cd $GOPATH/src/github.com/chaincode_example02 + curl --request GET https://raw.githubusercontent.com/hyperledger/fabric/master/examples/chaincode/go/chaincode_example02/chaincode_example02.go > chaincode_example02.go + +Next, you'll need to clone the Hyperledger fabric to your local $GOPATH, +so that you can build your chaincode. **Note:** this is a temporary +stop-gap until we can provide an independent package for the chaincode +shim. + +:: + + mkdir -p $GOPATH/src/github.com/hyperledger + cd $GOPATH/src/github.com/hyperledger + git clone http://gerrit.hyperledger.org/r/fabric + +Now, you should be able to build your chaincode. + +:: + + cd $GOPATH/src/github.com/chaincode_example02 + go build + +When you are ready to start creating your own Go chaincode, create a new +subdirectory under $GOPATH/src. You can copy the +**chaincode\_example02** file to the new directory and modify it. + +Starting and registering the chaincode +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Run the following chaincode command to start and register the chaincode +with the validating peer: + +:: + + CORE_CHAINCODE_ID_NAME=mycc CORE_PEER_ADDRESS=0.0.0.0:7051 ./chaincode_example02 + +The chaincode console will display the message "Received REGISTERED, +ready for invocations", which indicates that the chaincode is ready to +receive requests. Follow the steps below to send a chaincode deploy, +invoke or query transaction. If the "Received REGISTERED" message is not +displayed, then an error has occurred during the deployment; revisit the +previous steps to resolve the issue. + +Running the CLI or REST API +--------------------------- + +- `chaincode deploy via CLI and + REST <#chaincode-deploy-via-cli-and-rest>`__ +- `chaincode invoke via CLI and + REST <#chaincode-invoke-via-cli-and-rest>`__ +- `chaincode query via CLI and + REST <#chaincode-query-via-cli-and-rest>`__ + +If you were running with security enabled, see `Removing temporary files +when security is +enabled <#removing-temporary-files-when-security-is-enabled>`__ to learn +how to clean up the temporary files. + +See the `logging +control `__ +reference for information on controlling logging output from the +``peer`` and chaincodes. + +Terminal 3 (CLI or REST API) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Note on REST API port** +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The default REST interface port is ``7050``. It can be configured in +`core.yaml `__ +using the ``rest.address`` property. If using Vagrant, the REST port +mapping is defined in +`Vagrantfile `__. + +**Note on security functionality** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Current security implementation assumes that end user authentication +takes place at the application layer and is not handled by the fabric. +Authentication may be performed through any means considered appropriate +for the target application. Upon successful user authentication, the +application will perform user registration with the CA exactly once. If +registration is attempted a second time for the same user, an error will +result. During registration, the application sends a request to the +certificate authority to verify the user registration and if successful, +the CA responds with the user certificates and keys. The enrollment and +transaction certificates received from the CA will be stored locally +inside ``/var/hyperledger/production/crypto/client/`` directory. This +directory resides on a specific peer node which allows the user to +transact only through this specific peer while using the stored crypto +material. If the end user needs to perform transactions through more +then one peer node, the application is responsible for replicating the +crypto material to other peer nodes. This is necessary as registering a +given user with the CA a second time will fail. + +With security enabled, the CLI commands and REST payloads must be +modified to include the ``enrollmentID`` of a registered user who is +logged in; otherwise an error will result. A registered user can be +logged in through the CLI or the REST API by following the instructions +below. To log in through the CLI, issue the following commands, where +``username`` is one of the ``enrollmentID`` values listed in the +``eca.users`` section of the +`membersrvc.yaml `__ +file. + +From your command line terminal, move to the ``devenv`` subdirectory of +your workspace environment. Log into a Vagrant terminal by executing the +following command: + +:: + + vagrant ssh + +Register the user though the CLI, substituting for ```` +appropriately: + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric/peer + peer network login + +The command will prompt for a password, which must match the +``enrollmentPW`` listed for the target user in the ``eca.users`` section +of the +`membersrvc.yaml `__ +file. If the password entered does not match the ``enrollmentPW``, an +error will result. + +To log in through the REST API, send a POST request to the +``/registrar`` endpoint, containing the ``enrollmentID`` and +``enrollmentPW`` listed in the ``eca.users`` section of the +`membersrvc.yaml `__ +file. + +**REST Request:** + +:: + + POST localhost:7050/registrar + + { + "enrollId": "jim", + "enrollSecret": "6avZQLwcUe9b" + } + +**REST Response:** + +:: + + 200 OK + { + "OK": "Login successful for user 'jim'." + } + +chaincode deploy via CLI and REST +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +First, send a chaincode deploy transaction, only once, to the validating +peer. The CLI connects to the validating peer using the properties +defined in the core.yaml file. **Note:** The deploy transaction +typically requires a ``path`` parameter to locate, build, and deploy the +chaincode. However, because these instructions are specific to local +development mode and the chaincode is deployed manually, the ``name`` +parameter is used instead. + +:: + + peer chaincode deploy -n mycc -c '{"Args": ["init", "a","100", "b", "200"]}' + +Alternatively, you can run the chaincode deploy transaction through the +REST API. + +**REST Request:** + +:: + + POST /chaincode + + { + "jsonrpc": "2.0", + "method": "deploy", + "params": { + "type": 1, + "chaincodeID":{ + "name": "mycc" + }, + "input": { + "args":["init", "a", "100", "b", "200"] + } + }, + "id": 1 + } + +**REST Response:** + +:: + + { + "jsonrpc": "2.0", + "result": { + "status": "OK", + "message": "mycc" + }, + "id": 1 + } + +**Note:** When security is enabled, modify the CLI command and the REST +API payload to pass the ``enrollmentID`` of a logged in user. To log in +a registered user through the CLI or the REST API, follow the +instructions in the `note on security +functionality <#note-on-security-functionality>`__. On the CLI, the +``enrollmentID`` is passed with the ``-u`` parameter; in the REST API, +the ``enrollmentID`` is passed with the ``secureContext`` element. If +you are enabling security and privacy on the peer process with +environment variables, it is important to include these environment +variables in the command when executing all subsequent peer operations +(e.g. deploy, invoke, or query). + +:: + + CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode deploy -u jim -n mycc -c '{"Args": ["init", "a","100", "b", "200"]}' + +**REST Request:** + +:: + + POST /chaincode + + { + "jsonrpc": "2.0", + "method": "deploy", + "params": { + "type": 1, + "chaincodeID":{ + "name": "mycc" + }, + "input": { + "args":["init", "a", "100", "b", "200"] + }, + "secureContext": "jim" + }, + "id": 1 + } + +The deploy transaction initializes the chaincode by executing a target +initializing function. Though the example shows "init", the name could +be arbitrarily chosen by the chaincode developer. You should see the +following output in the chaincode window: + +:: + + Received INIT(uuid:005dea42-d57f-4983-803e-3232e551bf61), initializing chaincode + Aval = 100, Bval = 200 + +Chaincode invoke via CLI and REST +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Run the chaincode invoking transaction on the CLI as many times as +desired. The ``-n`` argument should match the value provided in the +chaincode window (started in Vagrant terminal 2): + +:: + + peer chaincode invoke -l golang -n mycc -c '{"Args": ["invoke", "a", "b", "10"]}' + +Alternatively, run the chaincode invoking transaction through the REST +API. + +**REST Request:** + +:: + + POST /chaincode + + { + "jsonrpc": "2.0", + "method": "invoke", + "params": { + "type": 1, + "chaincodeID":{ + "name":"mycc" + }, + "input": { + "args":["invoke", "a", "b", "10"] + } + }, + "id": 3 + } + +**REST Response:** + +:: + + { + "jsonrpc": "2.0", + "result": { + "status": "OK", + "message": "5a4540e5-902b-422d-a6ab-e70ab36a2e6d" + }, + "id": 3 + } + +**Note:** When security is enabled, modify the CLI command and REST API +payload to pass the ``enrollmentID`` of a logged in user. To log in a +registered user through the CLI or the REST API, follow the instructions +in the `note on security +functionality <#note-on-security-functionality>`__. On the CLI, the +``enrollmentID`` is passed with the ``-u`` parameter; in the REST API, +the ``enrollmentID`` is passed with the ``secureContext`` element. If +you are enabling security and privacy on the peer process with +environment variables, it is important to include these environment +variables in the command when executing all subsequent peer operations +(e.g. deploy, invoke, or query). + +:: + + CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode invoke -u jim -l golang -n mycc -c '{"Args": ["invoke", "a", "b", "10"]}' + +**REST Request:** + +:: + + POST /chaincode + + { + "jsonrpc": "2.0", + "method": "invoke", + "params": { + "type": 1, + "chaincodeID":{ + "name":"mycc" + }, + "input": { + "args":["invoke", "a", "b", "10"] + }, + "secureContext": "jim" + }, + "id": 3 + } + +The invoking transaction runs the specified chaincode function name +"invoke" with the arguments. This transaction transfers 10 units from A +to B. You should see the following output in the chaincode window: + +:: + + Received RESPONSE. Payload 200, Uuid 075d72a4-4d1f-4a1d-a735-4f6f60d597a9 + Aval = 90, Bval = 210 + +Chaincode query via CLI and REST +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Run a query on the chaincode to retrieve the desired values. The ``-n`` +argument should match the value provided in the chaincode window +(started in Vagrant terminal 2): + +:: + + peer chaincode query -l golang -n mycc -c '{"Args": ["query", "b"]}' + +The response should be similar to the following: + +:: + + {"Name":"b","Amount":"210"} + +If a name other than "a" or "b" is provided in a query sent to +``chaincode_example02``, you should see an error response similar to the +following: + +:: + + {"Error":"Nil amount for c"} + +Alternatively, run the chaincode query transaction through the REST API. + +**REST Request:** + +:: + + POST /chaincode + + { + "jsonrpc": "2.0", + "method": "query", + "params": { + "type": 1, + "chaincodeID":{ + "name":"mycc" + }, + "input": { + "args":["query", "a"] + } + }, + "id": 5 + } + +**REST Response:** + +:: + + { + "jsonrpc": "2.0", + "result": { + "status": "OK", + "message": "90" + }, + "id": 5 + } + +**Note:** When security is enabled, modify the CLI command and REST API +payload to pass the ``enrollmentID`` of a logged in user. To log in a +registered user through the CLI or the REST API, follow the instructions +in the `note on security +functionality <#note-on-security-functionality>`__. On the CLI, the +``enrollmentID`` is passed with the ``-u`` parameter; in the REST API, +the ``enrollmentID`` is passed with the ``secureContext`` element. If +you are enabling security and privacy on the peer process with +environment variables, it is important to include these environment +variables in the command when executing all subsequent peer operations +(e.g. deploy, invoke, or query). + +:: + + CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode query -u jim -l golang -n mycc -c '{"Args": ["query", "b"]}' + +**REST Request:** + +:: + + POST /chaincode + + { + "jsonrpc": "2.0", + "method": "query", + "params": { + "type": 1, + "chaincodeID":{ + "name":"mycc" + }, + "input": { + "args":["query", "a"] + }, + "secureContext": "jim" + }, + "id": 5 + } + +Removing temporary files when security is enabled +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**Note:** this step applies **ONLY** if you were using Option 1 above. +For Option 2 or 3, the cleanup is handled by Docker. + +After the completion of a chaincode test with security enabled, remove +the temporary files that were created by the CA server process. To +remove the client enrollment certificate, enrollment key, transaction +certificate chain, etc., run the following commands. Note, that you must +run these commands if you want to register a user who has already been +registered previously. + +From your command line terminal, ``ssh`` into Vagrant: + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric/devenv + vagrant ssh + +And then run: + +:: + + rm -rf /var/hyperledger/production diff --git a/docs/source/Setup/JAVAChaincode.rst b/docs/source/Setup/JAVAChaincode.rst new file mode 100644 index 00000000000..92f35d4fc47 --- /dev/null +++ b/docs/source/Setup/JAVAChaincode.rst @@ -0,0 +1,175 @@ +Java chaincode +-------------- + +Note: This guide generally assumes you have followed the Chaincode +development environment setup tutorial +`here `__. + +To get started developing Java chaincode +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Ensure you have gradle + +- Download the binary distribution from + http://gradle.org/gradle-download/ +- Unpack, move to the desired location, and add gradle's bin directory + to your system path +- Ensure ``gradle -v`` works from the command-line, and shows version + 2.12 or greater +- Optionally, enable the `gradle + daemon `__ + for faster builds + +2. Ensure you have the Java 1.8 **JDK** installed. Also ensure Java's + directory is on your path with ``java -version`` + +- Additionally, you will need to have the + ```JAVA HOME`` `__ + variable set to your **JDK** installation in your system path + +3. From your command line terminal, move to the ``devenv`` subdirectory + of your workspace environment. Log into a Vagrant terminal by + executing the following command: + + :: + + vagrant ssh + +4. Build and run the peer process. + + :: + + cd $GOPATH/src/github.com/hyperledger/fabric + make peer + peer node start + +5. The following steps is for deploying chaincode in non-dev mode. + + - Deploy the chaincode, + +:: + + peer chaincode deploy -l java -p /opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/java/SimpleSample -c '{"Args": ["init", "a","100", "b", "200"]}' + +``6d9a704d95284593fe802a5de89f84e86fb975f00830bc6488713f9441b835cf32d9cd07b087b90e5cb57a88360f90a4de39521a5595545ad689cd64791679e9`` + +:: + + * This command will give the 'name' for this chaincode, and use this value in all the further commands with the -n (name) parameter + + + * PS. This may take a few minutes depending on the environment as it deploys the chaincode in the container, + +- Invoke a transfer transaction, + +:: + + peer chaincode invoke -l java \ + -n 6d9a704d95284593fe802a5de89f84e86fb975f00830bc6488713f9441b835cf32d9cd07b087b90e5cb57a88360f90a4de39521a5595545ad689cd64791679e9 \ + -c '{"Args": ["transfer", "a", "b", "10"]}' + +``c7dde1d7-fae5-4b68-9ab1-928d61d1e346`` + +- Query the values of a and b after the transfer + +:: + + peer chaincode query -l java \ + -n 6d9a704d95284593fe802a5de89f84e86fb975f00830bc6488713f9441b835cf32d9cd07b087b90e5cb57a88360f90a4de39521a5595545ad689cd64791679e9 \ + -c '{ "Args": ["query", "a"]}' + {"Name":"a","Amount":"80"} + + + peer chaincode query -l java \ + -n 6d9a704d95284593fe802a5de89f84e86fb975f00830bc6488713f9441b835cf32d9cd07b087b90e5cb57a88360f90a4de39521a5595545ad689cd64791679e9 \ + -c '{ "Args": ["query", "b"]}' + {"Name":"b","Amount":"220"} + +Java chaincode deployment in DEV Mode +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Follow the step 1 to 3 as above, +2. Build and run the peer process + + :: + + cd $GOPATH/src/github.com/hyperledger/fabric + make peer + peer node start --peer-chaincodedev + +3. Open the second Vagrant terminal and build the Java shim layer and + publish it to Local Maven Repo + + :: + + cd $GOPATH/src/github.com/hyperledger/fabric/core/chaincode/shim/java + gradle -b build.gradle clean + gradle -b build.gradle build + +4. Change to examples folder to build and run, + + :: + + cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/java/SimpleSample + gradle -b build.gradle build + +5. Run the SimpleSample chaincode using the + ``gradle -b build.gradle run`` + +6. Open the third Vagrant terminal to run init and invoke on the + chaincode + + peer chaincode deploy -l java -n SimpleSample -c '{"Args": ["init", + "a","100", "b", "200"]}' + + :: + + 2016/06/28 19:10:15 Load docker HostConfig: %+v &{[] [] [] [] false map[] [] false [] [] [] [] host { 0} [] { map[]} false [] 0 0 0 false 0 0 0 0 []} + 19:10:15.461 [crypto] main -> INFO 002 Log level recognized 'info', set to INFO + SimpleSample + + peer chaincode invoke -l java -n SimpleSample -c '{"Args": + ["transfer", "a", "b", "10"]}' + +:: + + 2016/06/28 19:11:13 Load docker HostConfig: %+v &{[] [] [] [] false map[] [] false [] [] [] [] host { 0} [] { map[]} false [] 0 0 0 false 0 0 0 0 []} + 19:11:13.553 [crypto] main -> INFO 002 Log level recognized 'info', set to INFO + 978ff89e-e4ef-43da-a9f8-625f2f6f04e5 + +:: + + peer chaincode query -l java -n SimpleSample -c '{ "Args": ["query", "a"]}' + +:: + + 2016/06/28 19:12:19 Load docker HostConfig: %+v &{[] [] [] [] false map[] [] false [] [] [] [] host { 0} [] { map[]} false [] 0 0 0 false 0 0 0 0 []} + 19:12:19.289 [crypto] main -> INFO 002 Log level recognized 'info', set to INFO + {"Name":"a","Amount":"90"} + +:: + + peer chaincode query -l java -n SimpleSample -c '{"Args": ["query", "b"]}' + +:: + + 2016/06/28 19:12:25 Load docker HostConfig: %+v &{[] [] [] [] false map[] [] false [] [] [] [] host { 0} [] { map[]} false [] 0 0 0 false 0 0 0 0 []} + 19:12:25.667 [crypto] main -> INFO 002 Log level recognized 'info', set to INFO + {"Name":"b","Amount":"210"} + +Developing new JAVA chaincode +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Create a new Java project structure. +2. Use existing ``build.grade`` from any example JAVA Chaincode project + like ``examples/chaincode/java/SimpleSample``. +3. Make your main class extend ChaincodeBase class and implement the + following methods from base class. +4. ``public String run(ChaincodeStub stub, String function, String[] args)`` +5. ``public String query(ChaincodeStub stub, String function, String[] args)`` +6. ``public String getChaincodeID()`` +7. Modify the ``mainClassName`` in ``build.gradle`` to point to your new + class. +8. Build this project using ``gradle -b build.gradle build`` +9. Run this chaincode after starting a peer in dev-mode as above using + ``gradle -b build.gradle run`` diff --git a/docs/source/Setup/Network-setup.rst b/docs/source/Setup/Network-setup.rst new file mode 100644 index 00000000000..5cd8458653f --- /dev/null +++ b/docs/source/Setup/Network-setup.rst @@ -0,0 +1,389 @@ +Setting Up a Network +-------------------- + +This document covers setting up a network on your local machine for +various development and testing activities. Unless you are intending to +contribute to the development of the Hyperledger Fabric project, you'll +probably want to follow the more commonly used approach below - +`leveraging published Docker +images <#leveraging-published-docker-images>`__ for the various +Hyperledger Fabric components, directly. Otherwise, skip down to the +`secondary approach <#building-your-own-images>`__ below. + +Leveraging published Docker images +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This approach simply leverages the Docker images that the Hyperledger +Fabric project publishes to +`DockerHub `__ and either Docker +commands or Docker Compose descriptions of the network one wishes to +create. + +Installing Docker +^^^^^^^^^^^^^^^^^ + +**Note:** When running Docker *natively* on Mac and Windows, there is no +IP forwarding support available. Hence, running more than one +fabric-peer image is not advised because you do not want to have +multiple processes binding to the same port. For most application and +chaincode development/testing running with a single fabric peer should +not be an issue unless you are interested in performance and resilience +testing the fabric's capabilities, such as consensus. For more advanced +testing, we strongly recommend using the fabric's Vagrant `development +environment <../dev-setup/devenv.md>`__. + +With this approach, there are multiple choices as to how to run Docker: +using `Docker Toolbox `__ or +one of the new native Docker runtime environments for `Mac +OSX `__ or +`Windows `__. +There are some subtle differences between how Docker runs natively on +Mac and Windows versus in a virtualized context on Linux. We'll call +those out where appropriate below, when we get to the point of actually +running the various components. + +Pulling the images from DockerHub +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Once you have Docker (1.11 or greater) installed and running, prior to +starting any of the fabric components, you will need to first pull the +fabric images from DockerHub. + +:: + + docker pull hyperledger/fabric-peer:latest + docker pull hyperledger/fabric-membersrvc:latest + +Building your own images +~~~~~~~~~~~~~~~~~~~~~~~~ + +**Note:** *This approach is not necessarily recommended for most users*. +If you have pulled images from DockerHub as described in the previous +section, you may proceed to the `next +step <#starting-up-validating-peers>`__. + +The second approach would be to leverage the `development +environment <../dev-setup/devenv.md>`__ setup (which we will assume you +have already established) to build and deploy your own binaries and/or +Docker images from a clone of the +`hyperledger/fabric `__ GitHub +repository. This approach is suitable for developers that might wish to +contribute directly to the Hyperledger Fabric project, or that wish to +deploy from a fork of the Hyperledger code base. + +The following commands should be run from *within* the Vagrant +environment described in `Setting Up Development +Environment <../dev-setup/devenv.md>`__. + +To create the Docker image for the ``hyperledger/fabric-peer``: + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric + make peer-image + +To create the Docker image for the ``hyperledger/fabric-membersrvc``: + +:: + + make membersrvc-image + +Starting up validating peers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Check the available images again with ``docker images``. You should see +``hyperledger/fabric-peer`` and ``hyperledger/fabric-membersrvc`` +images. For example, + +:: + + $ docker images + REPOSITORY TAG IMAGE ID CREATED SIZE + hyperledger/fabric-membersrvc latest 7d5f6e0bcfac 12 days ago 1.439 GB + hyperledger/fabric-peer latest 82ef20d7507c 12 days ago 1.445 GB + +If you don't see these, go back to the previous step. + +With the relevant Docker images in hand, we can start running the peer +and membersrvc services. + +Determine value for CORE\_VM\_ENDPOINT variable +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Next, we need to determine the address of your docker daemon for the +CORE\_VM\_ENDPOINT. If you are working within the Vagrant development +environment, or a Docker Toolbox environment, you can determine this +with the ``ip add`` command. For example, + +:: + + $ ip add + + <<< detail removed >>> + + 3: docker0: mtu 1500 qdisc noqueue state DOWN group default + link/ether 02:42:ad:be:70:cb brd ff:ff:ff:ff:ff:ff + inet 172.17.0.1/16 scope global docker0 + valid_lft forever preferred_lft forever + inet6 fe80::42:adff:febe:70cb/64 scope link + valid_lft forever preferred_lft forever + +Your output might contain something like +``inet 172.17.0.1/16 scope global docker0``. That means the docker0 +interface is on IP address 172.17.0.1. Use that IP address for the +``CORE_VM_ENDPOINT`` option. For more information on the environment +variables, see ``core.yaml`` configuration file in the ``fabric`` +repository. + +If you are using the native Docker for Mac or Windows, the value for +``CORE_VM_ENDPOINT`` should be set to ``unix:///var/run/docker.sock``. +[TODO] double check this. I believe that ``127.0.0.1:2375`` also works. + +Assigning a value for CORE\_PEER\_ID +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ID value of ``CORE_PEER_ID`` must be unique for each validating +peer, and it must be a lowercase string. We often use a convention of +naming the validating peers vpN where N is an integer starting with 0 +for the root node and incrementing N by 1 for each additional peer node +started. e.g. vp0, vp1, vp2, ... + +Consensus +^^^^^^^^^ + +By default, we are using a consensus plugin called ``NOOPS``, which +doesn't really do consensus. If you are running a single peer node, +running anything other than ``NOOPS`` makes little sense. If you want to +use some other consensus plugin in the context of multiple peer nodes, +please see the `Using a Consensus Plugin <#using-a-consensus-plugin>`__ +section, below. + +Docker Compose +^^^^^^^^^^^^^^ + +We'll be using Docker Compose to launch our various Fabric component +containers, as this is the simplest approach. You should have it +installed from the initial setup steps. Installing Docker Toolbox or any +of the native Docker runtimes should have installed Compose. + +Start up a validating peer: +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Let's launch the first validating peer (the root node). We'll set +CORE\_PEER\_ID to vp0 and CORE\_VM\_ENDPOINT as above. Here's the +docker-compose.yml for launching a single container within the +**Vagrant** `development environment <../dev-setup/devenv.md>`__: + +:: + + vp0: + image: hyperledger/fabric-peer + environment: + - CORE_PEER_ID=vp0 + - CORE_PEER_ADDRESSAUTODETECT=true + - CORE_VM_ENDPOINT=http://172.17.0.1:2375 + - CORE_LOGGING_LEVEL=DEBUG + command: peer node start + +You can launch this Compose file as follows, from the same directory as +the docker-compose.yml file: + +:: + + $ docker-compose up + +Here's the corresponding Docker command: + +:: + + $ docker run --rm -it -e CORE_VM_ENDPOINT=http://172.17.0.1:2375 -e CORE_LOGGING_LEVEL=DEBUG -e CORE_PEER_ID=vp0 -e CORE_PEER_ADDRESSAUTODETECT=true hyperledger/fabric-peer peer node start + +If you are running Docker for Mac or Windows, we'll need to explicitly +map the ports, and we will need a different value for CORE\_VM\_ENDPOINT +as we discussed above. + +Here's the docker-compose.yml for Docker on Mac or Windows: + +:: + + vp0: + image: hyperledger/fabric-peer + ports: + - "7050:7050" + - "7051:7051" + - "7052:7052" + environment: + - CORE_PEER_ADDRESSAUTODETECT=true + - CORE_VM_ENDPOINT=unix:///var/run/docker.sock + - CORE_LOGGING_LEVEL=DEBUG + command: peer node start + +This single peer configuration, running the ``NOOPS`` 'consensus' +plugin, should satisfy many development/test scenarios. ``NOOPS`` is not +really providing consensus, it is essentially a no-op that simulates +consensus. For instance, if you are simply developing and testing +chaincode; this should be adequate unless your chaincode is leveraging +membership services for identity, access control, confidentiality and +privacy. + +Running with the CA +^^^^^^^^^^^^^^^^^^^ + +If you want to take advantage of security (authentication and +authorization), privacy and confidentiality, then you'll need to run the +Fabric's certificate authority (CA). Please refer to the `CA +Setup `__ instructions. + +Start up additional validating peers: +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Following the pattern we established +`above <#assigning-a-value-for-core_peer_id>`__ we'll use ``vp1`` as the +ID for the second validating peer. If using Docker Compose, we can +simply link the two peer nodes. Here's the docker-compose.yml for a +**Vagrant** environment with two peer nodes - vp0 and vp1: + +:: + + vp0: + image: hyperledger/fabric-peer + environment: + - CORE_PEER_ADDRESSAUTODETECT=true + - CORE_VM_ENDPOINT=http://172.17.0.1:2375 + - CORE_LOGGING_LEVEL=DEBUG + command: peer node start + vp1: + extends: + service: vp0 + environment: + - CORE_PEER_ID=vp1 + - CORE_PEER_DISCOVERY_ROOTNODE=vp0:7051 + links: + - vp0 + +If we wanted to use the docker command line to launch another peer, we +need to get the IP address of the first validating peer, which will act +as the root node to which the new peer(s) will connect. The address is +printed out on the terminal window of the first peer (e.g. 172.17.0.2) +and should be passed in with the ``CORE_PEER_DISCOVERY_ROOTNODE`` +environment variable. + +:: + + docker run --rm -it -e CORE_VM_ENDPOINT=http://172.17.0.1:2375 -e CORE_PEER_ID=vp1 -e CORE_PEER_ADDRESSAUTODETECT=true -e CORE_PEER_DISCOVERY_ROOTNODE=172.17.0.2:7051 hyperledger/fabric-peer peer node start + +.. raw:: html + + + +Using a Consensus Plugin +~~~~~~~~~~~~~~~~~~~~~~~~ + +A consensus plugin might require some specific configuration that you +need to set up. For example, to use the Practical Byzantine Fault +Tolerant (PBFT) consensus plugin provided as part of the fabric, perform +the following configuration: + +1. In ``core.yaml``, set the ``peer.validator.consensus`` value to + ``pbft`` +2. In ``core.yaml``, make sure the ``peer.id`` is set sequentially as + ``vpN`` where ``N`` is an integer that starts from ``0`` and goes to + ``N-1``. For example, with 4 validating peers, set the ``peer.id`` + to\ ``vp0``, ``vp1``, ``vp2``, ``vp3``. +3. In ``consensus/pbft/config.yaml``, set the ``general.mode`` value to + ``batch`` and the ``general.N`` value to the number of validating + peers on the network, also set ``general.batchsize`` to the number of + transactions per batch. +4. In ``consensus/pbft/config.yaml``, optionally set timer values for + the batch period (``general.timeout.batch``), the acceptable delay + between request and execution (``general.timeout.request``), and for + view-change (``general.timeout.viewchange``) + +See ``core.yaml`` and ``consensus/pbft/config.yaml`` for more detail. + +All of these setting may be overridden via the command line environment +variables, e.g. ``CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=pbft`` or +``CORE_PBFT_GENERAL_MODE=batch`` + +Logging control +~~~~~~~~~~~~~~~ + +See `Logging Control `__ for information on +controlling logging output from the ``peer`` and deployed chaincodes. + +.. raw:: html + + diff --git a/docs/source/Setup/NodeSDK-setup.rst b/docs/source/Setup/NodeSDK-setup.rst new file mode 100644 index 00000000000..aad7218ce3a --- /dev/null +++ b/docs/source/Setup/NodeSDK-setup.rst @@ -0,0 +1,35 @@ +Hyperledger Fabric Client (HFC) SDK for Node.js +----------------------------------------------- + +The Hyperledger Fabric Client (HFC) SDK provides a powerful and easy to +use API to interact with a Hyperledger Fabric blockchain. + +This document assumes that you already have set up a Node.js development +environment. If not, go +`here `__ to download +and install Node.js for your OS. You'll also want the latest version of +``npm`` installed. For that, execute ``sudo npm install npm -g`` to get +the latest version. + +Installing the hfc module +~~~~~~~~~~~~~~~~~~~~~~~~~ + +We publish the ``hfc`` node module to ``npm``. To install ``hfc`` from +npm simply execute the following command: + +:: + + npm install -g hfc + +See `Hyperledger fabric Node.js client +SDK `__ +for more information. + +Hyperledger fabric network +-------------------------- + +First, you'll want to have a running peer node and member services. The +instructions for setting up a network are `here `__. +You may also use the +`Fabric-starter-kit <../starter/fabric-starter-kit.md>`__ that provides +the network. diff --git a/docs/source/Setup/TLSSetup.rst b/docs/source/Setup/TLSSetup.rst new file mode 100644 index 00000000000..a3b05fe1091 --- /dev/null +++ b/docs/source/Setup/TLSSetup.rst @@ -0,0 +1,80 @@ +Steps to enable TLS for all sever (ECA , ACA , TLSCA , TCA) and between ACA client to server communications. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Go to **memebersrvc.yaml** file under the fabric/membersrvc directory + and edit security section, that is: + + :: + + security: + serverhostoverride: + tls_enabled: false + client: + cert: + file: + + To enable TLS between the ACA client and the rest of the CA Services + set the ``tls_enbabled`` flag to ``true``. + +2. Next, set **serverhostoverride** field to match **CN** (Common Name) + of TLS Server certificate. To extract the Common Name from TLS + Server's certificate, for example using OpenSSL, you can use the + following command: + +:: + + openssl x509 -in <`__ for more +information. + +Getting Started +--------------- + +Prerequisites +~~~~~~~~~~~~~ + +- Go 1.7+ installation or later +- **GOPATH** environment variable is set correctly + +Install +~~~~~~~ + +To install the fabric-ca command: + +:: + + # go get github.com/hyperledger/fabric-ca + +The Fabric CA CLI +~~~~~~~~~~~~~~~~~ + +The following shows the fabric-ca CLI usage: + +:: + + # fabric-ca + fabric-ca client - client related commands + fabric-ca server - server related commands + fabric-ca cfssl - all cfssl commands + + For help, type "fabric-ca client", "fabric-ca server", or "fabric-ca cfssl". + +The ``fabric-ca server`` and ``fabric-ca client`` commands are discussed +below. + +If you would like to enable debug-level logging (for server or client), +set the ``FABRIC_CA_DEBUG`` environment variable to ``true``. + +Since fabric-ca is built on top of +`CFSSL `__, the ``fabric-ca cfssl`` +commands are available but are not discussed in this document. See +`CFSSL `__ for more information. + +Fabric CA Server +---------------- + +This section describes the fabric-ca server. + +You must initialize the Fabric CA server before starting it. + +| The fabric-ca server's home directory is determined as follows: +| - if the ``FABRIC_CA_HOME`` environment variable is set, use its + value; +| - otherwise, if the ``HOME`` environment variable is set, use + ``$HOME/fabric-ca``; +| - otherwise, use \`/var/hyperledger/fabric/dev/fabric-ca'. + +For the remainder of this server section, we assume that you have set +the ``FABRIC_CA_HOME`` environment variable to +``$HOME/fabric-ca/server``. + +Initializing the server +^^^^^^^^^^^^^^^^^^^^^^^ + +Initialize the Fabric CA server as follows: + +:: + + # fabric-ca server init CSR-JSON-FILE + +The following is a sample ``CSR-JSON-FILE`` which you can customize as +desired. The "CSR" stands for "Certificate Signing Request". + +If you are going to connect to the fabric-ca server remotely over TLS, +replace "localhost" in the CSR-JSON-FILE below with the hostname where +you will be running your fabric-ca server. + +:: + + { + "CN": "localhost", + "key": { "algo": "ecdsa", "size": 256 }, + "names": [ + { + "O": "Hyperledger Fabric", + "OU": "Fabric CA", + "L": "Raleigh", + "ST": "North Carolina", + "C": "US" + } + ] + } + +All of the fields above pertain to the X.509 certificate which is +generated by the ``fabric server init`` command as follows: + +CSR fields +^^^^^^^^^^ + +- **CN** is the Common Name +- **keys** specifies the algorithm and key size as described below +- **O** is the organization name +- **OU** is the organization unit +- **L** is the location or city +- **ST** is the state +- **C** is the country + +The ``fabric-ca server init`` command generates a self-signed X.509 +certificate. It stores the certificate in the ``server-cert.pem`` file +and the key in the ``server-key.pem`` file in the Fabric CA server's +home directory. + +Algorithms and key sizes +^^^^^^^^^^^^^^^^^^^^^^^^ + + +The CSR-JSON-FILE can be customized to generate X.509 certificates and +keys that support both RSA and Elliptic Curve (ECDSA). The following +setting is an example of the implementation of Elliptic Curve Digital +Signature Algorithm (ECDSA) with curve ``prime256v1`` and signature +algorithm ``ecdsa-with-SHA256``: + +:: + + "key": { + "algo": "ecdsa" + "size": 256 + } + +The choice of algorithm and key size are based on security needs. + +Elliptic Curve (ECDSA) offers the following key size options: + ++--------+--------------+-----------------------+ +| size | ASN1 OID | Signature Algorithm | ++========+==============+=======================+ +| 256 | prime256v1 | ecdsa-with-SHA256 | ++--------+--------------+-----------------------+ +| 384 | secp384r1 | ecdsa-with-SHA384 | ++--------+--------------+-----------------------+ +| 521 | secp521r1 | ecdsa-with-SHA512 | ++--------+--------------+-----------------------+ + +RSA offers the following key size options: + ++--------+------------------+---------------------------+ +| size | Modulus (bits) | Signature Algorithm | ++========+==================+===========================+ +| 2048 | 2048 | sha256WithRSAEncryption | ++--------+------------------+---------------------------+ +| 4096 | 4096 | sha512WithRSAEncryption | ++--------+------------------+---------------------------+ + +Starting the server +^^^^^^^^^^^^^^^^^^^ + +Create a file named ``server-config.json`` as shown below in your +fabric-ca server's home directory (e.g. *$HOME/fabric-ca/server*). + +:: + + { + "tls_disable": false, + "ca_cert": "server-cert.pem", + "ca_key": "server-key.pem", + "driver":"sqlite3", + "data_source":"fabric-ca.db", + "user_registry": { "max_enrollments": 0 }, + "tls": { + "tls_cert": "server-cert.pem", + "tls_key": "server-key.pem" + }, + "users": { + "admin": { + "pass": "adminpw", + "type": "client", + "group": "bank_a", + "attrs": [ + {"name":"hf.Registrar.Roles","value":"client,peer,validator,auditor"}, + {"name":"hf.Registrar.DelegateRoles", "value": "client"} + ] + } + }, + "groups": { + "banks_and_institutions": { + "banks": ["bank_a", "bank_b", "bank_c"], + "institutions": ["institution_a"] + } + }, + "signing": { + "default": { + "usages": ["cert sign"], + "expiry": "8000h", + "ca_constraint": {"is_ca": true} + } + } + } + +Now you may start the Fabric CA server as follows: + +:: + + # cd $FABRIC_CA_HOME + # fabric-ca server start -address '0.0.0.0' -config server-config.json + +To cause the fabric-ca server to listen on ``http`` rather than +``https``, set ``tls_disable`` to ``true`` in the ``server-config.json`` +file. + +To limit the number of times that the same secret (or password) can be +used for enrollment, set the ``max_enrollments`` in the +``server-config.json`` file to the appropriate value. If you set the +value to 1, the fabric-ca server allows passwords to only be used once +for a particular enrollment ID. If you set the value to 0, the fabric-ca +server places no limit on the number of times that a secret can be +reused for enrollment. The default value is 0. + +The fabric-ca server should now be listening on port 7054. + +You may skip to the `Fabric CA Client <#fabric-ca-client>`__ section if +you do not want to configure the fabric-ca server to run in a cluster or +to use LDAP. + +Server database configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This section describes how to configure the fabric-ca server to connect +to Postgres or MySQL databases. The default database is SQLite and the +default database file is ``fabric-ca.db`` in the Fabric CA's home +directory. + +If you don't care about running the fabric-ca server in a cluster, you +may skip this section; otherwise, you must configure either Postgres or +MySQL as described below. + +Postgres +^^^^^^^^ + + +The following sample may be added to the ``server-config.json`` file in +order to connect to a Postgres database. Be sure to customize the +various values appropriately. + +:: + + "driver":"postgres", + "data_source":"host=localhost port=5432 user=Username password=Password dbname=fabric-ca sslmode=verify-full", + +Specifying *sslmode* enables SSL, and a value of *verify-full* means to +verify that the certificate presented by the postgres server was signed +by a trusted CA and that the postgres server's host name matches the one +in the certificate. + +We also need to set the TLS configuration in the fabric-ca server-config +file. If the database server requires client authentication, then a +client cert and key file needs to be provided. The following should be +present in the fabric-ca server config: + +:: + + "tls":{ + ... + "db_client":{ + "ca_certfiles":["CA.pem"], + "client":[{"keyfile":"client-key.pem","certfile":"client-cert.pem"}] + } + }, + +**ca\_certfiles** - The names of the trusted root certificate files. + +**certfile** - Client certificate file. + +**keyfile** - Client key file. + +MySQL +^^^^^ + + +The following sample may be added to the ``server-config.json`` file in +order to connect to a MySQL database. Be sure to customize the various +values appropriately. + +:: + + ... + "driver":"mysql", + "data_source":"root:rootpw@tcp(localhost:3306)/fabric-ca?parseTime=true&tls=custom", + ... + +If connecting over TLS to the MySQL server, the ``tls.db_client`` +section is also required as described in the **Postgres** section above. + +LDAP +^^^^ + +The fabric-ca server can be configured to read from an LDAP server. + +In particular, the fabric-ca server may connect to an LDAP server to do +the following: + +- authenticate a user prior to enrollment, and +- retrieve a user's attribute values which are used for authorization. + +In order to configure the fabric-ca server to connect to an LDAP server, +add a section of the following form to your fabric-ca server's +configuration file: + +:: + + { + "ldap": { + "url": "scheme://adminDN:pass@host[:port][/base]" + "userfilter": "filter" + } + +| where: \* ``scheme`` is one of *ldap* or *ldaps*; \* ``adminDN`` is + the distinquished name of the admin user; \* ``pass`` is the password + of the admin user; +| \* ``host`` is the hostname or IP address of the LDAP server; \* + ``port`` is the optional port number, where default 389 for *ldap* and + 636 for *ldaps*; \* ``base`` is the optional root of the LDAP tree to + use for searches; \* ``filter`` is a filter to use when searching to + convert a login user name to a distinquished name. For example, a + value of ``(uid=%s)`` searches for LDAP entries with the value of a + ``uid`` attribute whose value is the login user name. Similarly, + ``(email=%s)`` may be used to login with an email address. + +The following is a sample configuration section for the default settings +for the OpenLDAP server whose docker image is at +``https://github.com/osixia/docker-openldap``. + +:: + + "ldap": { + "url": "ldap://cn=admin,dc=example,dc=org:admin@localhost:10389/dc=example,dc=org", + "userfilter": "(uid=%s)" + }, + +See ``FABRIC_CA/testdata/testconfig-ldap.json`` for the complete +configuration file with this section. Also see +``FABRIC_CA/scripts/run-ldap-tests`` for a script which starts an +OpenLDAP docker image, configures it, runs the LDAP tests in +FABRIC\_CA/cli/server/ldap/ldap\_test.go, and stops the OpenLDAP server. + +When LDAP is configured, enrollment works as follows: + + +- A fabric-ca client or client SDK sends an enrollment request with a + basic authorization header. +- The fabric-ca server receives the enrollment request, decodes the + user/pass in the authorization header, looks up the DN (Distinquished + Name) associated with the user using the "userfilter" from the + configuration file, and then attempts an LDAP bind with the user's + password. If successful, the enrollment processing is authorized and + can proceed. + +When LDAP is configured, attribute retrieval works as follows: + + +- A client SDK sends a request for a batch of tcerts **with one or more + attributes** to the fabric-ca server. +- The fabric-ca server receives the tcert request and does as follows: + + - extracts the enrollment ID from the token in the authorization + header (after validating the token); + - does an LDAP search/query to the LDAP server, requesting all of + the attribute names received in the tcert request; + - the attribute values are placed in the tcert as normal + +Setting up a cluster of fabric-ca servers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You may use any IP sprayer to load balance to a cluster of fabric-ca +servers. This section provides an example of how to set up Haproxy to +route to a fabric-ca server cluster. Be sure to change hostname and port +to reflect the settings of your fabric-ca servers. + +haproxy.conf + +:: + + global + maxconn 4096 + daemon + + defaults + mode http + maxconn 2000 + timeout connect 5000 + timeout client 50000 + timeout server 50000 + + listen http-in + bind *:7054 + balance roundrobin + server server1 hostname1:port + server server2 hostname2:port + server server3 hostname3:port + +Fabric CA Client +---------------- + +This section describes how to use the fabric-ca client. + +The default fabric-ca client's home directory is ``$HOME/fabric-ca``, +but this can be changed by setting the ``FABRIC_CA_HOME`` environment +variable. + +You must create a file named **client-config.json** in the fabric-ca +client's home directory. The following is a sample client-config.json +file: + +:: + + { + "ca_certfiles":["server-cert.pem"], + "signing": { + "default": { + "usages": ["cert sign"], + "expiry": "8000h" + } + } + } + +You must also copy the server's certificate into the client's home +directory. In the examples in this document, the server's certificate is +at ``$HOME/fabric-ca/server/server-cert.pem``. The file name must match +the name in the *client-config.json* file. + +Enroll the bootstrap user +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Unless the fabric-ca server is configured to use LDAP, it must be +configured with at least one pre-registered bootstrap user. In the +previous server-config.json in this document, that user has an +enrollment ID of *admin* with an enrollment secret of *adminpw*. + + First, create a CSR (Certificate Signing Request) JSON file similar to +the following. Customize it as desired. + +:: + + { + "key": { "algo": "ecdsa", "size": 256 }, + "names": [ + { + "O": "Hyperledger Fabric", + "OU": "Fabric CA", + "L": "Raleigh", + "ST": "North Carolina", + "C": "US" + } + ] + } + +See `CSR fields <#csr-fields>`__ for a description of the fields in this +file. When enrolling, the CN (Common Name) field is automatically set to +the enrollment ID which is *admin* in this example, so it can be omitted +from the csr.json file. + +The following command enrolls the admin user and stores an enrollment +certificate (ECert) in the fabric-ca client's home directory. + +:: + + # export FABRIC_CA_HOME=$HOME/fabric-ca/clients/admin + # fabric-ca client enroll -config client-config.json admin adminpw http://localhost:7054 csr.json + +You should see a message similar to +``[INFO] enrollment information was successfully stored in`` which +indicates where the certificate and key files were stored. + +The enrollment certificate is stored at +``$FABRIC_CA_ENROLLMENT_DIR/cert.pem`` by default, but a different path +can be specified by setting the ``FABRIC_CA_CERT_FILE`` environment +variable. + +The enrollment key is stored at ``$FABRIC_CA_ENROLLMENT_DIR/key.pem`` by +default, but a different path can be specified by setting the +``FABRIC_CA_KEY_FILE`` environment variable. + +If ``FABRIC_CA_ENROLLMENT_DIR`` is not set, the value of the +``FABRIC_CA_HOME`` environment variable is used in its place. + +Register a new identity +^^^^^^^^^^^^^^^^^^^^^^^ + +The user performing the register request must be currently enrolled, and +must also have the proper authority to register the type of user being +registered. + +In particular, the invoker's identity must have been registered with the +attribute "hf.Registrar.Roles". This attribute specifies the types of +identities that the registrar is allowed to register. + +For example, the attributes for a registrar might be as follows, +indicating that this registrar identity can register peer, application, +and user identities. + +:: + + "attrs": [{"name":"hf.Registrar.Roles", "value":"peer,app,user"}] + +To register a new identity, you must first create a JSON file similar to +the one below which defines information for the identity being +registered. This is a sample of registration information for a peer. + +:: + + { + "id": "peer1", + "type": "peer", + "group": "bank_a", + "attrs": [{"name":"SomeAttrName","value":"SomeAttrValue"}] + } + +The **id** field is the enrollment ID of the identity. + +The **type** field is the type of the identity: orderer, peer, app, or +user. + +The **group** field must be a valid group name as found in the +*server-config.json* file. + +The **attrs** field is optional and is not required for a peer, but is +shown here as example of how you associate attributes with any identity. + +Assuming you store the information above in a file named +**register.json**, the following command uses the **admin** user's +credentials to register the **peer1** identity. + +:: + + # export FABRIC_CA_HOME=$HOME/fabric-ca/clients/admin + # cd $FABRIC_CA_HOME + # fabric-ca client register -config client-config.json register.json http://localhost:7054 + +The output of a successful *fabric-ca client register* command is a +password similar to ``One time password: gHIexUckKpHz``. Make a note of +your password to use in the following section to enroll a peer. + +Enrolling a peer identity +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Now that you have successfully registered a peer identity, you may now +enroll the peer given the enrollment ID and secret (i.e. the *password* +from the previous section). + +First, create a CSR (Certificate Signing Request) JSON file similar to +the one described in the `Enrolling the bootstrap +user <#EnrollBootstrap>`__ section. Name the file *csr.json* for the +following example. + +This is similar to enrolling the bootstrap user except that we also +demonstrate how to use environment variables to place the key and +certificate files in a specific location. The following example shows +how to place them into a Hyperledger Fabric MSP (Membership Service +Provider) directory structure. The *MSP\_DIR* environment variable +refers to the root directory of MSP in Hyperledger Fabric and the +$MSP\_DIR/signcerts and $MSP\_DIR/keystore directories must exist. + +Also note that you must replace ** with the secret which was +returned from the registration in the previous section. + +:: + + # export FABRIC_CA_CERT_FILE=$MSP_DIR/signcerts/peer.pem + # export FABRIC_CA_KEY_FILE=$MSP_DIR/keystore/key.pem + # fabric-ca client enroll -config client-config.json peer1 https://localhost:7054 csr.json + +The peer.pem and key.pem files should now exist at the locations +specified by the environment variables. + +Revoke a certificate or user +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In order to revoke a certificate or user, the calling identity must have +the ``hf.Revoker`` attribute. + +You may revoke a specific certificate by specifying its AKI (Authority +Key Identifier) and its serial number, as shown below. + +:: + + fabric-ca client revoke -config client-config.json -aki xxx -serial yyy -reason "you're bad" https://localhost:7054 + +The following command disables a user's identity and also revokes all of +the certificates associated with the identity. All future requests +received by the fabric-ca server from this identity will be rejected. + +:: + + fabric-ca client revoke -config client-config.json https://localhost:7054 ENROLLMENT-ID -reason "you're really bad" + +Enabling TLS for a fabric-ca client +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This section describes in more detail how to configure TLS for a +fabric-ca client. + +The following sections may be configured in the ``client-config.json``. + +:: + + { + "ca_certfiles":["CA_root_cert.pem"], + "client":[{"keyfile":"client-key.pem","certfile":"client-cert.pem"}] + } + +The **ca\_certfiles** option is the set of root certificates trusted by +the client. This will typically just be the root fabric-ca server's +certificate found in the server's home directory in the +**server-cert.pem** file. + +The **client** option is required only if mutual TLS is configured on +the server. + +Appendix +-------- + +Postgres SSL Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Basic instructions for configuring SSL on Postgres server:** 1. In +postgresql.conf, uncomment SSL and set to "on" (SSL=on) 2. Place +Certificate and Key files Postgress data directory. + +Instructions for generating self-signed certificates for: +https://www.postgresql.org/docs/9.1/static/ssl-tcp.html + +Note: Self-signed certificates are for testing purposes and should not +be used in a production environment + +**Postgres Server - Require Client Certificates** 1. Place certificates +of the certificate authorities (CAs) you trust in the file root.crt in +the Postgres data directory 2. In postgresql.conf, set "ssl\_ca\_file" +to point to the root cert of client (CA cert) 3. Set the clientcert +parameter to 1 on the appropriate hostssl line(s) in pg\_hba.conf. + +For more details on configuring SSL on the Postgres server, please refer +to the following Postgres documentation: +https://www.postgresql.org/docs/9.4/static/libpq-ssl.html + +MySQL SSL Configuration +~~~~~~~~~~~~~~~~~~~~~~~ + +**Basic instructions for configuring SSL on MySQL server:** + +1. Open or create my.cnf file for the server. Add or un-comment the + lines below in [mysqld] section. These should point to the key and + certificates for the server, and the root CA cert. + +Instruction on creating server and client side certs: +http://dev.mysql.com/doc/refman/5.7/en/creating-ssl-files-using-openssl.html + +[mysqld] ssl-ca=ca-cert.pem ssl-cert=server-cert.pem +ssl-key=server-key.pem + +Can run the following query to confirm SSL has been enabled. + +mysql> SHOW GLOBAL VARIABLES LIKE 'have\_%ssl'; + +Should see: + +``+---------------+-------+ | Variable_name | Value | +---------------+-------+ | have_openssl | YES | | have_ssl | YES | +---------------+-------+`` + +2. After the server-side SSL configuration is finished, the next step is + to create a user who has a privilege to access the MySQL server over + SSL. For that, log in to the MySQL server, and type: + +mysql> GRANT ALL PRIVILEGES ON *.* TO 'ssluser'@'%' IDENTIFIED BY +'password' REQUIRE SSL; mysql> FLUSH PRIVILEGES; + +If you want to give a specific ip address from which the user will +access the server change the '%' to the specific ip address. + +**MySQL Server - Require Client Certificates** Options for secure +connections are similar to those used on the server side. + +- ssl-ca identifies the Certificate Authority (CA) certificate. This + option, if used, must specify the same certificate used by the + server. +- ssl-cert identifies the client public key certificate. +- ssl-key identifies the client private key. + +Suppose that you want to connect using an account that has no special +encryption requirements or was created using a GRANT statement that +includes the REQUIRE SSL option. As a recommended set of +secure-connection options, start the MySQL server with at least +--ssl-cert and --ssl-key, and invoke the fabric-ca server with +**ca\_certfiles** option set in the fabric-ca server file. + +To require that a client certificate also be specified, create the +account using the REQUIRE X509 option. Then the client must also specify +the proper client key and certificate files or the MySQL server will +reject the connection. CA cert, client cert, and client key are all +required for the fabric-ca server. diff --git a/docs/source/Setup/logging-control.rst b/docs/source/Setup/logging-control.rst new file mode 100644 index 00000000000..26050f4d64e --- /dev/null +++ b/docs/source/Setup/logging-control.rst @@ -0,0 +1,204 @@ +Logging Control +=============== + +Overview +-------- + +Logging in the ``peer`` application and in the ``shim`` interface to +chaincodes is programmed using facilities provided by the +``github.com/op/go-logging`` package. This package supports + +- Logging control based on the severity of the message +- Logging control based on the software *module* generating the message +- Different pretty-printing options based on the severity of the + message + +All logs are currently directed to ``stderr``, and the pretty-printing +is currently fixed. However global and module-level control of logging +by severity is provided for both users and developers. There are +currently no formalized rules for the types of information provided at +each severity level, however when submitting bug reports the developers +may want to see full logs down to the DEBUG level. + +In pretty-printed logs the logging level is indicated both by color and +by a 4-character code, e.g, "ERRO" for ERROR, "DEBU" for DEBUG, etc. In +the logging context a *module* is an arbitrary name (string) given by +developers to groups of related messages. In the pretty-printed example +below, the logging modules "peer", "rest" and "main" are generating +logs. + +:: + + 16:47:09.634 [peer] GetLocalAddress -> INFO 033 Auto detected peer address: 9.3.158.178:7051 + 16:47:09.635 [rest] StartOpenchainRESTServer -> INFO 035 Initializing the REST service... + 16:47:09.635 [main] serve -> INFO 036 Starting peer with id=name:"vp1" , network id=dev, address=9.3.158.178:7051, discovery.rootnode=, validator=true + +An arbitrary number of logging modules can be created at runtime, +therefore there is no "master list" of modules, and logging control +constructs can not check whether logging modules actually do or will +exist. Also note that the logging module system does not understand +hierarchy or wildcarding: You may see module names like "foo/bar" in the +code, but the logging system only sees a flat string. It doesn't +understand that "foo/bar" is related to "foo" in any way, or that +"foo/\*" might indicate all "submodules" of foo. + +peer +---- + +The logging level of the ``peer`` command can be controlled from the +command line for each invocation using the ``--logging-level`` flag, for +example + +:: + + peer node start --logging-level=debug + +The default logging level for each individual ``peer`` subcommand can +also be set in the +`core.yaml `__ +file. For example the key ``logging.node`` sets the default level for +the ``node`` subcommmand. Comments in the file also explain how the +logging level can be overridden in various ways by using environment +varaibles. + +Logging severity levels are specified using case-insensitive strings +chosen from + +:: + + CRITICAL | ERROR | WARNING | NOTICE | INFO | DEBUG + +The full logging level specification for the ``peer`` is of the form + +:: + + [[,...]=][:[[,...]=]...] + +A logging level by itself is taken as the overall default. Otherwise, +overrides for individual or groups of modules can be specified using the + +:: + + [,...]= + +syntax. Examples of specifications (valid for all of +``--logging-level``, environment variable and +`core.yaml `__ +settings): + +:: + + info - Set default to INFO + warning:main,db=debug:chaincode=info - Default WARNING; Override for main,db,chaincode + chaincode=info:main=debug:db=debug:warning - Same as above + +Go chaincodes +------------- + +The standard mechanism to log within a chaincode application is to +integrate with the logging transport exposed to each chaincode instance +via the peer. The chaincode ``shim`` package provides APIs that allow a +chaincode to create and manage logging objects whose logs will be +formatted and interleaved consistently with the ``shim`` logs. + +As independently executed programs, user-provided chaincodes may +technically also produce output on stdout/stderr. While naturally useful +for "devmode", these channels are normally disabled on a production +network to mitigate abuse from broken or malicious code. However, it is +possible to enable this output even for peer-managed containers (e.g. +"netmode") on a per-peer basis via the +CORE\_VM\_DOCKER\_ATTACHSTDOUT=true configuration option. + +Once enabled, each chaincode will receive its own logging channel keyed +by its container-id. Any output written to either stdout or stderr will +be integrated with the peer's log on a per-line basis. It is not +recommended to enable this for production. + +API +~~~ + +``NewLogger(name string) *ChaincodeLogger`` - Create a logging object +for use by a chaincode + +``(c *ChaincodeLogger) SetLevel(level LoggingLevel)`` - Set the logging +level of the logger + +``(c *ChaincodeLogger) IsEnabledFor(level LoggingLevel) bool`` - Return +true if logs will be generated at the given level + +``LogLevel(levelString string) (LoggingLevel, error)`` - Convert a +string to a ``LoggingLevel`` + +A ``LoggingLevel`` is a member of the enumeration + +:: + + LogDebug, LogInfo, LogNotice, LogWarning, LogError, LogCritical + +which can be used directly, or generated by passing a case-insensitive +version of the strings + +:: + + DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL + +to the ``LogLevel`` API. + +Formatted logging at various severity levels is provided by the +functions + +:: + + (c *ChaincodeLogger) Debug(args ...interface{}) + (c *ChaincodeLogger) Info(args ...interface{}) + (c *ChaincodeLogger) Notice(args ...interface{}) + (c *ChaincodeLogger) Warning(args ...interface{}) + (c *ChaincodeLogger) Error(args ...interface{}) + (c *ChaincodeLogger) Critical(args ...interface{}) + + (c *ChaincodeLogger) Debugf(format string, args ...interface{}) + (c *ChaincodeLogger) Infof(format string, args ...interface{}) + (c *ChaincodeLogger) Noticef(format string, args ...interface{}) + (c *ChaincodeLogger) Warningf(format string, args ...interface{}) + (c *ChaincodeLogger) Errorf(format string, args ...interface{}) + (c *ChaincodeLogger) Criticalf(format string, args ...interface{}) + +The ``f`` forms of the logging APIs provide for precise control over the +formatting of the logs. The non-\ ``f`` forms of the APIs currently +insert a space between the printed representations of the arguments, and +arbitrarily choose the formats to use. + +In the current implementation, the logs produced by the ``shim`` and a +``ChaincodeLogger`` are timestamped, marked with the logger *name* and +severity level, and written to ``stderr``. Note that logging level +control is currently based on the *name* provided when the +``ChaincodeLogger`` is created. To avoid ambiguities, all +``ChaincodeLogger`` should be given unique names other than "shim". The +logger *name* will appear in all log messages created by the logger. The +``shim`` logs as "shim". + +Go language chaincodes can also control the logging level of the +chaincode ``shim`` interface through the ``SetLoggingLevel`` API. + +``SetLoggingLevel(LoggingLevel level)`` - Control the logging level of +the shim + +The default logging level for the shim is ``LogDebug``. + +Below is a simple example of how a chaincode might create a private +logging object logging at the ``LogInfo`` level, and also control the +amount of logging provided by the ``shim`` based on an environment +variable. + +:: + + var logger = shim.NewLogger("myChaincode") + + func main() { + + logger.SetLevel(shim.LogInfo) + + logLevel, _ := shim.LogLevel(os.Getenv("SHIM_LOGGING_LEVEL")) + shim.SetLoggingLevel(logLevel) + ... + } diff --git a/docs/source/Style-guides/go-style.rst b/docs/source/Style-guides/go-style.rst new file mode 100644 index 00000000000..e2b9d708b23 --- /dev/null +++ b/docs/source/Style-guides/go-style.rst @@ -0,0 +1,54 @@ +Coding guidelines +----------------- + +Coding Golang +~~~~~~~~~~~~~~ + +We code in Go™ and strictly follow the `best +practices `__ and will not +accept any deviations. You must run the following tools against your Go +code and fix all errors and warnings: - +`golint `__ - `go +vet `__ - +`goimports `__ + +Generating gRPC code +--------------------- + +If you modify any ``.proto`` files, run the following command to +generate/update the respective ``.pb.go`` files. + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric + make protos + +Adding or updating Go packages +------------------------------ + +The Hyperledger Fabric Project uses Go 1.6 vendoring for package +management. This means that all required packages reside in the +``vendor`` folder within the fabric project. Go will use packages in +this folder instead of the GOPATH when the ``go install`` or +``go build`` commands are executed. To manage the packages in the +``vendor`` folder, we use +`Govendor `__, which is installed +in the Vagrant environment. The following commands can be used for +package management: + +:: + + # Add external packages. + govendor add +external + + # Add a specific package. + govendor add github.com/kardianos/osext + + # Update vendor packages. + govendor update +vendor + + # Revert back to normal GOPATH packages. + govendor remove +vendor + + # List package. + govendor list diff --git a/docs/source/SystemChaincode-noop.rst b/docs/source/SystemChaincode-noop.rst new file mode 100644 index 00000000000..ff5bc8e0399 --- /dev/null +++ b/docs/source/SystemChaincode-noop.rst @@ -0,0 +1,28 @@ +NO-OP system chaincode +~~~~~~~~~~~~~~~~~~~~~~ + +NO-OP is a system chaincode that does nothing when invoked. The +parameters of the invoke transaction are stored on the ledger so it is +possible to encode arbitrary data into them. + +Functions and valid options +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Invoke transactions have to be called with *'execute'* as function + name and at least one argument. Only the **first argument** is used. + Note that it should be **encoded with BASE64**. +- Only one type of query is supported: *'getTran'* (passed as a + function name). GetTran has to get a transaction ID as argument in + hexadecimal format. The function looks up the corresponding + transaction's (if any) **first argument** and tries to **decode it as + a BASE64 encoded string**. + +Testing +^^^^^^^ + +NO-OP has unit tests checking invocation and queries using +proper/improper arguments. The chaincode implementation provides a +facility for mocking the ledger under the chaincode (*mockLedgerH* in +struct *chaincode.SystemChaincode*). This should only be used for +testing as it is dangerous to rely on global variables in memory that +can hold state across invokes. diff --git a/docs/source/_static/css/custom.css b/docs/source/_static/css/custom.css new file mode 100644 index 00000000000..30b283debeb --- /dev/null +++ b/docs/source/_static/css/custom.css @@ -0,0 +1,181 @@ +@import "theme.css"; + +/* Highlights */ + +.highlight .k, +.highlight .kd { + color: #263673; +} + + +/* Text */ + +body, +h1, +h2, +.rst-content .toctree-wrapper p.caption, +h3, +h4, +h5, +h6, +legend, +input { + color: #010101; + letter-spacing: 0.3px +} + +p { + font-size: 100%; /* Get rid of RTD rule that assumes nobody changes their browser font size */ +} + + +/* Links */ + +a { + color: #263673 +} + +a:hover { + color: #005CAB +} + +a:visited { + color: #ADAFB3 +} + + +/* Side navigation bar */ + +.wy-side-nav-search { + background-color: #252627; +} + +.wy-side-nav-search a.icon-home { + color: transparent; + background-image: url('../images/fabric1.png'); + background-repeat: no-repeat; + background-size: Auto 20px; + background-position: center top; + background-origin: content box; + height: 20px; + width: 100% +} + +.wy-side-nav-search input[type=text] { + border-radius: 5px +} + +.wy-menu-vertical a:hover { + background-color: #ADAFB3; + color: #FFF +} + +.wy-nav-content { + background-color: #fff max-width: 1000px; +} + +.wy-nav-side { + background-color: #252627; +} + + +/* Navigation headers */ + +.rst-content tt.literal, +.rst-content tt.literal, +.rst-content code.literal { + color: ##d43232; + text-transform: none; +} + +.wy-menu-vertical header, +.wy-menu-vertical p.caption { + color: #6ca158; +} + + +/* Code snippets */ + +.codesnippet-widgets { + min-width: 100%; + display: block; + background: #005CAB; + color: white; + padding: 10px 0; + margin: 0 0 -1px 0; +} + +.codesnippet-widgets > span { + padding: 10px; + cursor: pointer; +} + +.codesnippet-widgets > .current { + background: #263673; +} + +.codeset > .highlight-java { + display: none; +} + + +/* Notification boxes */ + +.wy-alert.wy-alert-warning .wy-alert-title, +.rst-content .wy-alert-warning.note .wy-alert-title, +.rst-content .attention .wy-alert-title, +.rst-content .caution .wy-alert-title, +.rst-content .wy-alert-warning.danger .wy-alert-title, +.rst-content .wy-alert-warning.error .wy-alert-title, +.rst-content .wy-alert-warning.hint .wy-alert-title, +.rst-content .wy-alert-warning.important .wy-alert-title, +.rst-content .wy-alert-warning.tip .wy-alert-title, +.rst-content .warning .wy-alert-title, +.rst-content .wy-alert-warning.seealso .wy-alert-title, +.rst-content .admonition-todo .wy-alert-title, +.wy-alert.wy-alert-warning .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-warning .admonition-title, +.rst-content .wy-alert-warning.note .admonition-title, +.rst-content .attention .admonition-title, +.rst-content .caution .admonition-title, +.rst-content .wy-alert-warning.danger .admonition-title, +.rst-content .wy-alert-warning.error .admonition-title, +.rst-content .wy-alert-warning.hint .admonition-title, +.rst-content .wy-alert-warning.important .admonition-title, +.rst-content .wy-alert-warning.tip .admonition-title, +.rst-content .warning .admonition-title, +.rst-content .wy-alert-warning.seealso .admonition-title, +.rst-content .admonition-todo .admonition-title { + background-color: #263673 +} + +.wy-alert, +.rst-content .note, +.rst-content .attention, +.rst-content .caution, +.rst-content .danger, +.rst-content .error, +.rst-content .hint, +.rst-content .important, +.rst-content .tip, +.rst-content .warning, +.rst-content .seealso, +.rst-content .admonition-todo { + background-color: #d9e5ef +} + + +/* Mobile view */ + +.wy-nav-top { + background-color: #252627; +} + +.wy-nav-top a { + color: transparent; + background-image: url('../images/fabric1.png'); + background-repeat: no-repeat; + background-size: Auto 19px; + background-position: center top; + background-origin: content box; +} diff --git a/docs/source/_templates/layout.html b/docs/source/_templates/layout.html new file mode 100644 index 00000000000..a8d56182d94 --- /dev/null +++ b/docs/source/_templates/layout.html @@ -0,0 +1,7 @@ +{% extends "!layout.html" %} +{% block sidebartitle %} +{{ super() }} +
+Rocket Chat CI +StackOverflow +{% endblock %} diff --git a/docs/source/abstract_v1.rst b/docs/source/abstract_v1.rst new file mode 100644 index 00000000000..a10c98c77b9 --- /dev/null +++ b/docs/source/abstract_v1.rst @@ -0,0 +1,108 @@ +HYPERLEDGER FABRIC v1.0 +======================= + +Hyperledger Fabric is a platform that enables the delivery of a secure, +robust, permissioned blockchain for the enterprise that incorporates a +byzantine fault tolerant consensus. We have learned much as we +progressed through the v0.6-preview release. In particular, that in +order to provide for the scalability and confidentiality needs of many +use cases, a refactoring of the architecture was needed. The +v0.6-preview release will be the final (barring any bug fixes) release +based upon the original architecture. + +Hyperledger Fabric's v1.0 architecture has been designed to address two +vital enterprise-grade requirements – **security** and **scalability**. +Businesses and organizations can leverage this new architecture to +execute confidential transactions on networks with shared or common +assets – e.g. supply chain, FOREX market, healthcare, etc. The +progression to v1.0 will be incremental, with myriad windows for +community members to contribute code and start curating the fabric to +fit specific business needs. + +WHERE WE ARE: +------------- + +The current implementation involves every validating peer shouldering +the responsibility for the full gauntlet of network functionality. They +execute transactions, perform consensus, and maintain the shared ledger. +Not only does this configuration lay a huge computational burden on each +peer, hindering scalability, but it also constricts important facets of +privacy and confidentiality. Namely, there is no mechanism to “channel” +or “silo” confidential transactions. Every peer can see the most minute, +and at times, sensitive details and logic of every transaction. This is +untenable for many enterprise businesses, who must abide by stringent +regulatory statutes. + +WHERE WE'RE GOING +----------------- + +| The new architecture introduces a clear functional separation of peer + roles, and allows a transaction to pass through the network in a + structured and modularized fashion. +| The peers are diverged into two distinct roles – Endorser & Committer. + As an endorser, the peer will simulate the transaction and ensure that + the outcome is both deterministic and stable. As a committer, the peer + will validate the integrity of a transaction and then append to the + ledger. Now confidential transactions can be sent to specific + endorsers and their correlating committers, without the broader + network being made cognizant of the transaction. Additionally, + policies can be set to determine what levels of “endorsement” and + “validation” are acceptable for a specific class of transactions. +| A failure to meet these thresholds would simply result in a + transaction being withdrawn or labeled as "invalid", rather than + imploding or stagnating the entire network. +| This new model also introduces the possibility for more elaborate + networks, such as a foreign exchange market. For example, trade + settlement might be contingent upon a mandatory "endorsement" from a + trusted third party (e.g. a clearing house). + +| The consensus or "ordering" process (i.e. algorithmic computation) is + entirely abstracted from the peer. This modularity not only provides a + powerful security layer – the ordering nodes are agnostic to the + transaction logic – but it also generates a framework where ordering + can become a pluggable implementation and scalability can truly occur. +| There is no longer a parallel relationship between the number of peers + in a network and the number of orderers. Now networks can grow + dynamically (i.e. add endorsers and committers) without having to add + corresponding orderers, all the while existing in a modular + infrastructure designed to support high transaction throughput. + Moreover, networks now have the capability to completely liberate + themselves from the computational and legal burden of ordering by + tapping into a pre-existing or third party-hosted "ordering service." + +As v1.0 manifests, we will see the foundation for interoperable +blockchain networks that have the ability to scale and transact in a +manner adherent with regulatory and industry standards. Watch how fabric +v1.0 and the Hyperledger Project are building a true blockchain for +business - + +|HYPERLEDGERv1.0\_ANIMATION| + +HOW TO CONTRIBUTE +----------------- + +Use the following links to explore upcoming additions to the codebase +that will spawn the capabilities in v1.0: + +- Familiarize yourself with the `guidelines for code + contributions `__ to this project. **Note**: In + order to participate in the development of the Hyperledger Fabric + project, you will need an `LF account `__. This + will give you single sign-on to JIRA and Gerrit. +- Explore the design document for the new + `architecture `__ +- Explore design docs for the various `Fabric + components `__ +- Explore `JIRA `__ + for open Hyperledger Fabric issues. +- Explore the + `JIRA `__ backlog + for upcoming Hyperledger Fabric issues. +- Explore `JIRA `__ + for Hyperledger Fabric issues tagged with "help wanted." +- Explore the `source code `__ +- Explore the + `documentation `__ + +.. |HYPERLEDGERv1.0\_ANIMATION| image:: http://img.youtube.com/vi/EKa5Gh9whgU/0.jpg + :target: http://www.youtube.com/watch?v=EKa5Gh9whgU diff --git a/docs/source/adminops.rst b/docs/source/adminops.rst new file mode 100644 index 00000000000..4baf9c99a6f --- /dev/null +++ b/docs/source/adminops.rst @@ -0,0 +1,4 @@ +Administration and operations +============================= + +[WIP] ...coming soon diff --git a/docs/source/arch-deep-dive.rst b/docs/source/arch-deep-dive.rst new file mode 100644 index 00000000000..b18ed07b2c8 --- /dev/null +++ b/docs/source/arch-deep-dive.rst @@ -0,0 +1,832 @@ +Architecture Explained +====================== + +The v1 architecture delivers the following advantages: + +- **Chaincode trust flexibility.** The architecture separates *trust + assumptions* for chaincodes (blockchain applications) from trust + assumptions for ordering. In other words, the ordering service may be + provided by one set of nodes (orderers) and tolerate some of them to + fail or misbehave, and the endorsers may be different for each + chaincode. + +- **Scalability.** As the endorser nodes responsible for particular + chaincode are orthogonal to the orderers, the system may *scale* + better than if these functions were done by the same nodes. In + particular, this results when different chaincodes specify disjoint + endorsers, which introduces a partitioning of chaincodes between + endorsers and allows parallel chaincode execution (endorsement). + Besides, chaincode execution, which can potentially be costly, is + removed from the critical path of the ordering service. + +- **Confidentiality.** The architecture facilitates deployment of + chaincodes that have *confidentiality* requirements with respect to + the content and state updates of its transactions. + +- **Consensus modularity.** The architecture is *modular* and allows + pluggable consensus (i.e., ordering service) implementations. + +**Part I: Elements of the architecture relevant to Hyperledger Fabric +v1** + +1. System architecture +2. Basic workflow of transaction endorsement +3. Endorsement policies + + **Part II: Post-v1 elements of the architecture** + +4. Ledger checkpointing (pruning) + +1. System architecture +---------------------- + +The blockchain is a distributed system consisting of many nodes that +communicate with each other. The blockchain runs programs called +chaincode, holds state and ledger data, and executes transactions. The +chaincode is the central element as transactions are operations invoked +on the chaincode. Transactions have to be "endorsed" and only endorsed +transactions may be committed and have an effect on the state. There may +exist one or more special chaincodes for management functions and +parameters, collectively called *system chaincodes*. + +1.1. Transactions +~~~~~~~~~~~~~~~~~ + +Transactions may be of two types: + +- *Deploy transactions* create new chaincode and take a program as + parameter. When a deploy transaction executes successfully, the + chaincode has been installed "on" the blockchain. + +- *Invoke transactions* perform an operation in the context of + previously deployed chaincode. An invoke transaction refers to a + chaincode and to one of its provided functions. When successful, the + chaincode executes the specified function - which may involve + modifying the corresponding state, and returning an output. + +As described later, deploy transactions are special cases of invoke +transactions, where a deploy transaction that creates new chaincode, +corresponds to an invoke transaction on a system chaincode. + +**Remark:** *This document currently assumes that a transaction either +creates new chaincode or invokes an operation provided by *one* already +deployed chaincode. This document does not yet describe: a) +optimizations for query (read-only) transactions (included in v1), b) +support for cross-chaincode transactions (post-v1 feature).* + +1.2. Blockchain datastructures +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1.2.1. State +^^^^^^^^^^^^ + +The latest state of the blockchain (or, simply, *state*) is modeled as a +versioned key/value store (KVS), where keys are names and values are +arbitrary blobs. These entries are manipulated by the chaincodes +(applications) running on the blockchain through ``put`` and ``get`` +KVS-operations. The state is stored persistently and updates to the +state are logged. Notice that versioned KVS is adopted as state model, +an implementation may use actual KVSs, but also RDBMSs or any other +solution. + +More formally, state ``s`` is modeled as an element of a mapping +``K -> (V X N)``, where: + +- ``K`` is a set of keys +- ``V`` is a set of values +- ``N`` is an infinite ordered set of version numbers. Injective + function ``next: N -> N`` takes an element of ``N`` and returns the + next version number. + +Both ``V`` and ``N`` contain a special element ``\bot``, which is in +case of ``N`` the lowest element. Initially all keys are mapped to +``(\bot,\bot)``. For ``s(k)=(v,ver)`` we denote ``v`` by ``s(k).value``, +and ``ver`` by ``s(k).version``. + +KVS operations are modeled as follows: + +- ``put(k,v)``, for ``k\in K`` and ``v\in V``, takes the blockchain + state ``s`` and changes it to ``s'`` such that + ``s'(k)=(v,next(s(k).version))`` with ``s'(k')=s(k')`` for all + ``k'!=k``. +- ``get(k)`` returns ``s(k)``. + +State is maintained by peers, but not by orderers and clients. + +**State partitioning.** Keys in the KVS can be recognized from their +name to belong to a particular chaincode, in the sense that only +transaction of a certain chaincode may modify the keys belonging to this +chaincode. In principle, any chaincode can read the keys belonging to +other chaincodes. *Support for cross-chaincode transactions, that modify +the state belonging to two or more chaincodes is a post-v1 feature.* + +1.2.2 Ledger +^^^^^^^^^^^^ + +Ledger provides a verifiable history of all successful state changes (we +talk about *valid* transactions) and unsuccessful attempts to change +state (we talk about *invalid* transactions), occurring during the +operation of the system. + +Ledger is constructed by the ordering service (see Sec 1.3.3) as a +totally ordered hashchain of *blocks* of (valid or invalid) +transactions. The hashchain imposes the total order of blocks in a +ledger and each block contains an array of totally ordered transactions. +This imposes total order across all transactions. + +Ledger is kept at all peers and, optionally, at a subset of orderers. In +the context of an orderer we refer to the Ledger as to +``OrdererLedger``, whereas in the context of a peer we refer to the +ledger as to ``PeerLedger``. ``PeerLedger`` differs from the +``OrdererLedger`` in that peers locally maintain a bitmask that tells +apart valid transactions from invalid ones (see Section XX for more +details). + +Peers may prune ``PeerLedger`` as described in Section XX (post-v1 +feature). Orderers maintain ``OrdererLedger`` for fault-tolerance and +availability (of the ``PeerLedger``) and may decide to prune it at +anytime, provided that properties of the ordering service (see Sec. +1.3.3) are maintained. + +The ledger allows peers to replay the history of all transactions and to +reconstruct the state. Therefore, state as described in Sec 1.2.1 is an +optional datastructure. + +1.3. Nodes +~~~~~~~~~~ + +Nodes are the communication entities of the blockchain. A "node" is only +a logical function in the sense that multiple nodes of different types +can run on the same physical server. What counts is how nodes are +grouped in "trust domains" and associated to logical entities that +control them. + +There are three types of nodes: + +1. **Client** or **submitting-client**: a client that submits an actual + transaction-invocation to the endorsers, and broadcasts + transaction-proposals to the ordering service. + +2. **Peer**: a node that commits transactions and maintains the state + and a copy of the ledger (see Sec, 1.2). Besides, peers can have a + special **endorser** role. + +3. **Ordering-service-node** or **orderer**: a node running the + communication service that implements a delivery guarantee, such as + atomic or total order broadcast. + +The types of nodes are explained next in more detail. + +1.3.1. Client +^^^^^^^^^^^^^ + +The client represents the entity that acts on behalf of an end-user. It +must connect to a peer for communicating with the blockchain. The client +may connect to any peer of its choice. Clients create and thereby invoke +transactions. + +As detailed in Section 2, clients communicate with both peers and the +ordering service. + +1.3.2. Peer +^^^^^^^^^^^ + +A peer receives ordered state updates in the form of *blocks* from the +ordering service and maintain the state and the ledger. + +Peers can additionally take up a special role of an **endorsing peer**, +or an **endorser**. The special function of an *endorsing peer* occurs +with respect to a particular chaincode and consists in *endorsing* a +transaction before it is committed. Every chaincode may specify an +*endorsement policy* that may refer to a set of endorsing peers. The +policy defines the necessary and sufficient conditions for a valid +transaction endorsement (typically a set of endorsers' signatures), as +described later in Sections 2 and 3. In the special case of deploy +transactions that install new chaincode the (deployment) endorsement +policy is specified as an endorsement policy of the system chaincode. + +1.3.3. Ordering service nodes (Orderers) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The *orderers* form the *ordering service*, i.e., a communication fabric +that provides delivery guarantees. The ordering service can be +implemented in different ways: ranging from a centralized service (used +e.g., in development and testing) to distributed protocols that target +different network and node fault models. + +Ordering service provides a shared *communication channel* to clients +and peers, offering a broadcast service for messages containing +transactions. Clients connect to the channel and may broadcast messages +on the channel which are then delivered to all peers. The channel +supports *atomic* delivery of all messages, that is, message +communication with total-order delivery and (implementation specific) +reliability. In other words, the channel outputs the same messages to +all connected peers and outputs them to all peers in the same logical +order. This atomic communication guarantee is also called *total-order +broadcast*, *atomic broadcast*, or *consensus* in the context of +distributed systems. The communicated messages are the candidate +transactions for inclusion in the blockchain state. + +**Partitioning (ordering service channels).** Ordering service may +support multiple *channels* similar to the *topics* of a +publish/subscribe (pub/sub) messaging system. Clients can connects to a +given channel and can then send messages and obtain the messages that +arrive. Channels can be thought of as partitions - clients connecting to +one channel are unaware of the existence of other channels, but clients +may connect to multiple channels. Even though some ordering service +implementations included with Hyperledger Fabric v1 will support +multiple channels, for simplicity of presentation, in the rest of this +document, we assume ordering service consists of a single channel/topic. + +**Ordering service API.** Peers connect to the channel provided by the +ordering service, via the interface provided by the ordering service. +The ordering service API consists of two basic operations (more +generally *asynchronous events*): + +**TODO** add the part of the API for fetching particular blocks under +client/peer specified sequence numbers. + +- ``broadcast(blob)``: a client calls this to broadcast an arbitrary + message ``blob`` for dissemination over the channel. This is also + called ``request(blob)`` in the BFT context, when sending a request + to a service. + +- ``deliver(seqno, prevhash, blob)``: the ordering service calls this + on the peer to deliver the message ``blob`` with the specified + non-negative integer sequence number (``seqno``) and hash of the most + recently delivered blob (``prevhash``). In other words, it is an + output event from the ordering service. ``deliver()`` is also + sometimes called ``notify()`` in pub-sub systems or ``commit()`` in + BFT systems. + +**Ledger and block formation.** The ledger (see also Sec. 1.2.2) +contains all data output by the ordering service. In a nutshell, it is a +sequence of ``deliver(seqno, prevhash, blob)`` events, which form a hash +chain according to the computation of ``prevhash`` described before. + +Most of the time, for efficiency reasons, instead of outputting +individual transactions (blobs), the ordering service will group (batch) +the blobs and output *blocks* within a single ``deliver`` event. In this +case, the ordering service must impose and convey a deterministic +ordering of the blobs within each block. The number of blobs in a block +may be chosen dynamically by an ordering service implementation. + +In the following, for ease of presentation, we define ordering service +properties (rest of this subsection) and explain the workflow of +transaction endorsement (Section 2) assuming one blob per ``deliver`` +event. These are easily extended to blocks, assuming that a ``deliver`` +event for a block corresponds to a sequence of individual ``deliver`` +events for each blob within a block, according to the above mentioned +deterministic ordering of blobs within a blocs. + +**Ordering service properties** + +The guarantees of the ordering service (or atomic-broadcast channel) +stipulate what happens to a broadcasted message and what relations exist +among delivered messages. These guarantees are as follows: + +1. **Safety (consistency guarantees)**: As long as peers are connected + for sufficiently long periods of time to the channel (they can + disconnect or crash, but will restart and reconnect), they will see + an *identical* series of delivered ``(seqno, prevhash, blob)`` + messages. This means the outputs (``deliver()`` events) occur in the + *same order* on all peers and according to sequence number and carry + *identical content* (``blob`` and ``prevhash``) for the same sequence + number. Note this is only a *logical order*, and a + ``deliver(seqno, prevhash, blob)`` on one peer is not required to + occur in any real-time relation to ``deliver(seqno, prevhash, blob)`` + that outputs the same message at another peer. Put differently, given + a particular ``seqno``, *no* two correct peers deliver *different* + ``prevhash`` or ``blob`` values. Moreover, no value ``blob`` is + delivered unless some client (peer) actually called + ``broadcast(blob)`` and, preferably, every broadcasted blob is only + delivered *once*. + + Furthermore, the ``deliver()`` event contains the cryptographic hash + of the data in the previous ``deliver()`` event (``prevhash``). When + the ordering service implements atomic broadcast guarantees, + ``prevhash`` is the cryptographic hash of the parameters from the + ``deliver()`` event with sequence number ``seqno-1``. This + establishes a hash chain across ``deliver()`` events, which is used + to help verify the integrity of the ordering service output, as + discussed in Sections 4 and 5 later. In the special case of the first + ``deliver()`` event, ``prevhash`` has a default value. + +2. **Liveness (delivery guarantee)**: Liveness guarantees of the + ordering service are specified by a ordering service implementation. + The exact guarantees may depend on the network and node fault model. + + In principle, if the submitting client does not fail, the ordering + service should guarantee that every correct peer that connects to the + ordering service eventually delivers every submitted transaction. + +To summarize, the ordering service ensures the following properties: + +- *Agreement.* For any two events at correct peers + ``deliver(seqno, prevhash0, blob0)`` and + ``deliver(seqno, prevhash1, blob1)`` with the same ``seqno``, + ``prevhash0==prevhash1`` and ``blob0==blob1``; +- *Hashchain integrity.* For any two events at correct peers + ``deliver(seqno-1, prevhash0, blob0)`` and + ``deliver(seqno, prevhash, blob)``, + ``prevhash = HASH(seqno-1||prevhash0||blob0)``. +- *No skipping*. If an ordering service outputs + ``deliver(seqno, prevhash, blob)`` at a correct peer *p*, such that + ``seqno>0``, then *p* already delivered an event + ``deliver(seqno-1, prevhash0, blob0)``. +- *No creation*. Any event ``deliver(seqno, prevhash, blob)`` at a + correct peer must be preceded by a ``broadcast(blob)`` event at some + (possibly distinct) peer; +- *No duplication (optional, yet desirable)*. For any two events + ``broadcast(blob)`` and ``broadcast(blob')``, when two events + ``deliver(seqno0, prevhash0, blob)`` and + ``deliver(seqno1, prevhash1, blob')`` occur at correct peers and + ``blob == blob'``, then ``seqno0==seqno1`` and + ``prevhash0==prevhash1``. +- *Liveness*. If a correct client invokes an event ``broadcast(blob)`` + then every correct peer "eventually" issues an event + ``deliver(*, *, blob)``, where ``*`` denotes an arbitrary value. + +2. Basic workflow of transaction endorsement +-------------------------------------------- + +In the following we outline the high-level request flow for a +transaction. + +**Remark:** *Notice that the following protocol *does not* assume that +all transactions are deterministic, i.e., it allows for +non-deterministic transactions.* + +2.1. The client creates a transaction and sends it to endorsing peers of its choice +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To invoke a transaction, the client sends a ``PROPOSE`` message to a set +of endorsing peers of its choice (possibly not at the same time - see +Sections 2.1.2. and 2.3.). The set of endorsing peers for a given +``chaincodeID`` is made available to client via peer, which in turn +knows the set of endorsing peers from endorsement policy (see Section +3). For example, the transaction could be sent to *all* endorsers of a +given ``chaincodeID``. That said, some endorsers could be offline, +others may object and choose not to endorse the transaction. The +submitting client tries to satisfy the policy expression with the +endorsers available. + +In the following, we first detail ``PROPOSE`` message format and then +discuss possible patterns of interaction between submitting client and +endorsers. + +2.1.1. ``PROPOSE`` message format +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The format of a ``PROPOSE`` message is ````, where +``tx`` is a mandatory and ``anchor`` optional argument explained in the +following. + +- ``tx=``, where + + - ``clientID`` is an ID of the submitting client, + - ``chaincodeID`` refers to the chaincode to which the transaction + pertains, + - ``txPayload`` is the payload containing the submitted transaction + itself, + - ``timestamp`` is a monotonically increasing (for every new + transaction) integer maintained by the client, + - ``clientSig`` is signature of a client on other fields of ``tx``. + + The details of ``txPayload`` will differ between invoke transactions + and deploy transactions (i.e., invoke transactions referring to a + deploy-specific system chaincode). For an **invoke transaction**, + ``txPayload`` would consist of two fields + + - ``txPayload = ``, where + + - ``operation`` denotes the chaincode operation (function) and + arguments, + - ``metadata`` denotes attributes related to the invocation. + + For a **deploy transaction**, ``txPayload`` would consist of three + fields + + - ``txPayload = ``, where + + - ``source`` denotes the source code of the chaincode, + - ``metadata`` denotes attributes related to the chaincode and + application, + - ``policies`` contains policies related to the chaincode that + are accessible to all peers, such as the endorsement policy. + Note that endorsement policies are not supplied with + ``txPayload`` in a ``deploy`` transaction, but + ``txPayload of a``\ deploy\` contains endorsement policy ID and + its parameters (see Section 3). + +- ``anchor`` contains *read version dependencies*, or more + specifically, key-version pairs (i.e., ``anchor`` is a subset of + ``KxN``), that binds or "anchors" the ``PROPOSE`` request to + specified versions of keys in a KVS (see Section 1.2.). If the client + specifies the ``anchor`` argument, an endorser endorses a transaction + only upon *read* version numbers of corresponding keys in its local + KVS match ``anchor`` (see Section 2.2. for more details). + +Cryptographic hash of ``tx`` is used by all nodes as a unique +transaction identifier ``tid`` (i.e., ``tid=HASH(tx)``). The client +stores ``tid`` in memory and waits for responses from endorsing peers. + +2.1.2. Message patterns +^^^^^^^^^^^^^^^^^^^^^^^ + +The client decides on the sequence of interaction with endorsers. For +example, a client would typically send ```` (i.e., without +the ``anchor`` argument) to a single endorser, which would then produce +the version dependencies (``anchor``) which the client can later on use +as an argument of its ``PROPOSE`` message to other endorsers. As another +example, the client could directly send ```` (without +``anchor``) to all endorsers of its choice. Different patterns of +communication are possible and client is free to decide on those (see +also Section 2.3.). + +2.2. The endorsing peer simulates a transaction and produces an endorsement signature +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +On reception of a ```` message from a client, the +endorsing peer ``epID`` first verifies the client's signature +``clientSig`` and then simulates a transaction. If the client specifies +``anchor`` then endorsing peer simulates the transactions only upon read +version numbers (i.e., ``readset`` as defined below) of corresponding +keys in its local KVS match those version numbers specified by +``anchor``. + +Simulating a transaction involves endorsing peer tentatively *executing* +a transaction (``txPayload``), by invoking the chaincode to which the +transaction refers (``chaincodeID``) and the copy of the state that the +endorsing peer locally holds. + +As a result of the execution, the endorsing peer computes *read version +dependencies* (``readset``) and *state updates* (``writeset``), also +called *MVCC+postimage info* in DB language. + +Recall that the state consists of key/value (k/v) pairs. All k/v entries +are versioned, that is, every entry contains ordered version +information, which is incremented every time when the value stored under +a key is updated. The peer that interprets the transaction records all +k/v pairs accessed by the chaincode, either for reading or for writing, +but the peer does not yet update its state. More specifically: + +- Given state ``s`` before an endorsing peer executes a transaction, + for every key ``k`` read by the transaction, pair + ``(k,s(k).version)`` is added to ``readset``. +- Additionally, for every key ``k`` modified by the transaction to the + new value ``v'``, pair ``(k,v')`` is added to ``writeset``. + Alternatively, ``v'`` could be the delta of the new value to previous + value (``s(k).value``). + +If a client specifies ``anchor`` in the ``PROPOSE`` message then client +specified ``anchor`` must equal ``readset`` produced by endorsing peer +when simulating the transaction. + +Then, the peer forwards internally ``tran-proposal`` (and possibly +``tx``) to the part of its (peer's) logic that endorses a transaction, +referred to as **endorsing logic**. By default, endorsing logic at a +peer accepts the ``tran-proposal`` and simply signs the +``tran-proposal``. However, endorsing logic may interpret arbitrary +functionality, to, e.g., interact with legacy systems with +``tran-proposal`` and ``tx`` as inputs to reach the decision whether to +endorse a transaction or not. + +If endorsing logic decides to endorse a transaction, it sends +```` message to the +submitting client(\ ``tx.clientID``), where: + +- ``tran-proposal := (epID,tid,chaincodeID,txContentBlob,readset,writeset)``, + + where ``txContentBlob`` is chaincode/transaction specific + information. The intention is to have ``txContentBlob`` used as some + representation of ``tx`` (e.g., ``txContentBlob=tx.txPayload``). + +- ``epSig`` is the endorsing peer's signature on ``tran-proposal`` + +Else, in case the endorsing logic refuses to endorse the transaction, an +endorser *may* send a message ``(TRANSACTION-INVALID, tid, REJECTED)`` +to the submitting client. + +Notice that an endorser does not change its state in this step, the +updates produced by transaction simulation in the context of endorsement +do not affect the state! + +2.3. The submitting client collects an endorsement for a transaction and broadcasts it through ordering service +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The submitting client waits until it receives "enough" messages and +signatures on ``(TRANSACTION-ENDORSED, tid, *, *)`` statements to +conclude that the transaction proposal is endorsed. As discussed in +Section 2.1.2., this may involve one or more round-trips of interaction +with endorsers. + +The exact number of "enough" depend on the chaincode endorsement policy +(see also Section 3). If the endorsement policy is satisfied, the +transaction has been *endorsed*; note that it is not yet committed. The +collection of signed ``TRANSACTION-ENDORSED`` messages from endorsing +peers which establish that a transaction is endorsed is called an +*endorsement* and denoted by ``endorsement``. + +If the submitting client does not manage to collect an endorsement for a +transaction proposal, it abandons this transaction with an option to +retry later. + +For transaction with a valid endorsement, we now start using the +ordering service. The submitting client invokes ordering service using +the ``broadcast(blob)``, where ``blob=endorsement``. If the client does +not have capability of invoking ordering service directly, it may proxy +its broadcast through some peer of its choice. Such a peer must be +trusted by the client not to remove any message from the ``endorsement`` +or otherwise the transaction may be deemed invalid. Notice that, +however, a proxy peer may not fabricate a valid ``endorsement``. + +2.4. The ordering service delivers a transactions to the peers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When an event ``deliver(seqno, prevhash, blob)`` occurs and a peer has +applied all state updates for blobs with sequence number lower than +``seqno``, a peer does the following: + +- It checks that the ``blob.endorsement`` is valid according to the + policy of the chaincode (``blob.tran-proposal.chaincodeID``) to which + it refers. + +- In a typical case, it also verifies that the dependencies + (``blob.endorsement.tran-proposal.readset``) have not been violated + meanwhile. In more complex use cases, ``tran-proposal`` fields in + endorsement may differ and in this case endorsement policy (Section + 3) specifies how the state evolves. + +Verification of dependencies can be implemented in different ways, +according to a consistency property or "isolation guarantee" that is +chosen for the state updates. **Serializability** is a default isolation +guarantee, unless chaincode endorsement policy specifies a different +one. Serializability can be provided by requiring the version associated +with *every* key in the ``readset`` to be equal to that key's version in +the state, and rejecting transactions that do not satisfy this +requirement. + +- If all these checks pass, the transaction is deemed *valid* or + *committed*. In this case, the peer marks the transaction with 1 in + the bitmask of the ``PeerLedger``, applies + ``blob.endorsement.tran-proposal.writeset`` to blockchain state (if + ``tran-proposals`` are the same, otherwise endorsement policy logic + defines the function that takes ``blob.endorsement``). + +- If the endorsement policy verification of ``blob.endorsement`` fails, + the transaction is invalid and the peer marks the transaction with 0 + in the bitmask of the ``PeerLedger``. It is important to note that + invalid transactions do not change the state. + +Note that this is sufficient to have all (correct) peers have the same +state after processing a deliver event (block) with a given sequence +number. Namely, by the guarantees of the ordering service, all correct +peers will receive an identical sequence of +``deliver(seqno, prevhash, blob)`` events. As the evaluation of the +endorsement policy and evaluation of version dependencies in ``readset`` +are deterministic, all correct peers will also come to the same +conclusion whether a transaction contained in a blob is valid. Hence, +all peers commit and apply the same sequence of transactions and update +their state in the same way. + +.. figure:: http://vukolic.com/hyperledger/flow-4.png + :alt: Illustration of the transaction flow (common-case path). + + Illustration of the transaction flow (common-case path). + +Figure 1. Illustration of one possible transaction flow (common-case +path). + +3. Endorsement policies +----------------------- + +3.1. Endorsement policy specification +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An **endorsement policy**, is a condition on what *endorses* a +transaction. Blockchain peers have a pre-specified set of endorsement +policies, which are referenced by a ``deploy`` transaction that installs +specific chaincode. Endorsement policies can be parametrized, and these +parameters can be specified by a ``deploy`` transaction. + +To guarantee blockchain and security properties, the set of endorsement +policies **should be a set of proven policies** with limited set of +functions in order to ensure bounded execution time (termination), +determinism, performance and security guarantees. + +Dynamic addition of endorsement policies (e.g., by ``deploy`` +transaction on chaincode deploy time) is very sensitive in terms of +bounded policy evaluation time (termination), determinism, performance +and security guarantees. Therefore, dynamic addition of endorsement +policies is not allowed, but can be supported in future. + +3.2. Transaction evaluation against endorsement policy +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A transaction is declared valid only if it has been endorsed according +to the policy. An invoke transaction for a chaincode will first have to +obtain an *endorsement* that satisfies the chaincode's policy or it will +not be committed. This takes place through the interaction between the +submitting client and endorsing peers as explained in Section 2. + +Formally the endorsement policy is a predicate on the endorsement, and +potentially further state that evaluates to TRUE or FALSE. For deploy +transactions the endorsement is obtained according to a system-wide +policy (for example, from the system chaincode). + +An endorsement policy predicate refers to certain variables. Potentially +it may refer to: + +1. keys or identities relating to the chaincode (found in the metadata + of the chaincode), for example, a set of endorsers; +2. further metadata of the chaincode; +3. elements of the ``endorsement`` and ``endorsement.tran-proposal``; +4. and potentially more. + +The above list is ordered by increasing expressiveness and complexity, +that is, it will be relatively simple to support policies that only +refer to keys and identities of nodes. + +**The evaluation of an endorsement policy predicate must be +deterministic.** An endorsement shall be evaluated locally by every peer +such that a peer does *not* need to interact with other peers, yet all +correct peers evaluate the endorsement policy in the same way. + +3.3. Example endorsement policies +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The predicate may contain logical expressions and evaluates to TRUE or +FALSE. Typically the condition will use digital signatures on the +transaction invocation issued by endorsing peers for the chaincode. + +Suppose the chaincode specifies the endorser set +``E = {Alice, Bob, Charlie, Dave, Eve, Frank, George}``. Some example +policies: + +- A valid signature from on the same ``tran-proposal`` from all members + of E. + +- A valid signature from any single member of E. + +- Valid signatures on the same ``tran-proposal`` from endorsing peers + according to the condition + ``(Alice OR Bob) AND (any two of: Charlie, Dave, Eve, Frank, George)``. + +- Valid signatures on the same ``tran-proposal`` by any 5 out of the 7 + endorsers. (More generally, for chaincode with ``n > 3f`` endorsers, + valid signatures by any ``2f+1`` out of the ``n`` endorsers, or by + any group of *more* than ``(n+f)/2`` endorsers.) + +- Suppose there is an assignment of "stake" or "weights" to the + endorsers, like + ``{Alice=49, Bob=15, Charlie=15, Dave=10, Eve=7, Frank=3, George=1}``, + where the total stake is 100: The policy requires valid signatures + from a set that has a majority of the stake (i.e., a group with + combined stake strictly more than 50), such as ``{Alice, X}`` with + any ``X`` different from George, or + ``{everyone together except Alice}``. And so on. + +- The assignment of stake in the previous example condition could be + static (fixed in the metadata of the chaincode) or dynamic (e.g., + dependent on the state of the chaincode and be modified during the + execution). + +- Valid signatures from (Alice OR Bob) on ``tran-proposal1`` and valid + signatures from ``(any two of: Charlie, Dave, Eve, Frank, George)`` + on ``tran-proposal2``, where ``tran-proposal1`` and + ``tran-proposal2`` differ only in their endorsing peers and state + updates. + +How useful these policies are will depend on the application, on the +desired resilience of the solution against failures or misbehavior of +endorsers, and on various other properties. + +4 (post-v1). Validated ledger and ``PeerLedger`` checkpointing (pruning) +------------------------------------------------------------------------ + +4.1. Validated ledger (VLedger) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To maintain the abstraction of a ledger that contains only valid and +committed transactions (that appears in Bitcoin, for example), peers +may, in addition to state and Ledger, maintain the *Validated Ledger (or +VLedger)*. This is a hash chain derived from the ledger by filtering out +invalid transactions. + +The construction of the VLedger blocks (called here *vBlocks*) proceeds +as follows. As the ``PeerLedger`` blocks may contain invalid +transactions (i.e., transactions with invalid endorsement or with +invalid version dependencies), such transactions are filtered out by +peers before a transaction from a block becomes added to a vBlock. Every +peer does this by itself (e.g., by using the bitmask associated with +``PeerLedger``). A vBlock is defined as a block without the invalid +transactions, that have been filtered out. Such vBlocks are inherently +dynamic in size and may be empty. An illustration of vBlock construction +is given in the figure below. |Illustration of the transaction flow +(common-case path).| + +Figure 2. Illustration of validated ledger block (vBlock) formation from +ledger (``PeerLedger``) blocks. + +vBlocks are chained together to a hash chain by every peer. More +specifically, every block of a validated ledger contains: + +- The hash of the previous vBlock. + +- vBlock number. + +- An ordered list of all valid transactions committed by the peers + since the last vBlock was computed (i.e., list of valid transactions + in a corresponding block). + +- The hash of the corresponding block (in ``PeerLedger``) from which + the current vBlock is derived. + +All this information is concatenated and hashed by a peer, producing the +hash of the vBlock in the validated ledger. + +4.2. ``PeerLedger`` Checkpointing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ledger contains invalid transactions, which may not necessarily be +recorded forever. However, peers cannot simply discard ``PeerLedger`` +blocks and thereby prune ``PeerLedger`` once they establish the +corresponding vBlocks. Namely, in this case, if a new peer joins the +network, other peers could not transfer the discarded blocks (pertaining +to ``PeerLedger``) to the joining peer, nor convince the joining peer of +the validity of their vBlocks. + +To facilitate pruning of the ``PeerLedger``, this document describes a +*checkpointing* mechanism. This mechanism establishes the validity of +the vBlocks across the peer network and allows checkpointed vBlocks to +replace the discarded ``PeerLedger`` blocks. This, in turn, reduces +storage space, as there is no need to store invalid transactions. It +also reduces the work to reconstruct the state for new peers that join +the network (as they do not need to establish validity of individual +transactions when reconstructing the state by replaying ``PeerLedger``, +but may simply replay the state updates contained in the validated +ledger). + +4.2.1. Checkpointing protocol +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Checkpointing is performed periodically by the peers every *CHK* blocks, +where *CHK* is a configurable parameter. To initiate a checkpoint, the +peers broadcast (e.g., gossip) to other peers message +````, where +``blockno`` is the current blocknumber and ``blocknohash`` is its +respective hash, ``stateHash`` is the hash of the latest state (produced +by e.g., a Merkle hash) upon validation of block ``blockno`` and +``peerSig`` is peer's signature on +``(CHECKPOINT,blocknohash,blockno,stateHash)``, referring to the +validated ledger. + +A peer collects ``CHECKPOINT`` messages until it obtains enough +correctly signed messages with matching ``blockno``, ``blocknohash`` and +``stateHash`` to establish a *valid checkpoint* (see Section 4.2.2.). + +Upon establishing a valid checkpoint for block number ``blockno`` with +``blocknohash``, a peer: + +- if ``blockno>latestValidCheckpoint.blockno``, then a peer assigns + ``latestValidCheckpoint=(blocknohash,blockno)``, +- stores the set of respective peer signatures that constitute a valid + checkpoint into the set ``latestValidCheckpointProof``, +- stores the state corresponding to ``stateHash`` to + ``latestValidCheckpointedState``, +- (optionally) prunes its ``PeerLedger`` up to block number ``blockno`` + (inclusive). + +4.2.2. Valid checkpoints +^^^^^^^^^^^^^^^^^^^^^^^^ + +Clearly, the checkpointing protocol raises the following questions: +*When can a peer prune its ``PeerLedger``? How many ``CHECKPOINT`` +messages are "sufficiently many"?*. This is defined by a *checkpoint +validity policy*, with (at least) two possible approaches, which may +also be combined: + +- *Local (peer-specific) checkpoint validity policy (LCVP).* A local + policy at a given peer *p* may specify a set of peers which peer *p* + trusts and whose ``CHECKPOINT`` messages are sufficient to establish + a valid checkpoint. For example, LCVP at peer *Alice* may define that + *Alice* needs to receive ``CHECKPOINT`` message from Bob, or from + *both* *Charlie* and *Dave*. + +- *Global checkpoint validity policy (GCVP).* A checkpoint validity + policy may be specified globally. This is similar to a local peer + policy, except that it is stipulated at the system (blockchain) + granularity, rather than peer granularity. For instance, GCVP may + specify that: + + - each peer may trust a checkpoint if confirmed by *11* different + peers. + - in a specific deployment in which every orderer is collocated with + a peer in the same machine (i.e., trust domain) and where up to + *f* orderers may be (Byzantine) faulty, each peer may trust a + checkpoint if confirmed by *f+1* different peers collocated with + orderers. + +.. |Illustration of the transaction flow (common-case path).| image:: http://vukolic.com/hyperledger/blocks-3.png + diff --git a/docs/source/architecture.rst b/docs/source/architecture.rst new file mode 100644 index 00000000000..85bb663a0a0 --- /dev/null +++ b/docs/source/architecture.rst @@ -0,0 +1,104 @@ +Hyperledger Fabric is a unique implementation of distributed ledger +technology (DLT) that ensures data integrity and consistency while +delivering accountability, transparency, and efficiencies unmatched by +other blockchain or DLT technology. + +Hyperledger Fabric implements a specific type of +`permissioned `__ `blockchain +network `__ on which members can track, +exchange and interact with digitized assets using +`transactions `__ that are governed by smart +contracts - what we call `chaincode `__ - in a +secure and robust manner while enabling +`participants `__ in the network to interact +in a manner that ensures that their transactions and data can be +restricted to an identified subset of network participants - something +we call a `channel `__. + +The blockchain network supports the ability for members to establish +shared ledgers that contain the source of truth about those digitized +assets, and recorded transactions, that is replicated in a secure manner +only to the set of nodes participating in that channel. + +The Hyperledger Fabric architecture is comprised of the following +components: peer nodes, ordering nodes and the clients applications that +are likely leveraging one of the language-specific Fabric SDKs. These +components have identities derived from certificate authorities. +Hyperledger Fabric also offers a certificate authority service, +*fabric-ca* but, you may substitute that with your own. + +All peer nodes maintain the ledger/state by committing transactions. In +that role, the peer is called a `committer `__. +Some peers are also responsible for simulating transactions by executing +chaincodes (smart contracts) and endorsing the result. In that role the +peer is called an `endorser `__. A peer may be an +endorser for certain types of transactions and just a ledger maintainer +(committer) for others. + +The `orderers `__ consent on the order of +transactions in a block to be committed to the ledger. In common +blockchain architectures (including earlier versions of the Hyperledger +Fabric) the roles played by the peer and orderer nodes were unified (cf. +validating peer in Hyperledger Fabric v0.6). The orderers also play a +fundamental role in the creation and management of channels. + +Two or more `participants `__ may create and +join a channel, and begin to interact. Among other things, the policies +governing the channel membership and chaincode lifecycle are specified +at the time of channel creation. Initially, the members in a channel +agree on the terms of the chaincode that will govern the transactions. +When consensus is reached on the `proposal `__ to +deploy a given chaincode (as governed by the life cycle policy for the +channel), it is committed to the ledger. + +Once the chaincode is deployed to the peer nodes in the channel, `end +users `__ with the right privileges can propose +transactions on the channel by using one of the language-specific client +SDKs to invoke functions on the deployed chaincode. + +The proposed transactions are sent to endorsers that execute the +chaincode (also called "simulated the transaction"). On successful +execution, endorse the result using the peer's identity and return the +result to the client that initiated the proposal. + +The client application ensures that the results from the endorsers are +consistent and signed by the appropriate endorsers, according to the +endorsement policy for that chaincode and, if so, the application then +sends the transaction, comprised of the result and endorsements, to the +ordering service. + +Ordering nodes order the transactions - the result and endorsements +received from the clients - into a block which is then sent to the peer +nodes to be committed to the ledger. The peers then validate the +transaction using the endorsement policy for the transaction's chaincode +and against the ledger for consistency of result. + +Some key capabilities of Hyperledger Fabric include: + +- Allows for complex query for applications that need ability to handle + complex data structures. + +- Implements a permissioned network, also known as a consortia network, + where all members are known to each other. + +- Incorporates a modular approach to various capabilities, enabling + network designers to plug in their preferred implementations for + various capabilities such as consensus (ordering), identity + management, and encryption. + +- Provides a flexible approach for specifying policies and pluggable + mechanisms to enforce them. + +- Ability to have multiple channels, isolated from one another, that + allows for multi-lateral transactions amongst select peer nodes, + thereby ensuring high degrees of privacy and confidentiality required + by competing businesses and highly regulated industries on a common + network. + +- Network scalability and performance are achieved through separation + of chaincode execution from transaction ordering, which limits the + required levels of trust and verification across nodes for + optimization. + +For a deeper dive into the details, please visit `this +document `__. diff --git a/docs/source/asset_cli.rst b/docs/source/asset_cli.rst new file mode 100644 index 00000000000..78f1a47b62b --- /dev/null +++ b/docs/source/asset_cli.rst @@ -0,0 +1,96 @@ +Manually create and join peers to a new channel +----------------------------------------------- + +Use the cli container to manually exercise the create channel and join +channel APIs. + +Channel - ``myc1`` already exists, so let's create a new channel named +``myc2``. + +Exec into the cli container: + +.. code:: bash + + docker exec -it cli bash + +If successful, you should see the following in your terminal: + +.. code:: bash + + /opt/gopath/src/github.com/hyperledger/fabric/peer # + +Send createChannel API to Ordering Service: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc2 + +This will return a genesis block - ``myc2.block`` - that you can issue +join commands with. Next, send a joinChannel API to ``peer0`` and pass +in the genesis block as an argument. The channel is defined within the +genesis block: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc2.block + +To join the other peers to the channel, simply reissue the above command +with ``peer1`` or ``peer2`` specified. For example: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 CORE_PEER_ADDRESS=peer1:7051 peer channel join -b myc2.block + +Once the peers have all joined the channel, you are able to issues +queries against any peer without having to deploy chaincode to each of +them. + +Use cli to deploy, invoke and query +----------------------------------- + +Run the deploy command. This command is deploying a chaincode named +``mycc`` to ``peer0`` on the Channel ID ``myc2``. The constructor +message is initializing ``a`` and ``b`` with values of 100 and 200 +respectively. + +:: + + CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer chaincode deploy -C myc2 -n mycc -p github.com/hyperledger/fabric/examples -c '{"Args":["init","a","100","b","200"]}' + +Run the invoke command. This invocation is moving 10 units from ``a`` to +``b``. + +:: + + CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer chaincode invoke -C myc2 -n mycc -c '{"function":"invoke","Args":["move","a","b","10"]}' + +Run the query command. The invocation transferred 10 units from ``a`` to +``b``, therefore a query against ``a`` should return the value 90. + +:: + + CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer chaincode query -C myc2 -n mycc -c '{"function":"invoke","Args":["query","a"]}' + +You can issue an ``exit`` command at any time to exit the cli container. + +Creating your initial channel through the cli +--------------------------------------------- + +If you want to manually create the initial channel through the cli +container, you will need to edit the Docker Compose file. Use an editor +to open ``docker-compose-gettingstarted.yml`` and comment out the +``channel_test.sh`` command in your cli image. Simply place a ``#`` to +the left of the command. (Recall that this script is executing the +create and join channel APIs when you run ``docker-compose up``) For +example: + +.. code:: bash + + cli: + container_name: cli + + working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer + # command: sh -c './channel_test.sh; sleep 1000' + # command: /bin/sh + +Then use the cli commands from above. diff --git a/docs/source/asset_sdk.rst b/docs/source/asset_sdk.rst new file mode 100644 index 00000000000..96779d313f6 --- /dev/null +++ b/docs/source/asset_sdk.rst @@ -0,0 +1,43 @@ +Use node SDK to register/enroll user, followed by deploy/invoke +--------------------------------------------------------------- + +The individual javascript programs will exercise the SDK APIs to +register and enroll the client with the provisioned Certificate +Authority. Once the client is properly authenticated, the programs will +demonstrate basic chaincode functionalities - deploy, invoke, and query. +Make sure you are in the working directory where you pulled the source +code before proceeding. + +Upon success of each node program, you will receive a "200" response in +the terminal. + +Register/enroll & deploy chaincode (Linux or OSX): + +.. code:: bash + + # Deploy initializes key value pairs of "a","100" & "b","200". + GOPATH=$PWD node deploy.js + +Register/enroll & deploy chaincode (Windows): + +.. code:: bash + + # Deploy initializes key value pairs of "a","100" & "b","200". + SET GOPATH=%cd% + node deploy.js + +Issue an invoke. Move units 100 from "a" to "b": + +.. code:: bash + + node invoke.js + +Query against key value "b": + +.. code:: bash + + # this should return a value of 300 + node query.js + +Explore the various node.js programs, along with ``example_cc.go`` to +better understand the SDK and APIs. diff --git a/docs/source/asset_setup.rst b/docs/source/asset_setup.rst new file mode 100644 index 00000000000..33f27610fa8 --- /dev/null +++ b/docs/source/asset_setup.rst @@ -0,0 +1,483 @@ +Getting Setup +============= + +- `Go `__ - most recent version +- `Docker `__ - v1.13 or + higher +- `Docker Compose `__ - v1.8 + or higher +- `Node.js & npm `__ - node v6.9.5 and + npm v3.10.10 +- `xcode `__ - only required for OS + X users +- `nvm `__ + - if you want to use ``nvm install`` command If you already have node + on your machine, use the node website to install v6.9.5 or issue the + following command in your terminal: + + .. code:: bash + + nvm install v6.9.5 + + then execute the following to see your versions: + + .. code:: bash + + # should be 6.9.5 + node -v + + AND + + .. code:: bash + + # should be 3.10.10 + npm -v + +**Curl the source code to create network entities** + +- Download the `cURL `__ tool if + not already installed. +- Determine a location on your local machine where you want to place + the Fabric artifacts and application code. + + .. code:: bash + + mkdir -p /hackfest + cd /hackfest + + Next, execute the following command: + + .. code:: bash + + curl -L https://raw.githubusercontent.com/hyperledger/fabric/master/examples/sfhackfest/sfhackfest.tar.gz -o sfhackfest.tar.gz 2> /dev/null; tar -xvf sfhackfest.tar.gz + + This command pulls and extracts all of the necessary artifacts to set + up your network - Docker Compose script, channel generate/join + script, crypto material for identity attestation, etc. In the + ``/src/github.com/example_cc`` directory you will find the chaincode + that will be deployed. + +Your directory should contain the following: + +.. code:: bash + + JDoe-mbp: JohnDoe$ pwd + /Users/JohnDoe + JDoe-mbp: JohnDoe$ ls + sfhackfest.tar.gz channel_test.sh src + ccenv docker-compose-gettingstarted.yml tmp + +**Using Docker** + +You do not need to manually pull any images. The images for - +``fabric-peer``, ``fabric-orderer``, ``fabric-ca``, and ``cli`` are +specified in the .yml file and will automatically download, extract, and +run when you execute the ``docker-compose`` command. + +**Commands** + +The channel commands are: + +- ``create`` - create and name a channel in the ``orderer`` and get + back a genesis block for the channel. The genesis block is named in + accordance with the channel name. +- ``join`` - use the genesis block from the ``create`` command to issue + a join request to a peer. + +**Use Docker to spawn network** + +Ensure the hyperledger/fabric-ccenv image is tagged as latest: + +.. code:: bash + + docker-compose -f docker-compose-gettingstarted.yml build + +Create network entities, create channel, join peers to channel: + +.. code:: bash + + docker-compose -f docker-compose-gettingstarted.yml up -d + +Behind the scenes this started six containers (3 peers, a "solo" +orderer, cli and CA) in detached mode. A script - ``channel_test.sh`` - +embedded within the ``docker-compose-gettingstarted.yml`` issued the +create channel and join channel commands within the CLI container. In +the end, you are left with a network and a channel containing three +peers - peer0, peer1, peer2. + +View your containers: + +.. code:: bash + + # if you have no other containers running, you will see six + docker ps + +Ensure the channel has been created and peers have successfully joined: + +.. code:: bash + + docker exec -it cli bash + +You should see the following in your terminal: + +.. code:: bash + + /opt/gopath/src/github.com/hyperledger/fabric/peer # + +To view results for channel creation/join: + +.. code:: bash + + more results.txt + +You're looking for: + +.. code:: bash + + SUCCESSFUL CHANNEL CREATION + SUCCESSFUL JOIN CHANNEL on PEER0 + SUCCESSFUL JOIN CHANNEL on PEER1 + SUCCESSFUL JOIN CHANNEL on PEER2 + +To view genesis block: + +.. code:: bash + + more myc1.block + +Exit the cli container: + +.. code:: bash + + exit + +**Curl the application source code and SDK modules** + +- Prior to issuing the command, make sure you are in the same working + directory where you curled the network code. AND make sure you have + exited the cli container. +- Execute the following command: + + .. code:: bash + + curl -OOOOOO https://raw.githubusercontent.com/hyperledger/fabric-sdk-node/v1.0-alpha/examples/balance-transfer/{config.json,deploy.js,helper.js,invoke.js,query.js,package.json} + +This command pulls the javascript code for issuing your deploy, invoke +and query calls. It also retrieves dependencies for the node SDK +modules. + +- Install the node modules: + + .. code:: bash + + # You may be prompted for your root password at one or more times during this process. + npm install + + You now have all of the necessary prerequisites and Fabric artifacts. + +Asset Transfer with SDK +--------------------------------------------------------------- + +The individual javascript programs will exercise the SDK APIs to +register and enroll the client with the provisioned Certificate +Authority. Once the client is properly authenticated, the programs will +demonstrate basic chaincode functionalities - deploy, invoke, and query. +Make sure you are in the working directory where you pulled the source +code before proceeding. + +Upon success of each node program, you will receive a "200" response in +the terminal. + +Register/enroll & deploy chaincode (Linux or OSX): + +.. code:: bash + + # Deploy initializes key value pairs of "a","100" & "b","200". + GOPATH=$PWD node deploy.js + +Register/enroll & deploy chaincode (Windows): + +.. code:: bash + + # Deploy initializes key value pairs of "a","100" & "b","200". + SET GOPATH=%cd% + node deploy.js + +Issue an invoke. Move units 100 from "a" to "b": + +.. code:: bash + + node invoke.js + +Query against key value "b": + +.. code:: bash + + # this should return a value of 300 + node query.js + +Explore the various node.js programs, along with ``example_cc.go`` to +better understand the SDK and APIs. + +Asset transfer with CLI +----------------------------------------------- + +Use the cli container to manually exercise the create channel and join +channel APIs. + +Channel - ``myc1`` already exists, so let's create a new channel named +``myc2``. + +Exec into the cli container: + +.. code:: bash + + docker exec -it cli bash + +If successful, you should see the following in your terminal: + +.. code:: bash + + /opt/gopath/src/github.com/hyperledger/fabric/peer # + +Send createChannel API to Ordering Service: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc2 + +This will return a genesis block - ``myc2.block`` - that you can issue +join commands with. Next, send a joinChannel API to ``peer0`` and pass +in the genesis block as an argument. The channel is defined within the +genesis block: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc2.block + +To join the other peers to the channel, simply reissue the above command +with ``peer1`` or ``peer2`` specified. For example: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 CORE_PEER_ADDRESS=peer1:7051 peer channel join -b myc2.block + +Once the peers have all joined the channel, you are able to issues +queries against any peer without having to deploy chaincode to each of +them. + +**Deploy, invoke and query** + + +Run the deploy command. This command is deploying a chaincode named +``mycc`` to ``peer0`` on the Channel ID ``myc2``. The constructor +message is initializing ``a`` and ``b`` with values of 100 and 200 +respectively. + +:: + + CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer chaincode deploy -C myc2 -n mycc -p github.com/hyperledger/fabric/examples -c '{"Args":["init","a","100","b","200"]}' + +Run the invoke command. This invocation is moving 10 units from ``a`` to +``b``. + +:: + + CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer chaincode invoke -C myc2 -n mycc -c '{"function":"invoke","Args":["move","a","b","10"]}' + +Run the query command. The invocation transferred 10 units from ``a`` to +``b``, therefore a query against ``a`` should return the value 90. + +:: + + CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer chaincode query -C myc2 -n mycc -c '{"function":"invoke","Args":["query","a"]}' + +You can issue an ``exit`` command at any time to exit the cli container. + +**Create the initial channel** + +If you want to manually create the initial channel through the cli +container, you will need to edit the Docker Compose file. Use an editor +to open ``docker-compose-gettingstarted.yml`` and comment out the +``channel_test.sh`` command in your cli image. Simply place a ``#`` to +the left of the command. (Recall that this script is executing the +create and join channel APIs when you run ``docker-compose up``) For +example: + +.. code:: bash + + cli: + container_name: cli + + working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer + # command: sh -c './channel_test.sh; sleep 1000' + # command: /bin/sh + +Then use the cli commands from above. + +Troubleshooting +--------------- + +If you have existing containers running, you may receive an error +indicating that a port is already occupied. If this occurs, you will +need to kill the container that is using said port. + +If a file cannot be located, make sure your curl commands executed +successfully and make sure you are in the directory where you pulled the +source code. + +If you are receiving timeout or GRPC communication errors, make sure you +have the correct version of Docker installed - v1.13.0. Then try +restarting your failing docker process. For example: + +.. code:: bash + + docker stop peer0 + +Then: + +.. code:: bash + + docker start peer0 + +Another approach to GRPC and DNS errors (peer failing to resolve with +orderer and vice versa) is to hardcode the IP addresses for each. You +will know if there is a DNS issue, because a ``more results.txt`` +command within the cli container will display something similar to: + +.. code:: bash + + ERROR CREATING CHANNEL + PEER0 ERROR JOINING CHANNEL + +Issue a ``docker inspect `` to ascertain the IP address. +For example: + +.. code:: bash + + docker inspect peer0 | grep IPAddress + +AND + +.. code:: bash + + docker inspect orderer | grep IPAddress + +Take these values and hard code them into your cli commands. For +example: + +.. code:: bash + + CORE_PEER_COMMITTER_LEDGER_ORDERER=172.21.0.2:7050 peer channel create -c myc1 + +AND THEN + +.. code:: bash + + CORE_PEER_COMMITTER_LEDGER_ORDERER= CORE_PEER_ADDRESS= peer channel join -b myc1.block + +If you are seeing errors while using the node SDK, make sure you have +the correct versions of node.js and npm installed on your machine. You +want node v6.9.5 and npm v3.10.10. + +If you ran through the automated channel create/join process (i.e. did +not comment out ``channel_test.sh`` in the +``docker-compose-gettingstarted.yml``), then channel - ``myc1`` - and +genesis block - ``myc1.block`` - have already been created and exist on +your machine. As a result, if you proceed to execute the manual steps in +your cli container: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc1 + +Then you will run into an error similar to: + +:: + + UTC [msp] Sign -> DEBU 064 Sign: digest: 5ABA6805B3CDBAF16C6D0DCD6DC439F92793D55C82DB130206E35791BCF18E5F + Error: Got unexpected status: BAD_REQUEST + Usage: + peer channel create [flags] + +This occurs because you are attempting to create a channel named +``myc1``, and this channel already exists! There are two options. Try +issuing the peer channel create command with a different channel name - +``myc2``. For example: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc2 + +Then join: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc2.block + +If you do choose to create a new channel, and want to run +deploy/invoke/query with the node.js programs, you also need to edit the +"channelID" parameter in the ``config.json`` file to match the new +channel's name. For example: + +:: + + { + "chainName":"fabric-client1", + "chaincodeID":"mycc", + "channelID":"myc2", + "goPath":"../../test/fixtures", + "chaincodePath":"github.com/example_cc", + +OR, if you want your channel called - ``myc1`` -, remove your docker +containers and then follow the same commands in the **Manually create +and join peers to a new channel** topic. + +**Clean up** + +Shut down your containers: + +.. code:: bash + + docker-compose -f docker-compose-gettingstarted.yml down + +**Helpful Docker tips** + +Remove a specific docker container: + +.. code:: bash + + docker rm + +Force removal: + +.. code:: bash + + docker rm -f + +Remove all docker containers: + +.. code:: bash + + docker rm -f $(docker ps -aq) + +This will merely kill docker containers (i.e. stop the process). You +will not lose any images. + +Remove an image: + +.. code:: bash + + docker rmi + +Forcibly remove: + +.. code:: bash + + docker rmi -f + +Remove all images: + +.. code:: bash + + docker rmi -f $(docker images -q) diff --git a/docs/source/asset_trouble.rst b/docs/source/asset_trouble.rst new file mode 100644 index 00000000000..f8e31aaed42 --- /dev/null +++ b/docs/source/asset_trouble.rst @@ -0,0 +1,168 @@ +Troubleshooting +--------------- + +If you have existing containers running, you may receive an error +indicating that a port is already occupied. If this occurs, you will +need to kill the container that is using said port. + +If a file cannot be located, make sure your curl commands executed +successfully and make sure you are in the directory where you pulled the +source code. + +If you are receiving timeout or GRPC communication errors, make sure you +have the correct version of Docker installed - v1.13.0. Then try +restarting your failing docker process. For example: + +.. code:: bash + + docker stop peer0 + +Then: + +.. code:: bash + + docker start peer0 + +Another approach to GRPC and DNS errors (peer failing to resolve with +orderer and vice versa) is to hardcode the IP addresses for each. You +will know if there is a DNS issue, because a ``more results.txt`` +command within the cli container will display something similar to: + +.. code:: bash + + ERROR CREATING CHANNEL + PEER0 ERROR JOINING CHANNEL + +Issue a ``docker inspect `` to ascertain the IP address. +For example: + +.. code:: bash + + docker inspect peer0 | grep IPAddress + +AND + +.. code:: bash + + docker inspect orderer | grep IPAddress + +Take these values and hard code them into your cli commands. For +example: + +.. code:: bash + + CORE_PEER_COMMITTER_LEDGER_ORDERER=172.21.0.2:7050 peer channel create -c myc1 + +AND THEN + +.. code:: bash + + CORE_PEER_COMMITTER_LEDGER_ORDERER= CORE_PEER_ADDRESS= peer channel join -b myc1.block + +If you are seeing errors while using the node SDK, make sure you have +the correct versions of node.js and npm installed on your machine. You +want node v6.9.5 and npm v3.10.10. + +If you ran through the automated channel create/join process (i.e. did +not comment out ``channel_test.sh`` in the +``docker-compose-gettingstarted.yml``), then channel - ``myc1`` - and +genesis block - ``myc1.block`` - have already been created and exist on +your machine. As a result, if you proceed to execute the manual steps in +your cli container: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc1 + +Then you will run into an error similar to: + +:: + + UTC [msp] Sign -> DEBU 064 Sign: digest: 5ABA6805B3CDBAF16C6D0DCD6DC439F92793D55C82DB130206E35791BCF18E5F + Error: Got unexpected status: BAD_REQUEST + Usage: + peer channel create [flags] + +This occurs because you are attempting to create a channel named +``myc1``, and this channel already exists! There are two options. Try +issuing the peer channel create command with a different channel name - +``myc2``. For example: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc2 + +Then join: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc2.block + +If you do choose to create a new channel, and want to run +deploy/invoke/query with the node.js programs, you also need to edit the +"channelID" parameter in the ``config.json`` file to match the new +channel's name. For example: + +:: + + { + "chainName":"fabric-client1", + "chaincodeID":"mycc", + "channelID":"myc2", + "goPath":"../../test/fixtures", + "chaincodePath":"github.com/example_cc", + +OR, if you want your channel called - ``myc1`` -, remove your docker +containers and then follow the same commands in the **Manually create +and join peers to a new channel** topic. + +Clean up +-------- + +Shut down your containers: + +.. code:: bash + + docker-compose -f docker-compose-gettingstarted.yml down + +Helpful Docker tips +------------------- + +Remove a specific docker container: + +.. code:: bash + + docker rm + +Force removal: + +.. code:: bash + + docker rm -f + +Remove all docker containers: + +.. code:: bash + + docker rm -f $(docker ps -aq) + +This will merely kill docker containers (i.e. stop the process). You +will not lose any images. + +Remove an image: + +.. code:: bash + + docker rmi + +Forcibly remove: + +.. code:: bash + + docker rmi -f + +Remove all images: + +.. code:: bash + + docker rmi -f $(docker images -q) diff --git a/docs/source/auction.rst b/docs/source/auction.rst new file mode 100644 index 00000000000..2522f21fdbf --- /dev/null +++ b/docs/source/auction.rst @@ -0,0 +1,14 @@ +Art Auction +=========== + +[WIP] ...coming soon + +Shows the provenance, attestation, and ownership of a piece of artwork +and the ensuing interaction of the various stakeholders. Not yet stable +with v1 codebase. + +Learn more about the components +`here `__ + +Learn more about the client-side application +`here `__ diff --git a/docs/source/best_practices.rst b/docs/source/best_practices.rst new file mode 100644 index 00000000000..240dada1ace --- /dev/null +++ b/docs/source/best_practices.rst @@ -0,0 +1,8 @@ +Best Practices +=========== + +[WIP] ...coming soon + +Intended to contain best practices and configurations for MSP, networks, +ordering service, channels, ACL, stress, policies, chaincode +development, functions, etc... diff --git a/docs/biz/DCO1.1.txt b/docs/source/biz/DCO1.1.txt similarity index 100% rename from docs/biz/DCO1.1.txt rename to docs/source/biz/DCO1.1.txt diff --git a/docs/biz/images/Canonical-Use-Cases_Asset-Depository.png b/docs/source/biz/images/Canonical-Use-Cases_Asset-Depository.png similarity index 100% rename from docs/biz/images/Canonical-Use-Cases_Asset-Depository.png rename to docs/source/biz/images/Canonical-Use-Cases_Asset-Depository.png diff --git a/docs/biz/images/Canonical-Use-Cases_B2BContract.png b/docs/source/biz/images/Canonical-Use-Cases_B2BContract.png similarity index 100% rename from docs/biz/images/Canonical-Use-Cases_B2BContract.png rename to docs/source/biz/images/Canonical-Use-Cases_B2BContract.png diff --git a/docs/biz/images/Canonical-Use-Cases_Direct-Communication.png b/docs/source/biz/images/Canonical-Use-Cases_Direct-Communication.png similarity index 100% rename from docs/biz/images/Canonical-Use-Cases_Direct-Communication.png rename to docs/source/biz/images/Canonical-Use-Cases_Direct-Communication.png diff --git a/docs/biz/images/Canonical-Use-Cases_Interoperability-of-Assets.png b/docs/source/biz/images/Canonical-Use-Cases_Interoperability-of-Assets.png similarity index 100% rename from docs/biz/images/Canonical-Use-Cases_Interoperability-of-Assets.png rename to docs/source/biz/images/Canonical-Use-Cases_Interoperability-of-Assets.png diff --git a/docs/biz/images/Canonical-Use-Cases_Manufacturing-Supply-Chain.png b/docs/source/biz/images/Canonical-Use-Cases_Manufacturing-Supply-Chain.png similarity index 100% rename from docs/biz/images/Canonical-Use-Cases_Manufacturing-Supply-Chain.png rename to docs/source/biz/images/Canonical-Use-Cases_Manufacturing-Supply-Chain.png diff --git a/docs/biz/images/Canonical-Use-Cases_One-Trade-One-Contract.png b/docs/source/biz/images/Canonical-Use-Cases_One-Trade-One-Contract.png similarity index 100% rename from docs/biz/images/Canonical-Use-Cases_One-Trade-One-Contract.png rename to docs/source/biz/images/Canonical-Use-Cases_One-Trade-One-Contract.png diff --git a/docs/biz/images/Canonical-Use-Cases_Separation-of-Asset-Ownership-and-Custodians-Duties.png b/docs/source/biz/images/Canonical-Use-Cases_Separation-of-Asset-Ownership-and-Custodians-Duties.png similarity index 100% rename from docs/biz/images/Canonical-Use-Cases_Separation-of-Asset-Ownership-and-Custodians-Duties.png rename to docs/source/biz/images/Canonical-Use-Cases_Separation-of-Asset-Ownership-and-Custodians-Duties.png diff --git a/docs/biz/images/assetrepository.png b/docs/source/biz/images/assetrepository.png similarity index 100% rename from docs/biz/images/assetrepository.png rename to docs/source/biz/images/assetrepository.png diff --git a/docs/biz/images/b2bcontract.png b/docs/source/biz/images/b2bcontract.png similarity index 100% rename from docs/biz/images/b2bcontract.png rename to docs/source/biz/images/b2bcontract.png diff --git a/docs/biz/images/corporate_action.png b/docs/source/biz/images/corporate_action.png similarity index 100% rename from docs/biz/images/corporate_action.png rename to docs/source/biz/images/corporate_action.png diff --git a/docs/biz/images/exchange.png b/docs/source/biz/images/exchange.png similarity index 100% rename from docs/biz/images/exchange.png rename to docs/source/biz/images/exchange.png diff --git a/docs/biz/images/interoperability_of_assets.png b/docs/source/biz/images/interoperability_of_assets.png similarity index 100% rename from docs/biz/images/interoperability_of_assets.png rename to docs/source/biz/images/interoperability_of_assets.png diff --git a/docs/biz/images/one_contract_per_trade.png b/docs/source/biz/images/one_contract_per_trade.png similarity index 100% rename from docs/biz/images/one_contract_per_trade.png rename to docs/source/biz/images/one_contract_per_trade.png diff --git a/docs/biz/images/separation_of_ownship_and_custodyservice.png b/docs/source/biz/images/separation_of_ownship_and_custodyservice.png similarity index 100% rename from docs/biz/images/separation_of_ownship_and_custodyservice.png rename to docs/source/biz/images/separation_of_ownship_and_custodyservice.png diff --git a/docs/biz/images/supplychain.png b/docs/source/biz/images/supplychain.png similarity index 100% rename from docs/biz/images/supplychain.png rename to docs/source/biz/images/supplychain.png diff --git a/docs/source/biz/usecases.rst b/docs/source/biz/usecases.rst new file mode 100644 index 00000000000..361fb413dc6 --- /dev/null +++ b/docs/source/biz/usecases.rst @@ -0,0 +1,254 @@ +Use Cases +========= + +B2B Contract +------------ + +Business contracts can be codified to allow two or more parties to +automate contractual agreements in a trusted way. Although information +on blockchain is naturally “public”, B2B contracts may require privacy +control to protect sensitive business information from being disclosed +to outside parties that also have access to the ledger. + +While confidential agreements are a key business case, there are many +scenarios where contracts can and should be easily discoverable by all +parties on a ledger. For example, a ledger used to create offers (asks) +seeking bids, by definition, requires access without restriction. This +type of contract may need to be standardized so that bidders can easily +find them, effectively creating an electronic trading platform with +smart contracts (aka chaincode). + +Persona +^^^^^^^ + +- Contract participant – Contract counter parties + +- Third party participant – A third party stakeholder guaranteeing the + integrity of the contract. + +Key Components +^^^^^^^^^^^^^^ + +- Multi-sig contract activation - When a contract is first deployed by + one of the counter parties, it will be in the pending activation + state. To activate a contract, signatures from other counterparties + and/or third party participants are required. + +- Multi-sig contract execution - Some contracts will require one of + many signatures to execute. For example, in trade finance, a payment + instruction can only be executed if either the recipient or an + authorized third party (e.g. UPS) confirms the shipment of the good. + +- Discoverability - If a contract is a business offer seeking bids, it + must be easily searchable. In addition, such contracts must have the + built-in intelligence to evaluate, select and honor bids. + +- Atomicity of contract execution - Atomicity of the contract is needed + to guarantee that asset transfers can only occur when payment is + received (Delivery vs. Payment). If any step in the execution process + fails, the entire transaction must be rolled back. + +- Contract to chain-code communication - Contracts must be able to + communicate with chaincodes that are deployed on the same ledger. + +- Longer Duration contract - Timer is required to support B2B contracts + that have long execution windows. + +- Reuseable contracts - Often-used contracts can be standardized for + reuse. + +- Auditable contractual agreement - Any contract can be made auditable + to third parties. + +- Contract life-cycle management - B2B contracts are unique and cannot + always be standardized. An efficient contract management system is + needed to enhance the scalability of the ledger network. + +- Validation access – Only nodes with validation rights are allowed to + validate transactions of a B2B contract. + +- View access – B2B contracts may include confidential information, so + only accounts with predefined access rights are allowed to view and + interrogate them. + +  + +Manufacturing Supply Chain +-------------------------- + +Final assemblers, such as automobile manufacturers, can create a supply +chain network managed by its peers and suppliers so that a final +assembler can better manage its suppliers and be more responsive to +events that would require vehicle recalls (possibly triggered by faulty +parts provided by a supplier). The blockchain fabric must provide a +standard protocol to allow every participant on a supply chain network +to input and track numbered parts that are produced and used on a +specific vehicle. + +Why is this specific example an abstract use case? Because while all +blockchain cases store immutable information, and some add the need for +transfer of assets between parties, this case emphasizes the need to +provide deep searchability backwards through as many as 5-10 transaction +layers. This backwards search capability is the core of establishing +provenance of any manufactured good that is made up of other component +goods and supplies. + +Persona +^^^^^^^ + +- Final Assembler – The business entity that performs the final + assembly of a product. + +- Part supplier – Supplier of parts. Suppliers can also be assemblers + by assembling parts that they receive from their sub-suppliers, and + then sending their finished product to the final (root) assembler. + +Key Components +^^^^^^^^^^^^^^ + +- Payment upon delivery of goods - Integration with off-chain payment + systems is required, so that payment instructions can be sent when + parts are received. + +- Third party Audit - All supplied parts must be auditable by third + parties. For example, regulators might need to track the total number + of parts supplied by a specific supplier, for tax accounting + purposes. + +- Obfuscation of shipments - Balances must be obfuscated so that no + supplier can deduce the business activities of any other supplier. + +- Obfuscation of market size - Total balances must be obfuscated so + that part suppliers cannot deduce their own market share to use as + leverage when negotiating contractual terms. + +- Validation Access – Only nodes with validation rights are allowed to + validate transactions (shipment of parts). + +- View access – Only accounts with view access rights are allowed to + interrogate balances of shipped parts and available parts. + +  + +Asset Depository +---------------- + +Assets such as financial securities must be able to be dematerialized on +a blockchain network so that all stakeholders of an asset type will have +direct access to that asset, allowing them to initiate trades and +acquire information on an asset without going through layers of +intermediaries. Trades should be settled in near real time and all +stakeholders must be able to access asset information in near real time. +A stakeholder should be able to add business rules on any given asset +type, as one example of using automation logic to further reduce +operating costs. + +Persona +^^^^^^^ + +- Investor – Beneficial and legal owner of an asset. + +- Issuer – Business entity that issued the asset which is now + dematerialized on the ledger network. + +- Custodian – Hired by investors to manage their assets, and offer + other value-add services on top of the assets being managed. + +- Securities Depository – Depository of dematerialized assets. + +Key Components +^^^^^^^^^^^^^^ + +- Asset to cash - Integration with off-chain payment systems is + necessary so that issuers can make payments to and receive payments + from investors. + +- Reference Rate - Some types of assets (such as floating rate notes) + may have attributes linked to external data (such as reference rate), + and such information must be fed into the ledger network. + +- Asset Timer - Many types of financial assets have predefined life + spans and are required to make periodic payments to their owners, so + a timer is required to automate the operation management of these + assets. + +- Asset Auditor - Asset transactions must be made auditable to third + parties. For example, regulators may want to audit transactions and + movements of assets to measure market risks. + +- Obfuscation of account balances - Individual account balances must be + obfuscated so that no one can deduce the exact amount that an + investor owns. + +- Validation Access – Only nodes with validation rights are allowed to + validate transactions that update the balances of an asset type (this + could be restricted to CSD and/or the issuer). + +- View access – Only accounts with view access rights are allowed to + interrogate the chaincode that defines an asset type. If an asset + represents shares of publicly traded companies, then the view access + right must be granted to every entity on the network. + + +One Trade, One Contract +----------------------- + +From the time that a trade is captured by the front office until the +trade is finally settled, only one contract that specifies the trade +will be created and used by all participants. The middle office will +enrich the same electronic contract submitted by the front office, and +that same contract will then be used by counter parties to confirm and +affirm the trade. Finally, securities depository will settle the trade +by executing the trading instructions specified on the contract. When +dealing with bulk trades, the original contract can be broken down into +sub-contracts that are always linked to the original parent contract. + +  + +Direct Communication +-------------------- + +Company A announces its intention to raise 2 Billion USD by way of +rights issue. Because this is a voluntary action, Company A needs to +ensure that complete details of the offer are sent to shareholders in +real time, regardless of how many intermediaries are involved in the +process (such as receiving/paying agents, CSD, ICSD, local/global +custodian banks, asset management firms, etc). Once a shareholder has +made a decision, that decision will also be processed and settled +(including the new issuance of shares) in real time. If a shareholder +sold its rights to a third party, the securities depository must be able +to record the new shares under the name of their new rightful owner. + +  + +Separation of Asset Ownership and Custodian’s Duties +---------------------------------------------------- + +Assets should always be owned by their actual owners, and asset owners +must be able to allow third-party professionals to manage their assets +without having to pass legal ownership of assets to third parties (such +as nominee or street name entities). If issuers need to send messages or +payments to asset owners (for example, listed share holders), issuers +send them directly to asset owners. Third-party asset managers and/or +custodians can always buy, sell, and lend assets on behalf of their +owners. Under this arrangement, asset custodians can focus on providing +value-add services to shareowners, without worrying about asset +ownership duties such as managing and redirecting payments from issuers +to shareowners. + +  + +Interoperability of Assets +-------------------------- + +If an organization requires 20,000 units of asset B, but instead owns +10,000 units of asset A, it needs a way to exchange asset A for asset B. +Though the current market might not offer enough liquidity to fulfill +this trade quickly, there might be plenty of liquidity available between +asset A and asset C, and also between asset C and asset B. Instead of +settling for market limits on direct trading (A for B) in this case, a +chain network connects buyers with "buried" sellers, finds the best +match (which could be buried under several layers of assets), and +executes the transaction. + + diff --git a/docs/source/blockchain.rst b/docs/source/blockchain.rst new file mode 100644 index 00000000000..4570c2b4bbc --- /dev/null +++ b/docs/source/blockchain.rst @@ -0,0 +1,4 @@ +Why blockchain? +=============== + +...coming soon diff --git a/docs/source/bootstrap.rst b/docs/source/bootstrap.rst new file mode 100644 index 00000000000..be7866e6e4c --- /dev/null +++ b/docs/source/bootstrap.rst @@ -0,0 +1,9 @@ +Starting a network +================== + +[WIP] ...coming soon + +Intended to contain the recommended steps for generating prerequisite +cryptographic material and then bootstrapping an ordering service (i.e. +overall network) with participating organizations, ordering node +certificates, load balancing, configuration, policies, etc... diff --git a/docs/capabilities.md b/docs/source/capabilities.rst similarity index 65% rename from docs/capabilities.md rename to docs/source/capabilities.rst index 935abcc8fd0..faa60ffeafa 100644 --- a/docs/capabilities.md +++ b/docs/source/capabilities.rst @@ -1,5 +1,7 @@ -## Capabilities +Capabilities +------------ ...coming soon -Identity Management, Privacy, Confidentiality, Throughput, Chaincode, Modularity +Identity Management, Privacy, Confidentiality, Throughput, Chaincode, +Modularity diff --git a/docs/source/carlease.rst b/docs/source/carlease.rst new file mode 100644 index 00000000000..26615c17460 --- /dev/null +++ b/docs/source/carlease.rst @@ -0,0 +1,11 @@ +Car Lease +========= + +[WIP] ...coming soon + +Uses the blockchain to record the lifecycle of a vehicle from materials +provenance, manufacture, buyer, all the way to scrap yard. Not yet +stable with v1 codebase. + +Learn more about the application and underlying chaincode +`here `__ diff --git a/docs/source/case_for_fabric.rst b/docs/source/case_for_fabric.rst new file mode 100644 index 00000000000..bfbab034e3a --- /dev/null +++ b/docs/source/case_for_fabric.rst @@ -0,0 +1,71 @@ +The Case for Fabric +=================== + +Hyperledger Fabric is a social innovation that is about to free innovators in startups, +enterprises and government to transform and radically reduce the cost of working together +across organizations. By the end of this section, you should have the essential understanding +of Fabric you need to start *knitting* together a great business network. + +Fabric is a network of networks, like the Internet itself. An application can use one or more +networks, each managing different :ref:`Assets`, Agreements and Transactions between different +sets of :ref:`Member` s. In Fabric, the Ordering Service is the foundation of each network. +The founder of a network selects an Ordering Service (or creates a new one) and passes in a +config file with the rules (usually called Policies) that govern it. Examples of these rules +include setting/defining which Members can join the network, how Members can be added or removed, +and configuration details like block size. While it is possible for one company to set and control +these rules as a "dictator," typically these rules will also include policies that make changing +the rules a matter of consensus among the members of the network. Fabric also requires some level of +"endorsement" in order to transact. Check out the power and intricacy of :doc:`endorsement-policies` +, which are used across the Fabric landscape - from a consortium's network configuration to a simple +read operation. + +We mentioned that the Ordering Service (OS) is the foundation of the network, and you're probably +thinking, "It must do something beyond just ordering." Well you're right! All members and entities +in the network will be tied to a higher level certificate authority, and this authority is defined +within the configuration of the Ordering Service. As a result, the OS can verify and authenticate +transactions arriving from any corner of the network. The OS plays a central and critical role in +the functionality and integrity of the network, and skeptics might fear too much centralization of +power and responsibility. After all, that's a principal feature of shared ledger technology - to +decentralize the control and provide a foundation of trust with entities who you CAN'T wholeheartedly +trust. Well let's assuage that fear. The OS is agnostic to transaction details; it simply orders on +a first-come-first-serve basis and returns blocks to their corresponding channels. Perhaps more +importantly though, control of the ordering service can be shared and co-administered by the +participating members in the network. OR, if even that solution is untenable, then the OS can be +hosted and maintained by a trusted third-party. Fabric is built upon a modular and pluggable +architecture, so the only real decision for business networks is how to configure an OS to meet +their requirements. + +(This notion of the OS as a pluggable component also opens the door to exciting opportunities for +innovative teams and individuals. Currently there are only a few OS orchestrations - Solo and Kafka. +However, other options such as Intel's PoET or BFT flavors could be powerful supplementaries to Fabric, +and help solve challenging use cases.) + +To participate in the Network, each Organization maintains a runtime called a :ref:`Peer`, which will +allow an application to participate in Transactions, interact with the Ordering Service, and maintain +a set of ledgers. Notice we said a set of ledgers. One of Fabric's key innovations is the ability to +run multiple :ref:`Channel` s on each network. This is how a network can conduct both highly confidential +bilateral transactions and multilateral, or even public, transactions in the same solution without +everyone having a copy of every transaction or run the code in every agreement. Watch how Fabric is +Building a Blockchain for Business . + +If you're still reading, you clearly have some knowledge and an interest in distributed ledger +technology, AND you probably think a key piece is missing. Where is consensus in all of this? Well, +it's embedded in the entire life cycle of a transaction. Transactions come into the network, and the +submitting client's identity is verified and consented upon. Transactions then get executed and endorsed, +and these endorsements are consented upon. Transactions get ordered, and the validity of this order is +consented upon. Finally, transactions get committed to a shared ledger, and each transaction's subsequent +impact on the state of the involved asset(s) is consented upon. Consensus isn't pigeonholed into one +module or one function. It lives and exists throughout the entire DNA of Fabric. Fabric is built +with security at the forefront, not as an afterthought. Members and participating entities operate with +known identities, no action on the network circumvents the sign/verify/authenticate mandate. Requirements +such as security, privacy and confidentiality are paramount in some manner to nearly all business dealings, +and they, like consensus, are stitched into the very essence of Fabric. + +So what problem do you want to solve? What assets are at stake? Who are the players? What levels of +security and encryption do you need? Fabric is designed to provide an answer and solution to this +challenging collective of questions and beyond. Just like fabric - in the literal sense of the word - is +used in everything from airplane seats to bespoke suits, solutions built on Hyperledger Fabric can range +from diamond provenance to equities trading. Explore the documentation and see how you can leverage Fabric +to craft a PoC for your own business network. + + diff --git a/docs/source/chaincode.rst b/docs/source/chaincode.rst new file mode 100644 index 00000000000..3c59343a407 --- /dev/null +++ b/docs/source/chaincode.rst @@ -0,0 +1,537 @@ +What is chaincode? +================== + +[WIP] + +coming soon ... end-to-end examples of chaincode demonstrating the +available APIs. + +Chaincode is a piece of code that is written in one of the supported +languages such as Go or Java. It is installed and instantiated through +an SDK or CLI onto a network of Hyperledger Fabric peer nodes, enabling +interaction with that network's shared ledger. + +There are three aspects to chaincode development: + +* Chaincode Interfaces +* APIs +* Chaincode Responses + +Chaincode interfaces +-------------------- + +A chaincode implements the Chaincode Interface that supports two +methods: + +* ``Init`` +* ``Invoke`` + +Init() +^^^^^^ + +Init is called when you first deploy your chaincode. As the name +implies, this function is used to do any initialization your chaincode +needs. + +Invoke() +^^^^^^^^ + +Invoke is called when you want to call chaincode functions to do real +work (i.e. read and write to the ledger). Invocations are captured as +transactions, which get grouped into blocks on the chain. When you need +to update or query the ledger, you do so by invoking your chaincode. + +Dependencies +------------ + +The import statement lists a few dependencies for the chaincode to +compile successfully. + +* fmt – contains ``Println`` for debugging/logging. +* errors – standard go error format. +* `shim `__ – contains the definitions for the chaincode interface and the chaincode stub, which are required to interact with the ledger. + +Chaincode APIs +-------------- + +When the Init or Invoke function of a chaincode is called, the fabric +passes the ``stub shim.ChaincodeStubInterface`` parameter and the +chaincode returns a ``pb.Response``. This stub can be used to call APIs +to access to the ledger services, transaction context, or to invoke +other chaincodes. + +The current APIs are defined in the shim package, and can be generated +with the following command: + +.. code:: bash + + godoc github.com/hyperledger/fabric/core/chaincode/shim + +However, it also includes functions from chaincode.pb.go (protobuffer +functions) that are not intended as public APIs. The best practice is to +look at the function definitions in chaincode.go and and the +`examples `__ +directory. + +Response +-------- + +The chaincode response comes in the form of a protobuffer. + +.. code:: go + + message Response { + + // A status code that should follow the HTTP status codes. + int32 status = 1; + + // A message associated with the response code. + string message = 2; + + // A payload that can be used to include metadata with this response. + bytes payload = 3; + + } + +The chaincode will also return events. Message events and chaincode +events. + +.. code:: go + + messageEvent { + + oneof Event { + + //Register consumer sent event + Register register = 1; + + //producer events common. + Block block = 2; + ChaincodeEvent chaincodeEvent = 3; + Rejection rejection = 4; + + //Unregister consumer sent events + Unregister unregister = 5; + + } + + } + +.. code:: go + + messageChaincodeEvent { + + string chaincodeID = 1; + string txID = 2; + string eventName = 3; + bytes payload = 4; + + } + +Once developed and deployed, there are two ways to interact with the +chaincode - through an SDK or the CLI. The steps for CLI are described +below. For SDK interaction, refer to the `balance transfer `__ samples. **Note**: This SDK interaction is covered in the **Getting Started** section. + +Command Line Interfaces +----------------------- + +To view the currently available CLI commands, execute the following: + +.. code:: bash + + # this assumes that you have correctly set the GOPATH variable and cloned the Fabric codebase into that path + cd /opt/gopath/src/github.com/hyperledger/fabric + build /bin/peer + +You will see output similar to the example below. (**NOTE**: rootcommand +below is hardcoded in main.go. Currently, the build will create a *peer* +executable file). + +.. code:: bash + + Usage: + peer [flags] + peer [command] + + Available Commands: + version Print fabric peer version. + node node specific commands. + channel channel specific commands. + chaincode chaincode specific commands. + logging logging specific commands + + + Flags: + --logging-level string: Default logging level and overrides, see core.yaml for full syntax + --test.coverprofile string: Done (default “coverage.cov) + -v, --version: Display current version of fabric peer server + Use "peer [command] --help" for more information about a command. + +The ``peer`` command supports several subcommands and flags, as shown +above. To facilitate its use in scripted applications, the ``peer`` +command always produces a non-zero return code in the event of command +failure. Upon success, many of the subcommands produce a result on +stdout as shown in the table below: + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + +
+ +Command + +.. raw:: html + + + +stdout result in the event of success + +.. raw:: html + +
+ +version + +.. raw:: html + + + +String form of peer.version defined in core.yaml + +.. raw:: html + +
+ +node start + +.. raw:: html + + + +N/A + +.. raw:: html + +
+ +node status + +.. raw:: html + + + +String form of StatusCode + +.. raw:: html + +
+ +node stop + +.. raw:: html + + + +String form of StatusCode + +.. raw:: html + +
+ +chaincode deploy + +.. raw:: html + + + +The chaincode container name (hash) required for subsequent chaincode +invoke and chaincode query commands + +.. raw:: html + +
+ +chaincode invoke + +.. raw:: html + + + +The transaction ID (UUID) + +.. raw:: html + +
+ +chaincode query + +.. raw:: html + + + +By default, the query result is formatted as a printable + +.. raw:: html + +
+ +channel create + +.. raw:: html + + + +Create a chain + +.. raw:: html + +
+ +channel join + +.. raw:: html + + + +Adds a peer to the chain + +.. raw:: html + +
+ +.. raw:: html + +
--peer-defaultchain=true
+ +.. raw:: html + +
+ + Allows users to continue to work with the default TEST\_CHAINID string. +Command line options support writing this value as raw bytes (-r, –raw) +or formatted as the hexadecimal representation of the raw bytes (-x, +–hex). If the query response is empty then nothing is output. + +.. raw:: html + +
+ +.. _swimlane: + +Chaincode Swimlanes +------------------- + +.. image:: images/chaincode_swimlane.png + +Deploy a chaincode +------------------ + +[WIP] - the CLI commands need to be refactored based on the new +deployment model. Channel Create and Channel Join will remain the same. diff --git a/docs/source/channel-setup.rst b/docs/source/channel-setup.rst new file mode 100644 index 00000000000..4a7dbc66158 --- /dev/null +++ b/docs/source/channel-setup.rst @@ -0,0 +1,179 @@ +Multichannel Setup +================== + +This document describe the CLI for creating channels and directing peers +to join channels. The CLI uses channel APIs that are also available in +the SDK. + +The channel commands are \* create - create a channel in the ``orderer`` +and get back a genesis block for the channel \* join - use genesis block +from create command to issue a join request to a Peer + +:: + + NOTE - The main JIRA items for the work are + https://jira.hyperledger.org/browse/FAB-1022 + https://jira.hyperledger.org/browse/FAB-1547 + + The commands are work in progress. In particular, there will be more configuration parameters to the commands. Some relevant JIRA items + https://jira.hyperledger.org/browse/FAB-1642 + https://jira.hyperledger.org/browse/FAB-1639 + https://jira.hyperledger.org/browse/FAB-1580 + +Using docker +------------ + +Pull the latest images from https://github.com/rameshthoomu/ + +Create a channel +~~~~~~~~~~~~~~~~ + +Copy ```docker-compose-channel.yml`` `__ to +your current directory. + +*Bring up peer and orderer* + +:: + + cd docs + docker-compose -f docker-compose-channel.yml up + +``docker ps`` should show containers ``orderer`` and ``peer0`` running. + +*Ask orderer to create a channel* Start the CLI container. + +:: + + docker-compose -f docker-compose-channel.yml run cli + +In the above shell execute the create command + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:5005 peer channel create -c myc1 + +This will create a channel genesis block file ``myc1.block`` to issue +join commands with. If you want to specify anchor peers, you can create +anchor peer files in the following format: peer-hostname port PEM file +of peer certificate + +See CORE\_PEER\_COMMITTER\_LEDGER\_ORDERER=orderer:5005 peer channel +create -h for an anchor-peer file example And pass the anchor peer files +as a comma-separated argument with flag -a: in example: + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:5005 peer channel create -c myc1 -a anchorPeer1.txt,anchorPeer2.txt + +Join a channel +~~~~~~~~~~~~~~ + +Execute the join command to peer0 in the CLI container. + +:: + + CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:5005 CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc1.block + +Use the channel to deploy and invoke chaincodes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Run the deploy command + +:: + + CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:5005 peer chaincode deploy -C myc1 -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a","100","b","200"]}' + +Run the invoke command + +:: + + CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:5005 peer chaincode invoke -C myc1 -n mycc -c '{"Args":["invoke","a","b","10"]}' + +Run the query command + +:: + + CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:5005 peer chaincode query -C myc1 -n mycc -c '{"Args":["query","a"]}' + +Using Vagrant +------------- + +Build the executables with ``make orderer`` and ``make peer`` commands. +Switch to build/bin directory. + +Create a channel +~~~~~~~~~~~~~~~~ + +*Vagrant window 1 - start orderer* + +:: + + ORDERER_GENERAL_LOGLEVEL=debug ./orderer + +*Vagrant window 2 - ask orderer to create a chain* + +:: + + peer channel create -c myc1 + +On successful creation, a genesis block myc1.block is saved in build/bin +directory. + +Join a channel +~~~~~~~~~~~~~~ + +*Vagrant window 3 - start the peer in a "chainless" mode* + +:: + + #NOTE - clear the environment with rm -rf /var/hyperledger/* after updating fabric to get channel support. + + peer node start --peer-defaultchain=false + +:: + + "--peer-defaultchain=true" is the default. It allow users continue to work with the default "testchainid" without having to join a chain. + + "--peer-defaultchain=false" starts the peer with only the channels that were joined by the peer. If the peer never joined a channel it would start up without any channels. In particular, it does not have the default "testchainid" support. + + To join channels, a peer MUST be started with the "--peer-defaultchain=false" option. + +*Vagrant window 2 - peer to join a channel* + +:: + + peer channel join -b myc1.block + +where myc1.block is the block that was received from the ``orderer`` +from the create channel command. + +At this point we can issue transactions. ### Use the channel to deploy +and invoke chaincodes *Vagrant window 2 - deploy a chaincode to myc1* + +:: + + peer chaincode deploy -C myc1 -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a","100","b","200"]}' + +Note the use of ``-C myc1`` to target the chaincode deployment against +the ``myc1`` channel. + +Wait for the deploy to get committed (e.g., by default the +``solo orderer`` can take upto 10 seconds to sends a batch of +transactions to be committed.) + +*Vagrant window 2 - invoke chaincode* + +:: + + peer chaincode invoke -C myc1 -n mycc -c '{"Args":["invoke","a","b","10"]}' + +Wait for upto 10 seconds for the invoke to get committed. + +*Vagrant window 2 - query chaincode* + +:: + + peer chaincode query -C myc1 -n mycc -c '{"Args":["query","a"]}' + +To reset, clear out the ``fileSystemPath`` directory (defined in +core.yaml) and myc1.block. diff --git a/docs/source/channels.rst b/docs/source/channels.rst new file mode 100644 index 00000000000..6914fc16b33 --- /dev/null +++ b/docs/source/channels.rst @@ -0,0 +1,4 @@ +Channels +-------- + +...coming soon diff --git a/docs/source/committer.rst b/docs/source/committer.rst new file mode 100644 index 00000000000..446e755ca1d --- /dev/null +++ b/docs/source/committer.rst @@ -0,0 +1,8 @@ +Committing Peer +=============== + +[WIP] ...coming soon + +This topic will explain the peer's runtime and role as a committer for +transactions on a channel. In the meantime, refer to the `high-level +data flow `__. diff --git a/docs/source/components.rst b/docs/source/components.rst new file mode 100644 index 00000000000..f9c44176110 --- /dev/null +++ b/docs/source/components.rst @@ -0,0 +1,7 @@ +Components +========== + +[WIP] ...coming soon + +This topic will contain a diagram explaining the various components of a +blockchain network and their corresponding roles. diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000000..a9ac538b3cc --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,194 @@ +# -*- coding: utf-8 -*- +# +# hyperledger-fabricdocs documentation build configuration file, created by +# sphinx-quickstart on Mon Feb 20 16:11:53 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('.')) + + +import sphinx_rtd_theme + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.imgmath', + 'sphinx.ext.ifconfig', + 'sphinx.ext.viewcode'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'hyperledger-fabricdocs' +copyright = u'2017, hyperledger' +author = u'hyperledger' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'master' +# The full version, including alpha/beta/rc tags. +release = u'master' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +html_add_permalinks = True + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +def setup(app): + app.add_stylesheet('css/custom.css') + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'hyperledger-fabricdocsdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'hyperledger-fabricdocs.tex', u'hyperledger-fabricdocs Documentation', + u'hyperledger', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'hyperledger-fabricdocs', u'hyperledger-fabricdocs Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'hyperledger-fabricdocs', u'hyperledger-fabricdocs Documentation', + author, 'hyperledger-fabricdocs', 'One line description of project.', + 'Miscellaneous'), +] + + + +# -- Options for Epub output ---------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project +epub_author = author +epub_publisher = author +epub_copyright = copyright + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} diff --git a/docs/source/configtxgen.rst b/docs/source/configtxgen.rst new file mode 100644 index 00000000000..ca34676e39e --- /dev/null +++ b/docs/source/configtxgen.rst @@ -0,0 +1,71 @@ +Configuring using the configtxgen tool +====================================== + +This document describe the usage for the ``configtxgen`` utility for +manipulating fabric channel configuration. + +For now, the tool is primarily focused on generating the genesis block +for bootstrapping the orderer, but it is intended to be enhanced in the +future for generating new channel configurations as well as +reconfiguring existing channels. + +Building the tool +----------------- + +Building the tool is as simple as ``make configtxgen``. This will create +a ``configtxgen`` binary at ``build/bin/configtxgen`` which is included +in the Vagrant development environment path by default. + +Configuration Profiles +---------------------- + +The configuration parameters supplied to the ``configtxgen`` tool are +primarily provided by the ``configtx.yaml`` file. This file is located +at ``fabric/common/configtx/tool/configtx.yaml`` in the fabric.git +repository. + +This configuration file is split primarily into three pieces. + +1. The ``Profiles`` section. By default, this section includes some + sample configurations which can be used for development or testing + scenarios, and refer to crypto material present in the fabric.git + tree. These profiles can make a good starting point for construction + a real deployment profile. The ``configtxgen`` tool allows you to + specify the profile it is operating under by passing the ``-profile`` + flag. Profiles may explicitly declare all configuration, but usually + inherit configuration from the defaults in (3) below. +2. The ``Organizations`` section. By default, this section includes a + single reference to the sampleconfig MSP definition. For production + deployments, the sample organization should be removed, and the MSP + definitions of the network members should be referenced and defined + instead. Each element in the ``Organizations`` section should be + tagged with an anchor label such as ``&orgName`` which will allow the + definition to be referenced in the ``Profiles`` sections. +3. The default sections. There are default sections for ``Orderer`` and + ``Application`` configuration, these include attributes like + ``BatchTimeout`` and are generally used as the base inherited values + for the profiles. + +This configuration file may be edited, or, individual properties may be +overridden by setting environment variables, such as +``CONFIGTX_ORDERER_ORDERERTYPE=kafka``. Note that the ``Profiles`` +element and profile name do not need to be specified. + +Bootstrapping the orderer +------------------------- + +After creating a configuration profile as desired, simply invoke + +:: + + configtxgen -profile <profile_name> + +This will produce a ``genesis.block`` file in the current directory. You +may optionally specify another filename by passing in the ``-path`` +parameter, or, you may skip the writing of the file by passing the +``dryRun`` parameter if you simply wish to test parsing of the file. + +Then, to utilize this genesis block, before starting the orderer, simply +specify ``ORDERER_GENERAL_GENESISMETHOD=file`` and +``ORDERER_GENERAL_GENESISFILE=$PWD/genesis.block`` or modify the +``orderer.yaml`` file to encode these values. diff --git a/docs/source/consensus.rst b/docs/source/consensus.rst new file mode 100644 index 00000000000..4f6e845f271 --- /dev/null +++ b/docs/source/consensus.rst @@ -0,0 +1,14 @@ +Consensus +========= + +[WIP] + +Not to be conflated with the ordering process. Consensus in v1 +architecture is a broader term overarching the entire transactional +flow, which serves to generate an agreement on the order and to confirm +the correctness of the set of transactions constituting a block. + +It is achieved as a byproduct of the various steps and verifications +that occur during a transaction's lifecycle from proposal to commitment. +More information on the high-level data flows is available +`here `__. diff --git a/docs/source/debug.rst b/docs/source/debug.rst new file mode 100644 index 00000000000..f58d2e691d6 --- /dev/null +++ b/docs/source/debug.rst @@ -0,0 +1,4 @@ +Debugging & Logging +=================== + +[WIP] ...coming soon diff --git a/docs/source/demos.rst b/docs/source/demos.rst new file mode 100644 index 00000000000..1eb3da1cd61 --- /dev/null +++ b/docs/source/demos.rst @@ -0,0 +1,30 @@ +Demos +===== + +Art Auction +----------- + +[WIP] ...coming soon + +Shows the provenance, attestation, and ownership of a piece of artwork +and the ensuing interaction of the various stakeholders. Not yet stable +with v1 codebase. + +Learn more about the components +`here `__ + +Learn more about the client-side application +`here `__ + +Marbles +------- + +[WIP] ...coming soon + +The marbles chaincode application demonstrates the ability to create +assets (marbles) with unique attributes - size, color, owner, etc... and +trade these assets with fellow participants in a blockchain network. It +is not yet stable with v1 codebase. + +Learn more about the marbles chaincode and client-side application +`here `__ diff --git a/docs/source/dev-setup/build.rst b/docs/source/dev-setup/build.rst new file mode 100644 index 00000000000..97e20403867 --- /dev/null +++ b/docs/source/dev-setup/build.rst @@ -0,0 +1,159 @@ +Building the fabric +------------------- + +The following instructions assume that you have already set up your +`development environment `__. + +To build the Fabric: + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric + make dist-clean all + +Running the unit tests +~~~~~~~~~~~~~~~~~~~~~~ + +Use the following sequence to run all unit tests + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric + make unit-test + +To run a specific test use the ``-run RE`` flag where RE is a regular +expression that matches the test case name. To run tests with verbose +output use the ``-v`` flag. For example, to run the ``TestGetFoo`` test +case, change to the directory containing the ``foo_test.go`` and +call/excecute + +:: + + go test -v -run=TestGetFoo + +Running Node.js Unit Tests +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You must also run the Node.js unit tests to insure that the Node.js +client SDK is not broken by your changes. To run the Node.js unit tests, +follow the instructions +`here `__. + +Running Behave BDD Tests +~~~~~~~~~~~~~~~~~~~~~~~~ + +**Note:** currently, the behave tests must be run from within in the +Vagrant environment. See the devenv setup instructions if you have not +already set up your `Vagrant +environment `__. + +`Behave `__ tests will setup networks +of peers with different security and consensus configurations and verify +that transactions run properly. To run these tests + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric + make behave + +Some of the Behave tests run inside Docker containers. If a test fails +and you want to have the logs from the Docker containers, run the tests +with this option: + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric/bddtests + behave -D logs=Y + +Building outside of Vagrant +--------------------------- + +It is possible to build the project and run peers outside of Vagrant. +Generally speaking, one has to 'translate' the vagrant `setup +file `__ +to the platform of your choice. + +Building on Z +~~~~~~~~~~~~~ + +To make building on Z easier and faster, `this +script `__ +is provided (which is similar to the `setup +file `__ +provided for vagrant). This script has been tested only on RHEL 7.2 and +has some assumptions one might want to re-visit (firewall settings, +development as root user, etc.). It is however sufficient for +development in a personally-assigned VM instance. + +To get started, from a freshly installed OS: + +:: + + sudo su + yum install git + mkdir -p $HOME/git/src/github.com/hyperledger + cd $HOME/git/src/github.com/hyperledger + git clone http://gerrit.hyperledger.org/r/fabric + source fabric/devenv/setupRHELonZ.sh + +From this point, you can proceed as described above for the Vagrant +development environment. + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric + make peer unit-test behave + +Building on Power Platform +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Development and build on Power (ppc64le) systems is done outside of +vagrant as outlined `here <#building-outside-of-vagrant->`__. For ease +of setting up the dev environment on Ubuntu, invoke `this +script `__ +as root. This script has been validated on Ubuntu 16.04 and assumes +certain things (like, development system has OS repositories in place, +firewall setting etc) and in general can be improvised further. + +To get started on Power server installed with Ubuntu, first ensure you +have properly setup your Host's `GOPATH environment +variable `__. Then, execute +the following commands to build the fabric code: + +:: + + mkdir -p $GOPATH/src/github.com/hyperledger + cd $GOPATH/src/github.com/hyperledger + git clone http://gerrit.hyperledger.org/r/fabric + sudo ./fabric/devenv/setupUbuntuOnPPC64le.sh + cd $GOPATH/src/github.com/hyperledger/fabric + make dist-clean all + +Configuration +------------- + +Configuration utilizes the `viper `__ +and `cobra `__ libraries. + +There is a **core.yaml** file that contains the configuration for the +peer process. Many of the configuration settings can be overridden on +the command line by setting ENV variables that match the configuration +setting, but by prefixing with *'CORE\_'*. For example, logging level +manipulation through the environment is shown below: + +:: + + CORE_PEER_LOGGING_LEVEL=CRITICAL peer + +Logging +------- + +Logging utilizes the `go-logging `__ +library. + +The available log levels in order of increasing verbosity are: *CRITICAL +\| ERROR \| WARNING \| NOTICE \| INFO \| DEBUG* + +See `specific logging +control `__ +instructions when running the peer process. diff --git a/docs/source/dev-setup/devenv.rst b/docs/source/dev-setup/devenv.rst new file mode 100644 index 00000000000..8117e7a9c77 --- /dev/null +++ b/docs/source/dev-setup/devenv.rst @@ -0,0 +1,175 @@ +Setting up the development environment +-------------------------------------- + +Overview +~~~~~~~~ + +Through the v0.6 release, the development environment utilized Vagrant +running an Ubuntu image, which in turn launched Docker containers as a +means of ensuring a consistent experience for developers who might be +working with varying platforms, such as MacOSX, Windows, Linux, or +whatever. Advances in Docker have enabled native support on the most +popular development platforms: MacOSX and Windows. Hence, we have +reworked our build to take full advantage of these advances. While we +still maintain a Vagrant based approach that can be used for older +versions of MacOSX and Windows that Docker does not support, we strongly +encourage that the non-Vagrant development setup be used. + +Note that while the Vagrant-based development setup could not be used in +a cloud context, the Docker-based build does support cloud platforms +such as AWS, Azure, Google and IBM to name a few. Please follow the +instructions for Ubuntu builds, below. + +Prerequisites +~~~~~~~~~~~~~ + +- `Git client `__ +- `Go `__ - 1.7 or later (for releases before + v1.0, 1.6 or later) +- For MacOSX, + `Xcode `__ + must be installed +- `Docker `__ - 1.12 or later +- `Pip `__ +- (MacOSX) you may need to install gnutar, as MacOSX comes with bsdtar + as the default, but the build uses some gnutar flags. You can use + Homebrew to install it as follows: + +:: + + brew install gnu-tar --with-default-names + +- (only if using Vagrant) - `Vagrant `__ - + 1.7.4 or later +- (only if using Vagrant) - + `VirtualBox `__ - 5.0 or later +- BIOS Enabled Virtualization - Varies based on hardware + +- Note: The BIOS Enabled Virtualization may be within the CPU or + Security settings of the BIOS + +``pip``, ``behave`` and ``docker-compose`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + pip install --upgrade pip + pip install behave nose docker-compose + pip install -I flask==0.10.1 python-dateutil==2.2 pytz==2014.3 pyyaml==3.10 couchdb==1.0 flask-cors==2.0.1 requests==2.4.3 pyOpenSSL==16.2.0 sha3==0.2.1 + +Steps +~~~~~ + +Set your GOPATH +^^^^^^^^^^^^^^^ + +Make sure you have properly setup your Host's `GOPATH environment +variable `__. This allows for +both building within the Host and the VM. + +Note to Windows users +^^^^^^^^^^^^^^^^^^^^^ + +If you are running Windows, before running any ``git clone`` commands, +run the following command. + +:: + + git config --get core.autocrlf + +If ``core.autocrlf`` is set to ``true``, you must set it to ``false`` by +running + +:: + + git config --global core.autocrlf false + +If you continue with ``core.autocrlf`` set to ``true``, the +``vagrant up`` command will fail with the error: + +``./setup.sh: /bin/bash^M: bad interpreter: No such file or directory`` + +Cloning the Fabric project +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Since the Fabric project is a ``Go`` project, you'll need to clone the +Fabric repo to your $GOPATH/src directory. If your $GOPATH has multiple +path components, then you will want to use the first one. There's a +little bit of setup needed: + +:: + + cd $GOPATH/src + mkdir -p github.com/hyperledger + cd github.com/hyperledger + +Recall that we are using ``Gerrit`` for source control, which has its +own internal git repositories. Hence, we will need to clone from +`Gerrit <../Gerrit/gerrit.md#Working-with-a-local-clone-of-the-repository>`__. +For brevity, the command is as follows: + +:: + + git clone ssh://LFID@gerrit.hyperledger.org:29418/fabric && scp -p -P 29418 LFID@gerrit.hyperledger.org:hooks/commit-msg fabric/.git/hooks/ + +**Note:** Of course, you would want to replace ``LFID`` with your own +`Linux Foundation ID <../Gerrit/lf-account.md>`__. + +Boostrapping the VM using Vagrant +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you are planning on using the Vagrant developer environment, the +following steps apply. **Again, we recommend against its use except for +developers that are limited to older versions of MacOSX and Windows that +are not supported by Docker for Mac or Windows.** + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric/devenv + vagrant up + +Go get coffee... this will take a few minutes. Once complete, you should +be able to ``ssh`` into the Vagrant VM just created. + +:: + + vagrant ssh + +Once inside the VM, you can find the peer project under +``$GOPATH/src/github.com/hyperledger/fabric``. It is also mounted as +``/hyperledger``. + +Building the fabric +~~~~~~~~~~~~~~~~~~~ + +Once you have all the dependencies installed, and have cloned the +repository, you can proceed to `build and test `__ the fabric. + +Notes +~~~~~ + +**NOTE:** Any time you change any of the files in your local fabric +directory (under ``$GOPATH/src/github.com/hyperledger/fabric``), the +update will be instantly available within the VM fabric directory. + +**NOTE:** If you intend to run the development environment behind an +HTTP Proxy, you need to configure the guest so that the provisioning +process may complete. You can achieve this via the *vagrant-proxyconf* +plugin. Install with ``vagrant plugin install vagrant-proxyconf`` and +then set the VAGRANT\_HTTP\_PROXY and VAGRANT\_HTTPS\_PROXY environment +variables *before* you execute ``vagrant up``. More details are +available here: https://github.com/tmatilai/vagrant-proxyconf/ + +**NOTE:** The first time you run this command it may take quite a while +to complete (it could take 30 minutes or more depending on your +environment) and at times it may look like it's not doing anything. As +long you don't get any error messages just leave it alone, it's all +good, it's just cranking. + +**NOTE to Windows 10 Users:** There is a known problem with vagrant on +Windows 10 (see +`mitchellh/vagrant#6754 `__). +If the ``vagrant up`` command fails it may be because you do not have +the Microsoft Visual C++ Redistributable package installed. You can +download the missing package at the following address: +http://www.microsoft.com/en-us/download/details.aspx?id=8328 diff --git a/docs/dev-setup/headers.txt b/docs/source/dev-setup/headers.txt similarity index 100% rename from docs/dev-setup/headers.txt rename to docs/source/dev-setup/headers.txt diff --git a/docs/docker-2peer.yml b/docs/source/docker-2peer.yml similarity index 100% rename from docs/docker-2peer.yml rename to docs/source/docker-2peer.yml diff --git a/docs/docker-compose-channel.yml b/docs/source/docker-compose-channel.yml similarity index 100% rename from docs/docker-compose-channel.yml rename to docs/source/docker-compose-channel.yml diff --git a/docs/source/dockercompose.rst b/docs/source/dockercompose.rst new file mode 100644 index 00000000000..db0661be8bb --- /dev/null +++ b/docs/source/dockercompose.rst @@ -0,0 +1,9 @@ +Docker Compose +============== + +[WIP] ...coming soon + +This section will explain how to use Docker Compose to stand up the +necessary components for a blockchain network. The various environment +variables correlated to each image will be explained, and different +configurations will be outlined. diff --git a/docs/source/endorsement-policies.rst b/docs/source/endorsement-policies.rst new file mode 100644 index 00000000000..2ccdb4c3e95 --- /dev/null +++ b/docs/source/endorsement-policies.rst @@ -0,0 +1,101 @@ +Endorsement policies +==================== + +Endorsement policies are used to instruct a peer on how to decide +whether a transaction is properly endorsed. When a peer receives a +transaction, it invokes the VSCC (Validation System Chaincode) +associated with the transaction's Chaincode as part of the transaction +validation flow to determine the validity of the transaction. Recall +that a transaction contains one or more endorsement from as many +endorsing peers. VSCC is tasked to make the following determinations: - +all endorsements are valid (i.e. they are valid signatures from valid +certificates over the expected message) - there is an appropriate number +of endorsements - endorsements come from the expected source(s) + +Endorsement policies are a way of specifying the second and third +points. + +Endorsement policy design +------------------------- + +Endorsement policies have two main components: - a principal - a +threshold gate + +A principal ``P`` identifies the entity whose signature is expected. + +A threshold gate ``T`` takes two inputs: an integer ``t`` (the +threshold) and a list of ``n`` principals or gates; this gate +essentially captures the expectation that out of those ``n`` principals +or gates, ``t`` are requested to be satisfied. + +For example: - ``T(2, 'A', 'B', 'C')`` requests a signature from any 2 +principals out of 'A', 'B' or 'C'; - ``T(1, 'A', T(2, 'B', 'C'))`` +requests either one signature from principal ``A`` or 1 signature from +``B`` and ``C`` each. + +Endorsement policy syntax in the CLI +------------------------------------ + +In the CLI, a simple language is used to express policies in terms of +boolean expressions over principals. + +A principal is described in terms of the MSP that is tasked to validate +the identity of the signer and of the role that the signer has within +that MSP. Currently, two roles are supported: **member** and **admin**. +Principals are described as ``MSP``.\ ``ROLE``, where ``MSP`` is the MSP +ID that is required, and ``ROLE`` is either one of the two strings +``member`` and ``admin``. Examples of valid principals are +``'Org0.admin'`` (any administrator of the ``Org0`` MSP) or +``'Org1.member'`` (any member of the ``Org1`` MSP). + +The syntax of the language is: + +``EXPR(E[, E...])`` + +where ``EXPR`` is either ``AND`` or ``OR``, representing the two boolean +expressions and ``E`` is either a principal (with the syntax described +above) or another nested call to ``EXPR``. + +For example: - ``AND('Org1.member', 'Org2.member', 'Org3.member')`` +requests 1 signature from each of the three principals - +``OR('Org1.member', 'Org2.member')`` requests 1 signature from either +one of the two principals - +``OR('Org1.member', AND('Org2.member', 'Org3.member'))`` requests either +one signature from a member of the ``Org1`` MSP or 1 signature from a +member of the ``Org2`` MSP and 1 signature from a member of the ``Org3`` +MSP. + +Specifying endorsement policies for a chaincode +----------------------------------------------- + +Using this language, a chaincode deployer can request that the +endorsements for a chaincode be validated against the specified policy. +NOTE - the default policy requires one signature from a member of the +``DEFAULT`` MSP). This is used if a policy is not specified in the CLI. + +The policy can be specified at deploy time using the ``-P`` switch, +followed by the policy. + +For example: + +:: + + peer chaincode deploy -C testchainid -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a","100","b","200"]}' -P "AND('Org1.member', 'Org2.member')" + +This command deploys chaincode ``mycc`` on chain ``testchainid`` with +the policy ``AND('Org1.member', 'Org2.member')``. + +Future enhancements +------------------- + +In this section we list future enhancements for endorsement policies: - +alongside the existing way of identifying principals by their +relationship with an MSP, we plan to identify principals in terms of the +*Organization Unit (OU)* expected in their certificates; this is useful +to express policies where we request signatures from any identity +displaying a valid certificate with an OU matching the one requested in +the definition of the principal. - instead of the syntax ``AND(., .)`` +we plan to move to a more intuitive syntax ``. AND .`` - we plan to +expose generalized threshold gates in the language as well alongside +``AND`` (which is the special ``n``-out-of-``n`` gate) and ``OR`` (which +is the special ``1``-out-of-``n`` gate) diff --git a/docs/source/endorser.rst b/docs/source/endorser.rst new file mode 100644 index 00000000000..c6529a60b00 --- /dev/null +++ b/docs/source/endorser.rst @@ -0,0 +1,8 @@ +Endorsing Peer +============== + +[WIP] ...coming soon + +This topic will explain the peer's runtime and role as an endorser for a +certain piece of chaincode. In the meantime, refer to the `high-level +data flow `__. diff --git a/docs/source/fabric_model.rst b/docs/source/fabric_model.rst new file mode 100644 index 00000000000..daa3d9e8f0e --- /dev/null +++ b/docs/source/fabric_model.rst @@ -0,0 +1,135 @@ +The Fabric Model +================= + +.. _Assets: + +Assets +------ + +Assets can range from the tangible (real estate and hardware) to the intangible +(contracts and intellectual property). You can easily define Assets in client-side +javascript and use them in your Fabric application using the included +`Fabric Composer `__ tool. + +Fabric supports the ability to exchange assets using unspent transaction outputs +as the inputs for subsequent transactions. Assets (and asset registries) live +in Fabric as a collection of key-value pairs, with state changes recorded as transactions +on a :ref:`Channel` ledger. Fabric allows for any asset +to be represented in binary or JSON format. + +.. _Chaincode: + +Chaincode +--------- + +Chaincode is software defining an asset or assets, and the transaction instructions for +modifying the asset(s). In other words, it's the business logic. Chaincode enforces the rules for reading +or altering key value pairs or other state database information. Chaincode functions execute against +the ledger current state database and are initiated through a transaction proposal. Chaincode execution +results in a set of key value writes (write set) that can be submitted to the network and applied to +the ledger on all peers. + +.. _Ledger-Features: + +Ledger Features +--------------- + +The ledger is the sequenced, tamper-resistant record of all state transitions in the fabric. State +transitions are a result of chaincode invocations ('transactions') submitted by participating +parties. Each transaction results in a set of asset key-value pairs that are committed to the +ledger as creates, updates, or deletes. + +The ledger is comprised of a blockchain ('chain') to store the immutable, sequenced record in +blocks, as well as a state database to maintain current fabric state. There is one ledger per +channel. Each peer maintains a copy of the ledger for each channel of which they are a member. + +- Query and update ledger using key-based lookups, range queries, and composite key queries +- Read-only queries using a rich query language (if using CouchDB as state database) +- Read-only history queries - Query ledger history for a key, enabling data provenance scenarios +- Transactions consist of the versions of keys/values that were read in chaincode (read set) and keys/values that were written in chaincode (write set) +- Transactions contain signatures of every endorsing peer and are submitted to ordering service +- Transactions are ordered into blocks and are "delivered" from an ordering service to peers on a channel +- Peers validate transactions against endorsement policies and enforce the policies +- Prior to appending a block, a versioning check is performed to ensure that states for assets that were read have not changed since chaincode execution time +- There is immutability once a transaction is validated and committed +- A channel's ledger contains a configuration block defining policies, access control lists, and other pertinent information +- Channel's contain :ref:`MSP`s allowing crypto materials to be derived from different certificate authorities + +See the :doc:`ledger` topic for a deeper dive on the databases, storage structure, and "query-ability." + +.. _Privacy-through-Channels: + +Privacy through Channels +------------------------ + +Fabric employs an immutable ledger on a per-channel basis, as well as +chaincodes that can manipulate and modify the current state of assets (i.e. update +key value pairs). A ledger exists in the scope of a channel - it can be shared +across the entire network (assuming every participant is operating on one common +channel) - or it can be privatized to only include a specific set of participants. + +In the latter scenario, these participants would create a separate channel and +thereby isolate/segregate their transactions and ledger. Fabric even solves +scenarios that want to bridge the gap between total transparency and privacy. +Chaincode gets installed only on peers that need to access the asset states +to perform reads and writes (in other words, if a chaincode is not installed on +a peer, it will not be able to properly interface with the ledger). To further +obfuscate the data, values within chaincode can be encrypted (in part or in total) using common +cryptographic algorithms such as SHA0-256, etc. before appending to the ledger. + +.. _Security-Membership-Services: + +Security & Membership Services +------------------------------ + +Hyperledger Fabric underpins a transactional network where all participants have +known identities. Public Key Infrastructure is used to generate cryptographic +certificates which are tied to organizations, network components, and end users +or client applications. As a result, data access control can be manipulated and +governed on the broader network and on channel levels. This "permissioned" notion +of Fabric, coupled with the existence and capabilities of channels, helps address +scenarios where privacy and confidentiality are paramount concerns. + +See the :doc:`ca-setup` to better understand cryptographic +implementations, and the sign, verify, authenticate approach used in Fabric. + +.. _Consensus: + +Consensus +--------- + +In distributed ledger technology, consensus has recently become synonymous with +a specific algorithm, within a single function. However, consensus encompasses more +than simply agreeing upon the order of transactions, and this differentiation is +highlighted in Hyperledger Fabric through its fundamental role in the entire +transaction flow, from proposal and endorsement, to ordering, validation and commitment. +In a nutshell, consensus is defined as the full-circle verification of the correctness of +a set of transactions comprising a block. + +Consensus is ultimately achieved when the order and results of a block's +transactions have met the explicit policy criteria checks. These checks and balances +take place during the lifecycle of a transaction, and include the usage of +endorsement policies to dictate which specific members must endorse a certain +transaction class, as well as system chaincodes to ensure that these policies +are enforced and upheld. Prior to commitment, the peers will employ these +system chaincodes to make sure that enough endorsements are present, and that +they were derived from the appropriate entities. Moreover, a versioning check +will take place during which the current state of the ledger is agreed or +consented upon, before any blocks containing transactions are appended to the ledger. +This final check provides protection against double spend operations and other +threats that might compromise data integrity, and allows for functions to be +executed against non-static variables. + +In addition to the multitude of endorsement, validity and versioning checks that +take place, there are also ongoing identity verifications happening in all +directions of the transaction flow. Access control lists are implemented on +hierarchal layers of the network (ordering service down to channels), and +payloads are repeatedly signed, verified and authenticated as a transaction proposal passes +through the different architectural components. To conclude, consensus is not +merely limited to the agreed upon order of a batch of transactions, but rather, +it is an overarching characterization that is achieved as a byproduct of the ongoing +verifications that take place during a transaction's journey from proposal to +commitment. + +Check out the :doc:`txflow` diagram for a visual representation +of consensus. diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst new file mode 100644 index 00000000000..d471f8fdebc --- /dev/null +++ b/docs/source/glossary.rst @@ -0,0 +1,338 @@ +Fabric Glossary +=========================== + +Terminology is important, so that all Fabric users and developers agree on what +we mean by each specific term. What is chaincode, for example. So we'll point you +there, whenever you want to reassure yourself. Of course, feel free to read the +entire thing in one sitting if you like, it's pretty enlightening! + +.. _Anchor-Peer: + +Anchor Peer +----------- + +The peer node that anchors a cluster of one, or more, peer nodes belonging to a +Member_ participating in a Channel_. Anchor peers are defined in the channel's +configuration and serve as a routing apparatus for gossip protocol. + +.. _Block: + +Block +----- + +An ordered set of transactions that is cryptographically linked to the +preceding block(s) on a channel. + +.. _Chain: + +Chain +----- + +The ledger's chain is a transaction log structured as hash-linked blocks of +transactions. Peers receive blocks of transactions from the ordering service, mark +the block's transactions as valid or invalid based on endorsement policies and +concurrency violations, and append the block to the hash chain on the peer's +file system. + +.. _chaincode: + +Chaincode +--------- + +Chaincode is software that encodes key value pairs or text-based data (JSON) and +transaction instructions for modifying this information. + +.. _Channel: + +Channel +------- + +A channel is a private blockchain overlay on a consortia blockchain network, +allowing for data isolation and confidentiality. A channel-specific ledger is +shared across the peer nodes, and transacting parties must be properly authenticated to +a channel in order to interact with the ledger. Channels are defined by a +Configuration_Block_. + +.. _Commitment: + +Commitment +---------- + +Each Peer_ on a channel validates ordered blocks of +transactions and then commits (writes/appends) the blocks to its replica of the +channel Ledger_. Peers also mark each transaction in each block +as valid or invalid. + +.. _Concurrency-Control-Version-Check: + +Concurrency Control Version Check +--------------------------------- + +Concurrency Control Version Check is a method of keeping state in sync across +peers on a channel. Peers execute transactions in parallel, and before commitment +to the ledger, peers check that the data read at execution time has not changed. +If the data read for the transaction has changed between execution time and +commitment time, then a Concurrency Control Version Check violation has +occurred, and the transaction is marked as invalid on the ledger and values +are not updated in the state database. + +.. _Configuration-Block: + +Configuration Block +------------------- + +Contains the configuration data defining members and policies for a system +chain (ordering service) or channel. Any configuration modifications to a +channel or overall network (e.g. a member leaving or joining) will result +in a new configuration block being appended to the appropriate chain. This +block will contain the contents of the genesis block, plus the delta. + +.. Consensus + +Consensus +--------- + +A broader term overarching the entire transactional flow, which serves to generate +an agreement on the order and to confirm the correctness of the set of transactions +constituting a block. + +.. _Current-State: + +Current State +------------- + +The current state of the ledger represents the latest values for all keys ever +included in its chain transaction log. Peers commit the latest values to ledger +current state for each valid transaction included in a processed block. Since +current state represents all latest key values known to the channel, it is +sometimes referred to as World State. Chaincode executes transaction proposals +against current state data. + +.. _Dynamic-Membership: + +Dynamic Membership +------------------ + +Fabric supports the addition/removal of members, peers, and ordering service +nodes, without compromising the operationality of the overall network. Dynamic +membership is critical when business relationships adjust and entities need to +be added/removed for various reasons. + +.. _Endorsement: + +Endorsement +----------- + +Refers to the process where specific peer nodes execute a transaction and return +a `YES/NO` response to the client application that generated the transaction proposal. +Chaincode applications have corresponding endorsement policies, in which the endorsing +peers are specified. + +.. _Endorsement-policy: + +Endorsement policy +------------------ + +Defines the peer nodes on a channel that must execute transactions attached to a +specific chaincode application, and the required combination of responses (endorsements). +A policy could require that a transaction be endorsed by a minimum number of +endorsing peers, a minimum percentage of endorsing peers, or by all endorsing +peers that are assigned to a specific chaincode application. Policies can be +curated based on the application and the desired level of resilience against +misbehavior (deliberate or not) by the endorsing peers. A distinct endorsement +policy for deploy transactions, which install new chaincode, is also required. + +.. _Genesis-Block: + +Genesis Block +------------- + +The configuration block that initializes a blockchain network or channel, and +also serves as the first block on a chain. + +.. _Gossip-Protocol: + +Gossip Protocol +--------------- + +The gossip data dissemination protocol performs three functions: +1) manages peer discovery and channel membership; +2) disseminates ledger data across all peers on the channel; +3) syncs ledger state across all peers on the channel. +Refer to the :doc:`gossip` topic for more details. + +.. _Initialize: + +Initialize +---------- + +A method to initialize a chaincode application prior to it being instantiated. + +Install +------- + +The process of placing a chaincode on a peer's file system + +Instantiate +----------- + +The process of starting a chaincode container + +.. _Invoke: + +Invoke +------ + +Used to call chaincode functions. Invocations are captured as transaction +proposals, which then pass through a modular flow of endorsement, ordering, +validation, committal. The structure of invoke is a function and an array of +arguments. + +.. _Leading-Peer: + +Leading Peer +------------ + +Each Member_ can own multiple peers on each channel that +it subscribes to. One of these peers is serves as the leading peer for the channel, +in order to communicate with the network ordering service on behalf of the +member. The ordering service "delivers" blocks to the leading peer(s) on a +channel, who then distribute them to other peers within the same member cluster. + +.. _Ledger: + +Ledger +------ + +A ledger is a channel's chain and current state data which is maintained by each +peer on the channel. + +.. _Member: + +Member +------ + +A legally separate entity that owns a unique root certificate for the network. +Network components such as peer nodes and application clients will be linked to a member. + +.. _MSP: + +Membership Service Provider +--------------------------- + +The Membership Service Provider (MSP) refers to an abstract component of the +system that provides credentials to clients, and peers for them to participate +in a Hyperledger Fabric network. Clients use these credentials to authenticate +their transactions, and peers use these credentials to authenticate transaction +processing results (endorsements). While strongly connected to the transaction +processing components of the systems, this interface aims to have membership +services components defined, in such a way that alternate implementations of +this can be smoothly plugged in without modifying the core of transaction +processing components of the system. + +.. _Membership-Services: + +Membership Services +------------------- + +Membership Services authenticates, authorizes, and manages identities on a +permissioned blockchain network. The membership services code that runs in peers +and orderers both authenticates and authorizes blockchain operations. It is a +PKI-based implementation of the Membership Services Provider (MSP) abstraction. + +The ``fabric-ca`` component is an implementation of membership services to manage +identities. In particular, it handles the issuance and revocation of enrollment +certificates and transaction certificates. + +An enrollment certificate is a long-term identity credential; a transaction +certificate is a short-term identity credential which is both anonymous and un-linkable. + +.. _Ordering-Service: + +Ordering Service +---------------- + +A defined collective of nodes that orders transactions into a block. The ordering +service exists independent of the peer processes and orders transactions on a +first-come-first-serve basis for all channel's on the network. The ordering service is +designed to support pluggable implementations beyond the out-of-the-box SOLO and Kafka varieties. +The ordering service is a common binding for the overall network; it contains the cryptographic +identity material tied to each Member_. + +.. _Peer: + +Peer +---- + +A network entity that maintains a ledger and runs chaincode containers in order to perform +read/write operations to the ledger. Peers are owned and maintained by members. + +.. _Policy: + +Policy +------ + +There are policies for endorsement, validation, block committal, chaincode +management and network/channel management. + +.. _Proposal: + +Proposal +-------- + +A request for endorsement that is aimed at specific peers on a channel. Each +proposal is either an instantiate or an invoke (read/write) request. + +.. _Query: + +Query +----- + +A query requests the value of a key(s) against the current state. + +.. _SDK: + +Software Development Kit (SDK) +------------------------------ + +The Hyperledger Fabric client SDK provides a structured environment of libraries +for developers to write and test chaincode applications. The SDK is fully +configurable and extensible through a standard interface. Components, including +cryptographic algorithms for signatures, logging frameworks and state stores, +are easily swapped in and out of the SDK. The SDK API uses protocol buffers over +gRPC for transaction processing, membership services, node traversal and event +handling applications to communicate across the fabric. The SDK comes in +multiple flavors - Node.js, Java. and Python. + +.. _State-DB: + +State Database +-------------- + +Current state data is stored in a state database for efficient reads and queries +from chaincode. These databases include levelDB and couchDB. + +.. _System-Chain: + +System Chain +------------ + +Contains a configuration block defining the network at a system level. The +system chain lives within the ordering service, and similar to a channel, has +an initial configuration containing information such as: MSP information, policies, +and configuration details. Any change to the overall network (e.g. a new org +joining or a new ordering node being added) will result in a new configuration block +being added to the system chain. + +The system chain can be thought of as the common binding for a channel or group +of channels. For instance, a collection of financial institutions may form a +consortium (represented through the system chain), and then proceed to create +channels relative to their aligned and varying business agendas. + +.. _Transaction: + +Transaction +----------- + +An invoke or instantiate operation. Invokes are requests to read/write data from +the ledger. Instantiate is a request to start a chaincode container on a peer. diff --git a/docs/source/gossip.rst b/docs/source/gossip.rst new file mode 100644 index 00000000000..e3b599792f8 --- /dev/null +++ b/docs/source/gossip.rst @@ -0,0 +1,4 @@ +Gossip data dissemination protocol +---------------------------------- + +...coming soon diff --git a/docs/images/Architecture_Step-1.png b/docs/source/images/Architecture_Step-1.png similarity index 100% rename from docs/images/Architecture_Step-1.png rename to docs/source/images/Architecture_Step-1.png diff --git a/docs/images/Architecture_Step-2.png b/docs/source/images/Architecture_Step-2.png similarity index 100% rename from docs/images/Architecture_Step-2.png rename to docs/source/images/Architecture_Step-2.png diff --git a/docs/images/Architecture_Step-3.png b/docs/source/images/Architecture_Step-3.png similarity index 100% rename from docs/images/Architecture_Step-3.png rename to docs/source/images/Architecture_Step-3.png diff --git a/docs/images/Architecture_Step-4.png b/docs/source/images/Architecture_Step-4.png similarity index 100% rename from docs/images/Architecture_Step-4.png rename to docs/source/images/Architecture_Step-4.png diff --git a/docs/images/BuildStatus.png b/docs/source/images/BuildStatus.png similarity index 100% rename from docs/images/BuildStatus.png rename to docs/source/images/BuildStatus.png diff --git a/docs/images/Canonical-Use-Cases_Asset-Depository.png b/docs/source/images/Canonical-Use-Cases_Asset-Depository.png similarity index 100% rename from docs/images/Canonical-Use-Cases_Asset-Depository.png rename to docs/source/images/Canonical-Use-Cases_Asset-Depository.png diff --git a/docs/images/Canonical-Use-Cases_B2BContract.png b/docs/source/images/Canonical-Use-Cases_B2BContract.png similarity index 100% rename from docs/images/Canonical-Use-Cases_B2BContract.png rename to docs/source/images/Canonical-Use-Cases_B2BContract.png diff --git a/docs/images/Canonical-Use-Cases_Direct-Communication.png b/docs/source/images/Canonical-Use-Cases_Direct-Communication.png similarity index 100% rename from docs/images/Canonical-Use-Cases_Direct-Communication.png rename to docs/source/images/Canonical-Use-Cases_Direct-Communication.png diff --git a/docs/images/Canonical-Use-Cases_Interoperability-of-Assets.png b/docs/source/images/Canonical-Use-Cases_Interoperability-of-Assets.png similarity index 100% rename from docs/images/Canonical-Use-Cases_Interoperability-of-Assets.png rename to docs/source/images/Canonical-Use-Cases_Interoperability-of-Assets.png diff --git a/docs/images/Canonical-Use-Cases_Manufacturing-Supply-Chain.png b/docs/source/images/Canonical-Use-Cases_Manufacturing-Supply-Chain.png similarity index 100% rename from docs/images/Canonical-Use-Cases_Manufacturing-Supply-Chain.png rename to docs/source/images/Canonical-Use-Cases_Manufacturing-Supply-Chain.png diff --git a/docs/images/Canonical-Use-Cases_One-Trade-One-Contract.png b/docs/source/images/Canonical-Use-Cases_One-Trade-One-Contract.png similarity index 100% rename from docs/images/Canonical-Use-Cases_One-Trade-One-Contract.png rename to docs/source/images/Canonical-Use-Cases_One-Trade-One-Contract.png diff --git a/docs/images/Canonical-Use-Cases_Separation-of-Asset-Ownership-and-Custodians-Duties.png b/docs/source/images/Canonical-Use-Cases_Separation-of-Asset-Ownership-and-Custodians-Duties.png similarity index 100% rename from docs/images/Canonical-Use-Cases_Separation-of-Asset-Ownership-and-Custodians-Duties.png rename to docs/source/images/Canonical-Use-Cases_Separation-of-Asset-Ownership-and-Custodians-Duties.png diff --git a/docs/images/Jira.png b/docs/source/images/Jira.png similarity index 100% rename from docs/images/Jira.png rename to docs/source/images/Jira.png diff --git a/docs/images/Jira1.png b/docs/source/images/Jira1.png similarity index 100% rename from docs/images/Jira1.png rename to docs/source/images/Jira1.png diff --git a/docs/images/Jira2.png b/docs/source/images/Jira2.png similarity index 100% rename from docs/images/Jira2.png rename to docs/source/images/Jira2.png diff --git a/docs/images/Jira3.png b/docs/source/images/Jira3.png similarity index 100% rename from docs/images/Jira3.png rename to docs/source/images/Jira3.png diff --git a/docs/images/Jira4.png b/docs/source/images/Jira4.png similarity index 100% rename from docs/images/Jira4.png rename to docs/source/images/Jira4.png diff --git a/docs/images/Travis_Settings.png b/docs/source/images/Travis_Settings.png similarity index 100% rename from docs/images/Travis_Settings.png rename to docs/source/images/Travis_Settings.png diff --git a/docs/images/Travis_service.png b/docs/source/images/Travis_service.png similarity index 100% rename from docs/images/Travis_service.png rename to docs/source/images/Travis_service.png diff --git a/docs/source/images/app.png b/docs/source/images/app.png new file mode 100644 index 00000000000..e906b26f159 Binary files /dev/null and b/docs/source/images/app.png differ diff --git a/docs/images/attributes_flow.png b/docs/source/images/attributes_flow.png similarity index 100% rename from docs/images/attributes_flow.png rename to docs/source/images/attributes_flow.png diff --git a/docs/source/images/binary.png b/docs/source/images/binary.png new file mode 100644 index 00000000000..af1df0c4677 Binary files /dev/null and b/docs/source/images/binary.png differ diff --git a/docs/source/images/block.png b/docs/source/images/block.png new file mode 100644 index 00000000000..b9d7caede27 Binary files /dev/null and b/docs/source/images/block.png differ diff --git a/docs/source/images/certificate.png b/docs/source/images/certificate.png new file mode 100644 index 00000000000..d8ad74e705a Binary files /dev/null and b/docs/source/images/certificate.png differ diff --git a/docs/source/images/chaincode_swimlane.png b/docs/source/images/chaincode_swimlane.png new file mode 100644 index 00000000000..b8bfdade754 Binary files /dev/null and b/docs/source/images/chaincode_swimlane.png differ diff --git a/docs/source/images/client.png b/docs/source/images/client.png new file mode 100644 index 00000000000..91481254591 Binary files /dev/null and b/docs/source/images/client.png differ diff --git a/docs/source/images/ledger.png b/docs/source/images/ledger.png new file mode 100644 index 00000000000..70d9c00e7fd Binary files /dev/null and b/docs/source/images/ledger.png differ diff --git a/docs/source/images/ordering_service.png b/docs/source/images/ordering_service.png new file mode 100644 index 00000000000..6e7c02b4c5f Binary files /dev/null and b/docs/source/images/ordering_service.png differ diff --git a/docs/source/images/peer.png b/docs/source/images/peer.png new file mode 100644 index 00000000000..6824f98497c Binary files /dev/null and b/docs/source/images/peer.png differ diff --git a/docs/source/images/radish.png b/docs/source/images/radish.png new file mode 100644 index 00000000000..61d61f83cd5 Binary files /dev/null and b/docs/source/images/radish.png differ diff --git a/docs/images/refarch-api.png b/docs/source/images/refarch-api.png similarity index 100% rename from docs/images/refarch-api.png rename to docs/source/images/refarch-api.png diff --git a/docs/images/refarch-app.png b/docs/source/images/refarch-app.png similarity index 100% rename from docs/images/refarch-app.png rename to docs/source/images/refarch-app.png diff --git a/docs/images/refarch-block.png b/docs/source/images/refarch-block.png similarity index 100% rename from docs/images/refarch-block.png rename to docs/source/images/refarch-block.png diff --git a/docs/images/refarch-chain.png b/docs/source/images/refarch-chain.png similarity index 100% rename from docs/images/refarch-chain.png rename to docs/source/images/refarch-chain.png diff --git a/docs/images/refarch-memb.png b/docs/source/images/refarch-memb.png similarity index 100% rename from docs/images/refarch-memb.png rename to docs/source/images/refarch-memb.png diff --git a/docs/images/refarch.png b/docs/source/images/refarch.png similarity index 100% rename from docs/images/refarch.png rename to docs/source/images/refarch.png diff --git a/docs/source/images/sdk.png b/docs/source/images/sdk.png new file mode 100644 index 00000000000..f89d4af86e5 Binary files /dev/null and b/docs/source/images/sdk.png differ diff --git a/docs/images/sec-RACapp-depl.png b/docs/source/images/sec-RACapp-depl.png similarity index 100% rename from docs/images/sec-RACapp-depl.png rename to docs/source/images/sec-RACapp-depl.png diff --git a/docs/images/sec-RACapp-inv.png b/docs/source/images/sec-RACapp-inv.png similarity index 100% rename from docs/images/sec-RACapp-inv.png rename to docs/source/images/sec-RACapp-inv.png diff --git a/docs/images/sec-entities.png b/docs/source/images/sec-entities.png similarity index 100% rename from docs/images/sec-entities.png rename to docs/source/images/sec-entities.png diff --git a/docs/images/sec-example-1.png b/docs/source/images/sec-example-1.png similarity index 100% rename from docs/images/sec-example-1.png rename to docs/source/images/sec-example-1.png diff --git a/docs/images/sec-example-2.png b/docs/source/images/sec-example-2.png similarity index 100% rename from docs/images/sec-example-2.png rename to docs/source/images/sec-example-2.png diff --git a/docs/images/sec-firstrel-1.jpg b/docs/source/images/sec-firstrel-1.jpg similarity index 100% rename from docs/images/sec-firstrel-1.jpg rename to docs/source/images/sec-firstrel-1.jpg diff --git a/docs/images/sec-firstrel-1.png b/docs/source/images/sec-firstrel-1.png similarity index 100% rename from docs/images/sec-firstrel-1.png rename to docs/source/images/sec-firstrel-1.png diff --git a/docs/images/sec-firstrel-2.png b/docs/source/images/sec-firstrel-2.png similarity index 100% rename from docs/images/sec-firstrel-2.png rename to docs/source/images/sec-firstrel-2.png diff --git a/docs/images/sec-firstrel-depl.png b/docs/source/images/sec-firstrel-depl.png similarity index 100% rename from docs/images/sec-firstrel-depl.png rename to docs/source/images/sec-firstrel-depl.png diff --git a/docs/images/sec-firstrel-inv.png b/docs/source/images/sec-firstrel-inv.png similarity index 100% rename from docs/images/sec-firstrel-inv.png rename to docs/source/images/sec-firstrel-inv.png diff --git a/docs/images/sec-futrel-depl.png b/docs/source/images/sec-futrel-depl.png similarity index 100% rename from docs/images/sec-futrel-depl.png rename to docs/source/images/sec-futrel-depl.png diff --git a/docs/images/sec-futrel-inv.png b/docs/source/images/sec-futrel-inv.png similarity index 100% rename from docs/images/sec-futrel-inv.png rename to docs/source/images/sec-futrel-inv.png diff --git a/docs/images/sec-memserv-components.png b/docs/source/images/sec-memserv-components.png similarity index 100% rename from docs/images/sec-memserv-components.png rename to docs/source/images/sec-memserv-components.png diff --git a/docs/images/sec-registration-detailed.png b/docs/source/images/sec-registration-detailed.png similarity index 100% rename from docs/images/sec-registration-detailed.png rename to docs/source/images/sec-registration-detailed.png diff --git a/docs/images/sec-registration-high-level.png b/docs/source/images/sec-registration-high-level.png similarity index 100% rename from docs/images/sec-registration-high-level.png rename to docs/source/images/sec-registration-high-level.png diff --git a/docs/images/sec-request-tcerts-deployment.png b/docs/source/images/sec-request-tcerts-deployment.png similarity index 100% rename from docs/images/sec-request-tcerts-deployment.png rename to docs/source/images/sec-request-tcerts-deployment.png diff --git a/docs/images/sec-request-tcerts-invocation.png b/docs/source/images/sec-request-tcerts-invocation.png similarity index 100% rename from docs/images/sec-request-tcerts-invocation.png rename to docs/source/images/sec-request-tcerts-invocation.png diff --git a/docs/images/sec-sec-arch.png b/docs/source/images/sec-sec-arch.png similarity index 100% rename from docs/images/sec-sec-arch.png rename to docs/source/images/sec-sec-arch.png diff --git a/docs/images/sec-sources-1.pptx b/docs/source/images/sec-sources-1.pptx similarity index 100% rename from docs/images/sec-sources-1.pptx rename to docs/source/images/sec-sources-1.pptx diff --git a/docs/images/sec-sources-2.pptx b/docs/source/images/sec-sources-2.pptx similarity index 100% rename from docs/images/sec-sources-2.pptx rename to docs/source/images/sec-sources-2.pptx diff --git a/docs/images/sec-txconf-v1.2.pptx b/docs/source/images/sec-txconf-v1.2.pptx similarity index 100% rename from docs/images/sec-txconf-v1.2.pptx rename to docs/source/images/sec-txconf-v1.2.pptx diff --git a/docs/images/sec-usrconf-deploy-interm.png b/docs/source/images/sec-usrconf-deploy-interm.png similarity index 100% rename from docs/images/sec-usrconf-deploy-interm.png rename to docs/source/images/sec-usrconf-deploy-interm.png diff --git a/docs/images/sec-usrconf-deploy.png b/docs/source/images/sec-usrconf-deploy.png similarity index 100% rename from docs/images/sec-usrconf-deploy.png rename to docs/source/images/sec-usrconf-deploy.png diff --git a/docs/images/sec-usrconf-invoke-interm.png b/docs/source/images/sec-usrconf-invoke-interm.png similarity index 100% rename from docs/images/sec-usrconf-invoke-interm.png rename to docs/source/images/sec-usrconf-invoke-interm.png diff --git a/docs/images/sec-usrconf-invoke.png b/docs/source/images/sec-usrconf-invoke.png similarity index 100% rename from docs/images/sec-usrconf-invoke.png rename to docs/source/images/sec-usrconf-invoke.png diff --git a/docs/source/images/signature.png b/docs/source/images/signature.png new file mode 100644 index 00000000000..2ec8be2954d Binary files /dev/null and b/docs/source/images/signature.png differ diff --git a/docs/images/standalone-app-developer.png b/docs/source/images/standalone-app-developer.png similarity index 100% rename from docs/images/standalone-app-developer.png rename to docs/source/images/standalone-app-developer.png diff --git a/docs/source/images/step0.png b/docs/source/images/step0.png new file mode 100644 index 00000000000..9d870ef701b Binary files /dev/null and b/docs/source/images/step0.png differ diff --git a/docs/source/images/step1.png b/docs/source/images/step1.png new file mode 100644 index 00000000000..80cd22907f1 Binary files /dev/null and b/docs/source/images/step1.png differ diff --git a/docs/source/images/step2.png b/docs/source/images/step2.png new file mode 100644 index 00000000000..9c08d3a692e Binary files /dev/null and b/docs/source/images/step2.png differ diff --git a/docs/source/images/step3.png b/docs/source/images/step3.png new file mode 100644 index 00000000000..69c05114d5e Binary files /dev/null and b/docs/source/images/step3.png differ diff --git a/docs/source/images/step4.png b/docs/source/images/step4.png new file mode 100644 index 00000000000..104f199119a Binary files /dev/null and b/docs/source/images/step4.png differ diff --git a/docs/source/images/step5.png b/docs/source/images/step5.png new file mode 100644 index 00000000000..b9ed14a00ea Binary files /dev/null and b/docs/source/images/step5.png differ diff --git a/docs/source/images/step6.png b/docs/source/images/step6.png new file mode 100644 index 00000000000..5a2193a9a85 Binary files /dev/null and b/docs/source/images/step6.png differ diff --git a/docs/images/top-multi-peer.png b/docs/source/images/top-multi-peer.png similarity index 100% rename from docs/images/top-multi-peer.png rename to docs/source/images/top-multi-peer.png diff --git a/docs/images/top-single-peer.png b/docs/source/images/top-single-peer.png similarity index 100% rename from docs/images/top-single-peer.png rename to docs/source/images/top-single-peer.png diff --git a/docs/source/images/tx_proposal.png b/docs/source/images/tx_proposal.png new file mode 100644 index 00000000000..f53b57a68e7 Binary files /dev/null and b/docs/source/images/tx_proposal.png differ diff --git a/docs/images/web-app-developer.png b/docs/source/images/web-app-developer.png similarity index 100% rename from docs/images/web-app-developer.png rename to docs/source/images/web-app-developer.png diff --git a/docs/images/world_view.png b/docs/source/images/world_view.png similarity index 100% rename from docs/images/world_view.png rename to docs/source/images/world_view.png diff --git a/docs/source/included.rst b/docs/source/included.rst new file mode 100644 index 00000000000..50fb2e8fd2a --- /dev/null +++ b/docs/source/included.rst @@ -0,0 +1,29 @@ +What's Offered? +================ + +The getting started example uses Docker images to generate the Fabric +network components. The scenario includes a consortium of three +members, each managing and maintaing a peer node, as well as a "SOLO" +:ref:`Ordering-Service` and a Certificate Authority (CA). The cryptographic identity +material, based on standard PKI implementation, has been pre-generated +and is used for signing + verification on both the server (peer + ordering service) +and client (SDK) sides. The CA is the network entity responsible for issuing +and maintaing this identity material, which is necessary for authentication by all +components and participants on the network. This sample uses a single CA. However, +in enterprise scenarios each :ref:`Member` would likely have their own CA, with more +complex security/identity measures implemented - e.g. cross-signing certificates, etc. + +The members will transact on a private channel, with a shared ledger maintained by +each peer node. Requests to read and write data to/from the ledger are sent +as "proposals" to the peers. These proposals are in fact a request for endorsement +from the peer, which will execute the transaction and return a response to the +submitting client. + +The sample demonstrates two methods for interacting with the network - a programmatical +approach exercising the Node.js SDK APIs and a CLI requiring manual commands. + +It's recommended to follow the sample in the order laid forth - application first, +followed by the optional CLI route. + + + diff --git a/docs/source/incubation.rst b/docs/source/incubation.rst new file mode 100644 index 00000000000..c5dddd4c823 --- /dev/null +++ b/docs/source/incubation.rst @@ -0,0 +1,7 @@ +Incubation Notice +================= + +This project is a Hyperledger project in *Incubation*. It was proposed +to the community and documented `here `__. +Information on what *Incubation* entails can be found in the +`Hyperledger Project Lifecycle document `__. diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000000..72b1fcf71c9 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,154 @@ +Welcome to Fabric +================= + +Hyperledger Fabric is a social innovation that is about to free innovators in startups, +enterprises and government to transform and radically reduce the cost of working together +across organizations. By the end of this section, you should have the essential understanding +of Fabric you need to start *knitting* together a great business network. + +Fabric is a network of networks, like the Internet itself. An application can use one or more +networks, each managing different :ref:`Assets`, Agreements and Transactions between different +sets of :ref:`Member` nodes. In Fabric, the Ordering Service is the foundation of each network. +The founder of a network selects an Ordering Service (or creates a new one) and passes in a +config file with the rules (usually called Policies) that govern it. Examples of these rules +include setting/defining which Members can join the network, how Members can be added or removed, +and configuration details like block size. While it is possible for one company to set and control +these rules as a "dictator," typically these rules will also include policies that make changing +the rules a matter of consensus among the members of the network. Fabric also requires some level of +"endorsement" in order to transact. Check out the power and intricacy of :doc:`endorsement-policies` +, which are used across the Fabric landscape - from a consortium's network configuration to a simple +read operation. + +We mentioned that the Ordering Service (OS) is the foundation of the network, and you're probably +thinking, "It must do something beyond just ordering." Well you're right! All members and entities +in the network will be tied to a higher level certificate authority, and this authority is defined +within the configuration of the Ordering Service. As a result, the OS can verify and authenticate +transactions arriving from any corner of the network. The OS plays a central and critical role in +the functionality and integrity of the network, and skeptics might fear too much centralization of +power and responsibility. After all, that's a principal feature of shared ledger technology - to +decentralize the control and provide a foundation of trust with entities who you CAN'T wholeheartedly +trust. Well let's assuage that fear. The OS is agnostic to transaction details; it simply orders on +a first-come-first-serve basis and returns blocks to their corresponding channels. Perhaps more +importantly though, control of the ordering service can be shared and co-administered by the +participating members in the network. OR, if even that solution is untenable, then the OS can be +hosted and maintained by a trusted third-party. Fabric is built upon a modular and pluggable +architecture, so the only real decision for business networks is how to configure an OS to meet +their requirements. + +(This notion of the OS as a pluggable component also opens the door to exciting opportunities for +innovative teams and individuals. Currently there are only a few OS orchestrations - Solo and Kafka. +However, other options such as Intel's PoET or certain BFT flavors could be powerful supplementaries to Fabric, +and help solve challenging use cases.) + +To participate in the Network, each Organization maintains a runtime called a :ref:`Peer`, which will +allow an application to participate in transactions, interact with the Ordering Service, and maintain +a set of ledgers. Notice we said a set of ledgers. One of Fabric's key innovations is the ability to +run multiple :ref:`Channel` s on each network. This is how a network can conduct both highly confidential +bilateral transactions and multilateral, or even public, transactions in the same solution without +everyone having a copy of every transaction or run the code in every agreement. + +Watch how Fabric is `Building a Blockchain for Business `__ . + +If you're still reading, you clearly have some knowledge and an interest in distributed ledger +technology, AND you probably think a key piece is missing. Where is consensus in all of this? Well, +it's embedded in the entire life cycle of a transaction. Transactions come into the network, and the +submitting client's identity is verified and consented upon. Transactions then get executed and endorsed, +and these endorsements are consented upon. Transactions get ordered, and the validity of this order is +consented upon. Finally, transactions get committed to a shared ledger, and each transaction's subsequent +impact on the state of the involved asset(s) is consented upon. Consensus isn't pigeonholed into one +module or one function. It lives and exists throughout the entire DNA of Fabric. Fabric is built +with security at the forefront, not as an afterthought. Members and participating entities operate with +known identities, and no action on the network circumvents the sign/verify/authenticate mandate. Requirements +such as security, privacy and confidentiality are paramount in some manner to nearly all business dealings, +and they, like consensus, are stitched into the very essence of Fabric. + +So what problem do you want to solve? What assets are at stake? Who are the players? What levels of +security and encryption do you need? Fabric is designed to provide an answer and solution to this +challenging collective of questions and beyond. Just like fabric - in the literal sense of the word - is +used in everything from airplane seats to bespoke suits, solutions built on Hyperledger Fabric can range +from diamond provenance to equities trading. Explore the documentation and see how you can leverage Fabric +to craft a PoC for your own business network. + +.. NOTE:: This build of the docs is from the "|version|" branch + +.. toctree:: + :maxdepth: 2 + :caption: Getting Started + + included + asset_setup + +.. toctree:: + :maxdepth: 2 + :caption: Key Concepts + + overview + fabric_model + biz/usecases + + +.. toctree:: + :maxdepth: 2 + :caption: Education + + demos + dockercompose + learn_chaincode + videos + +.. toctree:: + :maxdepth: 2 + :caption: Configuration Considerations + + best_practices + bootstrap + adminops + Setup/logging-control + +.. toctree:: + :maxdepth: 2 + :caption: Architecture + + txflow + arch-deep-dive + Setup/ca-setup + nodesdk + chaincode + endorsement-policies + orderingservice + ledger + readwrite + gossip + +.. toctree:: + :maxdepth: 2 + :caption: Troubleshooting and FAQs + + troubleshooting + FAQ/architecture_FAQ + FAQ/chaincode_FAQ + FAQ/confidentiality_FAQ + FAQ/identity_management_FAQ + +.. toctree:: + :maxdepth: 2 + :caption: Appendix + + glossary + releases + CONTRIBUTING + MAINTAINERS + jira_navigation + dev-setup/devenv + dev-setup/build + Gerrit/lf-account + Gerrit/gerrit + Gerrit/changes + Gerrit/reviewing + Gerrit/best-practices + testing + Style-guides/go-style + questions + quality + incubation + license diff --git a/docs/source/install_instantiate.rst b/docs/source/install_instantiate.rst new file mode 100644 index 00000000000..35698eeaf19 --- /dev/null +++ b/docs/source/install_instantiate.rst @@ -0,0 +1,169 @@ +Install and Instantiate +======================= + +This tutorial requires the latest builds for +``hyperledger/fabric-baseimage``, ``hyperledger/fabric-peer`` and +``hyperledger/fabric-orderer``. Rather than pull from docker hub, you +can compile these images locally to ensure they are up to date. It is up +to the user how to build the images, although a typical approach is +through vagrant. If you do choose to build through vagrant, make sure +you have followed the steps outlined in `setting up the development +environment `__. Then from the fabric directory +within your vagrant environment, execute the ``make peer-docker`` and +``make orderer-docker`` commands. + +Start the network of 2 peers, an orderer, and a CLI +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Navigate to the fabric/docs directory in your vagrant environment and +start your network: + +.. code:: bash + + docker-compose -f docker-2peer.yml up + +View all your containers: + +.. code:: bash + + # active and non-active + docker ps -a + +Get into the CLI container +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now, open a second terminal and navigate once again to your vagrant +environment. + +.. code:: bash + + docker exec -it cli bash + +You should see the following in your terminal: + +.. code:: bash + + root@ccd3308afc73:/opt/gopath/src/github.com/hyperledger/fabric/peer# + +Create and join channel from the remote CLI +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +From your second terminal, lets create a channel by the name of "myc": + +.. code:: bash + + peer channel create -c myc + +This will generate a genesis block - ``myc.block`` - and place it into +the same directory from which you issued your ``peer channel create`` +command. Now, from the same directory, direct both peers to join channel +- ``myc`` - by passing in the genesis block - ``myc.block`` - with a +``peer channel join`` command: + +.. code:: bash + + CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc.block + CORE_PEER_ADDRESS=peer1:7051 peer channel join -b myc.block + +Install the chaincode on peer0 from the remote CLI +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +From your second terminal, and still within the CLI container, issue the +following command to install a chaincode named ``mycc`` with a version +of ``v0`` onto ``peer0``. + +.. code:: bash + + CORE_PEER_ADDRESS=peer0:7051 peer chaincode install -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -v v0 + +Instantiate the chaincode on the channel from the remote CLI +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now, still within the cli container in your second terminal, instantiate +the chaincode ``mycc`` with version ``v0`` onto ``peer0``. This +instantiation will initialize the chaincode with key value pairs of +["a","100"] and ["b","200"]. + +.. code:: bash + + CORE_PEER_ADDRESS=peer0:7051 peer chaincode instantiate -C myc -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -v v0 -c '{"Args":["init","a","100","b","200"]}' + +**Continue operating within your second terminal for the remainder of +the commands** + +Query for the value of "a" to make sure the chaincode container has successfully started +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Send a query to ``peer0`` for the value of key ``"a"``: + +.. code:: bash + + CORE_PEER_ADDRESS=peer0:7051 peer chaincode query -C myc -n mycc -v v0 -c '{"Args":["query","a"]}' + +This query should return "100". + +Invoke to make a state change +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Send an invoke request to ``peer0`` to move 10 units from "a" to "b": + +.. code:: bash + + CORE_PEER_ADDRESS=peer0:7051 peer chaincode invoke -C myc -n mycc -v v0 -c '{"Args":["invoke","a","b","10"]}' + +Query on the second peer +~~~~~~~~~~~~~~~~~~~~~~~~ + +Issue a query against the key "a" to ``peer1``. Recall that ``peer1`` +has successfully joined the channel. + +.. code:: bash + + CORE_PEER_ADDRESS=peer1:7051 peer chaincode query -C myc -n mycc -v v0 -c '{"Args":["query","a"]}' + +This will return an error response because ``peer1`` does not have the +chaincode installed. + +Install on the second peer +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now add the chaincode to ``peer1`` so that you can successfully perform +read/write operations. + +.. code:: bash + + CORE_PEER_ADDRESS=peer1:7051 peer chaincode install -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -v v0 + +| **Note**: The initial instantiation applies to all peers in the + channel, and is affected upon any peer that has the chaincode + installed. Therefore, we installed the chaincode on ``peer0`` in order + to execute the instantiate command through it. +| Now that we want to access the chaincode on ``peer1``, we must install + the chaincode on ``peer1`` as well. In general, a chaincode has to be + installed only on those peers through which the chaincode needs to be + accessed from. In particular, the chaincode must be installed on any + peer receiving endorsement requests for that chaincode. + +Query on the second peer +~~~~~~~~~~~~~~~~~~~~~~~~ + +Now issue the same query request to ``peer1``. + +.. code:: bash + + CORE_PEER_ADDRESS=peer1:7051 peer chaincode query -C myc -n mycc -v v0 -c '{"Args":["query","a"]}' + +Query will now succeed. + +What does this demonstrate? +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- The ability to invoke (alter key value states) is restricted to peers + that have the chaincode installed. +- Just as state changes due to invoke on a peer affects all peers in + the channel, the instantiate on a peer will likewise affect all peers + in the channel. +- The world state of the chaincode is available to all peers on the + channel - even those that do not have the chaincode installed. +- Once the chaincode is installed on a peer, invokes and queries can + access those states normally. diff --git a/docs/source/javasdk.rst b/docs/source/javasdk.rst new file mode 100644 index 00000000000..0dcad8c35ab --- /dev/null +++ b/docs/source/javasdk.rst @@ -0,0 +1,14 @@ +Java SDK +======== + +[WIP] ...coming soon + +In the meantime, refer to the `Hyperledger Fabric SDK design +doc `__ +for more details on the APIs and specifications. + +OR + +Refer to the +`fabric-sdk-java `__ +repository in the Hyperledger community. diff --git a/docs/source/jira_navigation.rst b/docs/source/jira_navigation.rst new file mode 100644 index 00000000000..e72283003de --- /dev/null +++ b/docs/source/jira_navigation.rst @@ -0,0 +1,68 @@ +Using Jira to understand current work items +=========================================== + +This document has been created to give further insight into the work in +progress towards the hyperledger/fabric v1 architecture based off the +community roadmap. The requirements for the roadmap are being tracked in +`Jira `__. + +It was determined to organize in sprints to better track and show a +prioritized order of items to be implemented based on feedback received. +We’ve done this via boards. To see these boards and the priorities click +on **Boards** -> **Manage Boards**: + +.. figure:: images/Jira.png + :alt: Jira boards + + Jira boards + +Now on the left side of the screen click on **All boards**: + +.. figure:: images/Jira1.png + :alt: Jira boards + + Jira boards + +On this page you will see all the public (and restricted) boards that +have been created. If you want to see the items with current sprint +focus, click on the boards where the column labeled **Visibility** is +**All Users** and the column **Board type** is labeled **Scrum**. For +example the **Board Name** Consensus: + +.. figure:: images/Jira2.png + :alt: Jira boards + + Jira boards + +When you click on Consensus under **Board name** you will be directed to +a page that contains the following columns: + +.. figure:: images/Jira3.png + :alt: Jira boards + + Jira boards + +The meanings to these columns are as follows: + +- Backlog – list of items slated for the current sprint (sprints are + defined in 2 week iterations), but are not currently in progress +- In progress – are items currently being worked by someone in the + community. +- In Review – waiting to be reviewed and merged in Gerritt +- Done – merged and complete in the sprint. + +If you want to see all items in the backlog for a given feature set +click on the stacked rows on the left navigation of the screen: + +.. figure:: images/Jira4.png + :alt: Jira boards + + Jira boards + +This shows you items slated for the current sprint at the top, and all +items in the backlog at the bottom. Items are listed in priority order. + +If there is an item you are interested in working on, want more +information or have questions, or if there is an item that you feel +needs to be in higher priority, please add comments directly to the Jira +item. All feedback and help is very much appreciated. diff --git a/docs/source/learn_chaincode.rst b/docs/source/learn_chaincode.rst new file mode 100644 index 00000000000..cb22c969ee1 --- /dev/null +++ b/docs/source/learn_chaincode.rst @@ -0,0 +1,11 @@ +Learn to write chaincode +======================== + +[WIP] ...coming soon + +Teaches a developer how to write chaincode functions and implement the +necessary interfaces to create generic assets. + +In the meantime, visit the learn chaincode repo +`here `__ to +familiarize yourself with high level concepts and go code. diff --git a/docs/source/ledger.rst b/docs/source/ledger.rst new file mode 100644 index 00000000000..69edd74e495 --- /dev/null +++ b/docs/source/ledger.rst @@ -0,0 +1,109 @@ +Ledger +====== + +The ledger is the sequenced, tamper-resistant record of all state transitions in the fabric. State +transitions are a result of chaincode invocations ('transactions') submitted by participating +parties. Each transaction results in a set of asset key-value pairs that are committed to the +ledger as creates, updates, or deletes. + +The ledger is comprised of a blockchain ('chain') to store the immutable, sequenced record in +blocks, as well as a state database to maintain current fabric state. There is one ledger per +channel. Each peer maintains a copy of the ledger for each channel of which they are a member. + +Chain +----- + +The chain is a transaction log, structured as hash-linked blocks, where each block contains a +sequence of N transactions. The block header includes a hash of the block's transactions, as +well as a hash of the prior block's header. In this way, all transactions on the ledger are +sequenced and cryptographically linked together. In other words, it is not possible to tamper with +the ledger data, without breaking the hash links. The hash of the latest block represents every +transaction that has come before, making it possible to ensure that all peers are in a consistent +and trusted state. + +The chain is stored on the peer file system (either local or attached storage), efficiently +supporting the append-only nature of the blockchain workload. + +State Database +-------------- + +The ledger's current state data represents the latest values for all keys ever included in the chain +transaction log. Since current state represents all latest key values known to the channel, it is +sometimes referred to as World State. + +Chaincode invocations execute transactions against the current state data. To make these +chaincode interactions extremely efficient, the latest values of all keys are stored in a state +database. The state database is simply an indexed view into the chain's transaction log, it can +therefore be regenerated from the chain at any time. The state database will automatically get +recovered (or generated if needed) upon peer startup, before transactions are accepted. + +Transaction Flow +---------------- + +At a high level, the transaction flow consists of a transaction proposal sent by an application +client to specific endorsing peers. The endorsing peers verify the client signature, and execute +a chaincode function to simulate the transaction. The output is the chaincode results, +a set of key/value versions that were read in the chaincode (read set), and the set of keys/values +that were written in chaincode (write set). The proposal response gets sent back to the client +along with an endorsement signature. + +The client assembles the endorsements into a transaction payload and broadcasts it to an ordering +service. The ordering service delivers ordered transactions as blocks to all peers on a channel. + +Before committal, peers will validate the transactions. First, they will check the endorsement +policy to ensure that the correct allotment of the specified peers have signed the results, and they +will authenticate the signatures against the transaction payload. + +Secondly, peers will perform a versioning check against the transaction read set, to ensure +data integrity and protect against threats such as double-spending. +The fabric has concurrency control whereby transactions execute in parallel (by endorsers) +to increase throughput, and upon commit (by all peers) each transaction is verified to ensure +that no other transaction has modified data it has read. In other words, it ensures that the data +that was read during chaincode execution has not changed since execution (endorsement) time, +and therefore the execution results are still valid and can be committed to the ledger state +database. If the data that was read has been changed by another transaction, then the +transaction in the block is marked as invalid and is not applied to the ledger state database. +The client application is alerted, and can handle the error or retry as appropriate. + +See the :doc:`txflow` and :doc:`readwrite` topics for a deeper dive on transaction structure, +concurrency control, and the state DB. + +State Database options +---------------------- + +State database options include LevelDB and CouchDB (beta). LevelDB is the default key/value state +database embedded in the peer process. CouchDB is an optional alternative external state database. +Like the LevelDB key/value store, CouchDB can store any binary data that is modeled in chaincode +(CouchDB attachment functionality is used internally for non-JSON binary data). But as a JSON +document store, CouchDB additionally enables rich query against the chaincode data, when chaincode +values (e.g. assets) are modeled as JSON data. + +Both LevelDB and CouchDB support core chaincode operations such as getting and setting a key +(asset), and querying based on keys. Keys can be queried by range, and composite keys can be +modeled to enable equivalence queries against multiple parameters. For example a composite +key of (owner,asset_id) can be used to query all assets owned by a certain entity. These key-based +queries can be used for read-only queries against the ledger, as well as in transactions that +update the ledger. + +If you model assets as JSON and use CouchDB, you can also perform complex rich queries against the +chaincode data values, using the CouchDB JSON query language within chaincode. These types of +queries are excellent for understanding what is on the ledger. Proposal responses for these types +of queries are typically useful to the client application, but are not typically submitted as +transactions to the ordering service. In fact the fabric does not guarantee the result set is stable +between chaincode execution and commit time for rich queries, and therefore rich queries +are not appropriate for use in update transactions, unless your application can guarantee the +result set is stable between chaincode execution time and commit time, or can handle potential +changes in subsequent transactions. For example, if you perform a rich query for all assets +owned by Alice and transfer them to Bob, a new asset may be assigned to Alice by another +transaction between chaincode execution time and commit time, and you would miss this 'phantom' +item. + +CouchDB runs as a separate database process alongside the peer, therefore there are additional +considerations in terms of setup, management, and operations. You may consider starting with the +default embedded LevelDB, and move to CouchDB if you require the additional complex rich queries. +It is a good practice to model chaincode asset data as JSON, so that you have the option to perform +complex rich queries if needed in the future. + +To enable CouchDB as the state database, configure the /fabric/peer/core.yaml ``stateDatabase`` +section. + diff --git a/docs/source/license.rst b/docs/source/license.rst new file mode 100644 index 00000000000..53ac460a7b1 --- /dev/null +++ b/docs/source/license.rst @@ -0,0 +1,5 @@ +License +======== + +The Hyperledger Project uses the `Apache License Version +2.0 `__ software license. diff --git a/docs/source/make.bat b/docs/source/make.bat new file mode 100644 index 00000000000..57be7eb0c8c --- /dev/null +++ b/docs/source/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build +set SPHINXPROJ=hyperledger-fabricdocs + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/source/marbles.rst b/docs/source/marbles.rst new file mode 100644 index 00000000000..bd20de1e57b --- /dev/null +++ b/docs/source/marbles.rst @@ -0,0 +1,12 @@ +Marbles +======= + +[WIP] ...coming soon + +The marbles chaincode application demonstrates the ability to create +assets (marbles) with unique attributes - size, color, owner, etc... and +trade these assets with fellow participants in a blockchain network. It +is not yet stable with v1 codebase. + +Learn more about the marbles chaincode and client-side application +`here `__ diff --git a/docs/source/mdtorst.sh b/docs/source/mdtorst.sh new file mode 100644 index 00000000000..bd8a25e08be --- /dev/null +++ b/docs/source/mdtorst.sh @@ -0,0 +1,11 @@ + +FILES=*.md +for f in $FILES +do + # extension="${f##*.}" + filename="${f%.*}" + echo "Converting $f to $filename.rst" + `pandoc $f -t rst -o $filename.rst` + # uncomment this line to delete the source file. + rm $f +done diff --git a/docs/source/multichannel.rst b/docs/source/multichannel.rst new file mode 100644 index 00000000000..0fc31938b33 --- /dev/null +++ b/docs/source/multichannel.rst @@ -0,0 +1,15 @@ +Multichannel +============ + +[WIP] + +The fabric will allow for multiple channels with a designated ledger per +channel (data segregation). This capability allows for multilateral +contracts where only the restricted participants on the channel will +submit, endorse, order, or commit transactions on that channel.  As +such, a single peer can maintain multiple ledgers without compromising +privacy and confidentiality. + +Refer to the `multichannel design +document `__ +for more detailed explanation on the mechanics and architecture. diff --git a/docs/source/nodesdk.rst b/docs/source/nodesdk.rst new file mode 100644 index 00000000000..922f3102202 --- /dev/null +++ b/docs/source/nodesdk.rst @@ -0,0 +1,15 @@ +Node SDK +======== + +[WIP] ...coming soon + +In the meantime, refer to the `Hyperledger Fabric SDK design +doc `__ +for more details on the APIs and specifications. + +OR + +Refer to the +`fabric-sdk-node `__ +repository in the Hyperledger community. The README will take you through +a simple setup to build HTML output for the API classes and methods. diff --git a/docs/source/orderingservice.rst b/docs/source/orderingservice.rst new file mode 100644 index 00000000000..48de2923c83 --- /dev/null +++ b/docs/source/orderingservice.rst @@ -0,0 +1,14 @@ +Ordering Service +================ + +[WIP] ...coming soon + +This topic will outline the role and functionalities of the ordering +service, and explain its place in the broader network and in the lifecycle of a transaction. +The v1 architecture has been designed such that the ordering service is the centralized point +of trust in a decentralized network, but also such that the specific implementation of "ordering" +(solo, kafka, BFT) becomes a pluggable component. + +Refer to the design document on a `Kafka-based Ordering +Service `__ +for more information on the default v1 implementation. diff --git a/docs/source/overview.rst b/docs/source/overview.rst new file mode 100644 index 00000000000..766806eb6ce --- /dev/null +++ b/docs/source/overview.rst @@ -0,0 +1,19 @@ +Overview +======== + +**Hyperledger Fabric** is a platform for distributed ledger solutions, underpinned +by a modular architecture delivering high degrees of confidentiality, resiliency, +flexibility and scalability. It is designed to support pluggable implementations +of different components, and accomodate the complexity and intricacies that exist +across the economic ecosystem. + +This section provides a high-level overview of key Fabric concepts: + +* :ref:`Assets` +* :ref:`Chaincode` +* :ref:`Ledger-Features` +* :ref:`Privacy-through-Channels` +* :ref:`Security-Membership-Services` +* :ref:`Consensus` + + diff --git a/docs/source/paper.rst b/docs/source/paper.rst new file mode 100644 index 00000000000..d77a586eaaf --- /dev/null +++ b/docs/source/paper.rst @@ -0,0 +1,10 @@ +Commercial Paper +================ + +[WIP] ...coming soon + +Web application demonstrating a commercial trading network and the +issuance and maturation of trades. Not yet stable with v1 codebase. + +Learn more about the application and underlying chaincode +`here `__ diff --git a/docs/source/pluggableos.rst b/docs/source/pluggableos.rst new file mode 100644 index 00000000000..038fccc95ea --- /dev/null +++ b/docs/source/pluggableos.rst @@ -0,0 +1,12 @@ +Pluggable Ordering implementations +================================== + +[WIP] ...coming soon + +This topic is intended to explain how to configure an ordering service +such that it implements a alternate protocol from the default +kafka-based method. + +This JIRA issue outlines the proposal for a Simplified Byzantine Fault +Tolerant consensus protocol - +https://jira.hyperledger.org/browse/FAB-378 diff --git a/docs/source/protocol-spec.rst b/docs/source/protocol-spec.rst new file mode 100644 index 00000000000..ef1244a522a --- /dev/null +++ b/docs/source/protocol-spec.rst @@ -0,0 +1,4839 @@ +Protocol Specification +====================== + +Preface +------- + +This document is the protocol specification for a permissioned +blockchain implementation for industry use-cases. It is not intended to +be a complete explanation of the implementation, but rather a +description of the interfaces and relationships between components in +the system and the application. + +Intended Audience +~~~~~~~~~~~~~~~~~ + +The intended audience for this specification includes the following +groups: + +- Blockchain vendors who want to implement blockchain systems that + conform to this specification +- Tool developers who want to extend the capabilities of the fabric +- Application developers who want to leverage blockchain technologies + to enrich their applications + \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ + +Table of Contents +----------------- + +`1. Introduction <#1-introduction_1>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- `1.1 What is the fabric? <#11-what-is-the-fabric>`__ +- `1.2 Why the fabric? <#12-why-the-fabric>`__ +- `1.3 Terminology <#13-terminology>`__ + +`2. Fabric <#2-fabric_1>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- `2.1 Architecture <#21-architecture>`__ +- `2.1.1 Membership Services <#211-membership-services>`__ +- `2.1.2 Blockchain Services <#212-blockchain-services>`__ +- `2.1.3 Chaincode Services <#213-chaincode-services>`__ +- `2.1.4 Events <#214-events>`__ +- `2.1.5 Application Programming Interface + (API) <#215-application-programming-interface-api>`__ +- `2.1.6 Command Line Interface + (CLI) <#216-command-line-interface-cli>`__ +- `2.2 Topology <#22-topology>`__ +- `2.2.1 Single Validating Peer <#221-single-validating-peer>`__ +- `2.2.2 Multiple Validating Peers <#222-multiple-validating-peers>`__ +- `2.2.3 Multichain <#223-multichain>`__ + +`3. Protocol <#3-protocol_1>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- `3.1 Message <#31-message>`__ +- `3.1.1 Discovery Messages <#311-discovery-messages>`__ +- `3.1.2 Transaction Messages <#312-transaction-messages>`__ +- `3.1.2.1 Transaction Data + Structure <#3121-transaction-data-structure>`__ +- `3.1.2.2 Transaction + Specification <#3122-transaction-specification>`__ +- `3.1.2.3 Deploy Transaction <#3123-deploy-transaction>`__ +- `3.1.2.4 Invoke Transaction <#3124-invoke-transaction>`__ +- `3.1.2.5 Query Transaction <#3125-query-transaction>`__ +- `3.1.3 Synchronization Messages <#313-synchronization-messages>`__ +- `3.1.4 Consensus Messages <#314-consensus-messages>`__ +- `3.2 Ledger <#32-ledger>`__ +- `3.2.1 Blockchain <#321-blockchain>`__ +- `3.2.1.1 Block <#3211-block>`__ +- `3.2.1.2 Block Hashing <#3212-block-hashing>`__ +- `3.2.1.3 NonHashData <#3213-nonhashdata>`__ +- `3.2.1.4 Transaction Execution <#3214-transaction-execution>`__ +- `3.2.2 World State <#322-world-state>`__ +- `3.2.2.1 Hashing the world state <#3221-hashing-the-world-state>`__ +- `3.2.2.1.1 Bucket-tree <#32211-buckettree>`__ +- `3.3 Chaincode <#33-chaincode>`__ +- `3.3.1 Virtual Machine + Instantiation <#331-virtual-machine-instantiation>`__ +- `3.3.2 Chaincode Protocol <#332-chaincode-protocol>`__ +- `3.3.2.1 Chaincode Deploy <#3321-chaincode-deploy>`__ +- `3.3.2.2 Chaincode Invoke <#3322-chaincode-invoke>`__ +- `3.3.2.3 Chaincode Query <#3323-chaincode-query>`__ +- `3.3.2.4 Chaincode State <#3324-chaincode-state>`__ +- `3.4 Pluggable Consensus + Framework <#34-pluggable-consensus-framework>`__ +- `3.4.1 Consenter interface <#341-consenter-interface>`__ +- `3.4.2 CPI interface <#342-cpi-interface>`__ +- `3.4.3 Inquirer interface <#343-inquirer-interface>`__ +- `3.4.4 Communicator interface <#344-communicator-interface>`__ +- `3.4.5 SecurityUtils interface <#345-securityutils-interface>`__ +- `3.4.6 LedgerStack interface <#346-ledgerstack-interface>`__ +- `3.4.7 Executor interface <#347-executor-interface>`__ +- `3.4.7.1 Beginning a transaction + batch <#3471-beginning-a-transaction-batch>`__ +- `3.4.7.2 Executing transactions <#3472-executing-transactions>`__ +- `3.4.7.3 Committing and rolling-back + transactions <#3473-committing-and-rollingback-transactions>`__ +- `3.4.8 Ledger interface <#348-ledger-interface>`__ +- `3.4.8.1 ReadOnlyLedger interface <#3481-readonlyledger-interface>`__ +- `3.4.8.2 UtilLedger interface <#3482-utilledger-interface>`__ +- `3.4.8.3 WritableLedger interface <#3483-writableledger-interface>`__ +- `3.4.9 RemoteLedgers interface <#349-remoteledgers-interface>`__ +- `3.4.10 controller package <#3410-controller-package>`__ +- `3.4.10.1 controller.NewConsenter <#34101-controllernewconsenter>`__ +- `3.4.11 helper package <#3411-helper-package>`__ +- `3.4.11.1 High-level overview <#34111-highlevel-overview>`__ +- `3.4.11.2 helper.ConsensusHandler <#34112-helperconsensushandler>`__ +- `3.4.11.3 + helper.NewConsensusHandler <#34113-helpernewconsensushandler>`__ +- `3.4.11.4 helper.Helper <#34114-helperhelper>`__ +- `3.4.11.5 helper.NewHelper <#34115-helpernewhelper>`__ +- `3.4.11.6 helper.HandleMessage <#34116-helperhandlemessage>`__ +- `3.5 Events <#35-events>`__ +- `3.5.1 Event Stream <#351-event-stream>`__ +- `3.5.1.1 Event Producer <#3511-event-producer>`__ +- `3.5.1.2 Event Consumer <#3512-event-consumer>`__ +- `3.5.2 Event Adapters <#352-event-adapters>`__ +- `3.5.3 Event Structure <#353-event-structure>`__ + +`4. Security <#4-security_1>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- `4.1 Business security + requirements <#41-business-security-requirements>`__ +- `4.2 User Privacy through Membership + Services <#42-user-privacy-through-membership-services>`__ +- `4.2.1 User/Client Enrollment + Process <#421-userclient-enrollment-process>`__ +- `4.2.2 Expiration and revocation of + certificates <#422-expiration-and-revocation-of-certificates>`__ +- `4.3 Transaction security offerings at the infrastructure + level <#43-transaction-security-offerings-at-the-infrastructure-level>`__ +- `4.3.1 Security Lifecycle of + Transactions <#431-security-lifecycle-of-transactions>`__ +- `4.3.2 Transaction + confidentiality <#432-transaction-confidentiality>`__ +- `4.3.2.1 Confidentiality against + users <#4321-confidentiality-against-users>`__ +- `4.3.2.2 Confidentiality against + validators <#4322-confidentiality-against-validators>`__ +- `4.3.3 Replay attack resistance <#433-replay-attack-resistance>`__ +- `4.4 Access control features on the + application <#44-access-control-features-on-the-application>`__ +- `4.4.1 Invocation access control <#441-invocation-access-control>`__ +- `4.4.2 Read access control <#442-read-access-control>`__ +- `4.5 Online wallet service <#45-online-wallet-service>`__ +- `4.6 Network security (TLS) <#46-network-security-tls>`__ +- `4.7 Restrictions in the current + release <#47-restrictions-in-the-current-release>`__ +- `4.7.1 Simplified client <#471-simplified-client>`__ +- `4.7.2 Simplified transaction + confidentiality <#472-simplified-transaction-confidentiality>`__ + +`5. Byzantine Consensus <#5-byzantine-consensus_1>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- `5.1 Overview <#51-overview>`__ +- `5.2 Core PBFT Functions <#52-core-pbft-functions>`__ +- `5.2.1 newPbftCore <#521-newpbftcore>`__ + +`6. Application Programming Interface <#6-application-programming-interface_1>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- `6.1 REST Service <#61-rest-service>`__ +- `6.2 REST API <#62-rest-api>`__ +- `6.2.1 REST Endpoints <#621-rest-endpoints>`__ +- `6.2.1.1 Block API <#6211-block-api>`__ +- `6.2.1.2 Blockchain API <#6212-blockchain-api>`__ +- `6.2.1.3 Chaincode API <#6213-chaincode-api>`__ +- `6.2.1.4 Network API <#6214-network-api>`__ +- `6.2.1.5 Registrar API (member + services) <#6215-registrar-api-member-services>`__ +- `6.2.1.6 Transactions API <#6216-transactions-api>`__ +- `6.3 CLI <#63-cli>`__ +- `6.3.1 CLI Commands <#631-cli-commands>`__ +- `6.3.1.1 node start <#6311-node-start>`__ +- `6.3.1.2 network login <#6312-network-login>`__ +- `6.3.1.3 chaincode deploy <#6313-chaincode-deploy>`__ +- `6.3.1.4 chaincode invoke <#6314-chaincode-invoke>`__ +- `6.3.1.5 chaincode query <#6315-chaincode-query>`__ + +`7. Application Model <#7-application-model_1>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- `7.1 Composition of an + Application <#71-composition-of-an-application>`__ +- `7.2 Sample Application <#72-sample-application>`__ + +`8. Future Directions <#8-future-directions_1>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- `8.1 Enterprise Integration <#81-enterprise-integration>`__ +- `8.2 Performance and Scalability <#82-performance-and-scalability>`__ +- `8.3 Additional Consensus + Plugins <#83-additional-consensus-plugins>`__ +- `8.4 Additional Languages <#84-additional-languages>`__ + +`9.1 Authors <#91-authors>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +`9.2 Reviewers <#92-reviewers>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +`9.3 Acknowledgements <#93-acknowledgements>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +`10. References <#10-references_1>`__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +-------------- + +1. Introduction +--------------- + +This document specifies the principles, architecture, and protocol of a +blockchain implementation suitable for industrial use-cases. + +1.1 What is the fabric? +~~~~~~~~~~~~~~~~~~~~~~~ + +The fabric is a ledger of digital events, called transactions, shared +among different participants, each having a stake in the system. The +ledger can only be updated by consensus of the participants, and, once +recorded, information can never be altered. Each recorded event is +cryptographically verifiable with proof of agreement from the +participants. + +Transactions are secured, private, and confidential. Each participant +registers with proof of identity to the network membership services to +gain access to the system. Transactions are issued with derived +certificates unlinkable to the individual participant, offering a +complete anonymity on the network. Transaction content is encrypted with +sophisticated key derivation functions to ensure only intended +participants may see the content, protecting the confidentiality of the +business transactions. + +The ledger allows compliance with regulations as ledger entries are +auditable in whole or in part. In collaboration with participants, +auditors may obtain time-based certificates to allow viewing the ledger +and linking transactions to provide an accurate assessment of the +operations. + +The fabric is an implementation of blockchain technology, where Bitcoin +could be a simple application built on the fabric. It is a modular +architecture allowing components to be plug-and-play by implementing +this protocol specification. It features powerful container technology +to host any main stream language for smart contracts development. +Leveraging familiar and proven technologies is the motto of the fabric +architecture. + +1.2 Why the fabric? +~~~~~~~~~~~~~~~~~~~ + +Early blockchain technology serves a set of purposes but is often not +well-suited for the needs of specific industries. To meet the demands of +modern markets, the fabric is based on an industry-focused design that +addresses the multiple and varied requirements of specific industry use +cases, extending the learning of the pioneers in this field while also +addressing issues such as scalability. The fabric provides a new +approach to enable permissioned networks, privacy, and confidentially on +multiple blockchain networks. + +1.3 Terminology +~~~~~~~~~~~~~~~ + +The following terminology is defined within the limited scope of this +specification to help readers understand clearly and precisely the +concepts described here. + +**Transaction** is a request to the blockchain to execute a function on +the ledger. The function is implemented by a **chaincode**. + +**Transactor** is an entity that issues transactions such as a client +application. + +**Ledger** is a sequence of cryptographically linked blocks, containing +transactions and current **world state**. + +**World State** is the collection of variables containing the results of +executed transactions. + +**Chaincode** is an application-level code (a.k.a. `smart +contract `__) stored on +the ledger as a part of a transaction. Chaincode runs transactions that +may modify the world state. + +**Validating Peer** is a computer node on the network responsible for +running consensus, validating transactions, and maintaining the ledger. + +**Non-validating Peer** is a computer node on the network which +functions as a proxy connecting transactors to the neighboring +validating peers. A non-validating peer doesn't execute transactions but +does verify them. It also hosts the event stream server and the REST +service. + +**Permissioned Ledger** is a blockchain network where each entity or +node is required to be a member of the network. Anonymous nodes are not +allowed to connect. + +**Privacy** is required by the chain transactors to conceal their +identities on the network. While members of the network may examine the +transactions, the transactions can't be linked to the transactor without +special privilege. + +**Confidentiality** is the ability to render the transaction content +inaccessible to anyone other than the stakeholders of the transaction. + +**Auditability** of the blockchain is required, as business usage of +blockchain needs to comply with regulations to make it easy for +regulators to investigate transaction records. + +2. Fabric +--------- + +The fabric is made up of the core components described in the +subsections below. + +2.1 Architecture +~~~~~~~~~~~~~~~~ + +The reference architecture is aligned in 3 categories: Membership, +Blockchain, and Chaincode services. These categories are logical +structures, not a physical depiction of partitioning of components into +separate processes, address spaces or (virtual) machines. + +.. figure:: images/refarch.png + :alt: Reference architecture + + Reference architecture + +2.1.1 Membership Services +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Membership provides services for managing identity, privacy, +confidentiality and auditability on the network. In a non-permissioned +blockchain, participation does not require authorization and all nodes +can equally submit transactions and/or attempt to accumulate them into +acceptable blocks, i.e. there are no distinctions of roles. Membership +services combine elements of Public Key Infrastructure (PKI) and +decentralization/consensus to transform a non-permissioned blockchain +into a permissioned blockchain. In the latter, entities register in +order to acquire long-term identity credentials (enrollment +certificates), and may be distinguished according to entity type. In the +case of users, such credentials enable the Transaction Certificate +Authority (TCA) to issue pseudonymous credentials. Such credentials, +i.e., transaction certificates, are used to authorize submitted +transactions. Transaction certificates persist on the blockchain, and +enable authorized auditors to cluster otherwise unlinkable transactions. + +2.1.2 Blockchain Services +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Blockchain services manage the distributed ledger through a peer-to-peer +protocol, built on HTTP/2. The data structures are highly optimized to +provide the most efficient hash algorithm for maintaining the world +state replication. Different consensus (PBFT, Raft, PoW, PoS) may be +plugged in and configured per deployment. + +2.1.3 Chaincode Services +^^^^^^^^^^^^^^^^^^^^^^^^ + +Chaincode services provides a secured and lightweight way to sandbox the +chaincode execution on the validating nodes. The environment is a +“locked down” and secured container along with a set of signed base +images containing secure OS and chaincode language, runtime and SDK +layers for Go, Java, and Node.js. Other languages can be enabled if +required. + +2.1.4 Events +^^^^^^^^^^^^ + +Validating peers and chaincodes can emit events on the network that +applications may listen for and take actions on. There is a set of +pre-defined events, and chaincodes can generate custom events. Events +are consumed by 1 or more event adapters. Adapters may further deliver +events using other vehicles such as Web hooks or Kafka. + +2.1.5 Application Programming Interface (API) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The primary interface to the fabric is a REST API and its variations +over Swagger 2.0. The API allows applications to register users, query +the blockchain, and to issue transactions. There is a set of APIs +specifically for chaincode to interact with the stack to execute +transactions and query transaction results. + +2.1.6 Command Line Interface (CLI) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +CLI includes a subset of the REST API to enable developers to quickly +test chaincodes or query for status of transactions. CLI is implemented +in Golang and operable on multiple OS platforms. + +2.2 Topology +~~~~~~~~~~~~ + +A deployment of the fabric can consist of a membership service, many +validating peers, non-validating peers, and 1 or more applications. All +of these components make up a chain. There can be multiple chains; each +one having its own operating parameters and security requirements. + +2.2.1 Single Validating Peer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Functionally, a non-validating peer is a subset of a validating peer; +that is, every capability on a non-validating peer may be enabled on a +validating peer, so the simplest network may consist of a single +validating peer node. This configuration is most appropriate for a +development environment, where a single validating peer may be started +up during the edit-compile-debug cycle. + +.. figure:: images/top-single-peer.png + :alt: Single Validating Peer + + Single Validating Peer + +A single validating peer doesn't require consensus, and by default uses +the ``noops`` plugin, which executes transactions as they arrive. This +gives the developer an immediate feedback during development. + +2.2.2 Multiple Validating Peers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Production or test networks should be made up of multiple validating and +non-validating peers as necessary. Non-validating peers can take +workload off the validating peers, such as handling API requests and +processing events. + +.. figure:: images/top-multi-peer.png + :alt: Multiple Validating Peers + + Multiple Validating Peers + +The validating peers form a mesh-network (every validating peer connects +to every other validating peer) to disseminate information. A +non-validating peer connects to a neighboring validating peer that it is +allowed to connect to. Non-validating peers are optional since +applications may communicate directly with validating peers. + +2.2.3 Multichain +^^^^^^^^^^^^^^^^ + +Each network of validating and non-validating peers makes up a chain. +Many chains may be created to address different needs, similar to having +multiple Web sites, each serving a different purpose. + +3. Protocol +----------- + +The fabric's peer-to-peer communication is built on +`gRPC `__, which allows bi-directional +stream-based messaging. It uses `Protocol +Buffers `__ to serialize +data structures for data transfer between peers. Protocol buffers are a +language-neutral, platform-neutral and extensible mechanism for +serializing structured data. Data structures, messages, and services are +described using `proto3 +language `__ +notation. + +3.1 Message +~~~~~~~~~~~ + +Messages passed between nodes are encapsulated by ``Message`` proto +structure, which consists of 4 types: Discovery, Transaction, +Synchronization, and Consensus. Each type may define more subtypes +embedded in the ``payload``. + +:: + + message Message { + enum Type { + UNDEFINED = 0; + + DISC_HELLO = 1; + DISC_DISCONNECT = 2; + DISC_GET_PEERS = 3; + DISC_PEERS = 4; + DISC_NEWMSG = 5; + + CHAIN_STATUS = 6; + CHAIN_TRANSACTION = 7; + CHAIN_GET_TRANSACTIONS = 8; + CHAIN_QUERY = 9; + + SYNC_GET_BLOCKS = 11; + SYNC_BLOCKS = 12; + SYNC_BLOCK_ADDED = 13; + + SYNC_STATE_GET_SNAPSHOT = 14; + SYNC_STATE_SNAPSHOT = 15; + SYNC_STATE_GET_DELTAS = 16; + SYNC_STATE_DELTAS = 17; + + RESPONSE = 20; + CONSENSUS = 21; + } + Type type = 1; + bytes payload = 2; + google.protobuf.Timestamp timestamp = 3; + } + +The ``payload`` is an opaque byte array containing other objects such as +``Transaction`` or ``Response`` depending on the type of the message. +For example, if the ``type`` is ``CHAIN_TRANSACTION``, the ``payload`` +is a ``Transaction`` object. + +3.1.1 Discovery Messages +^^^^^^^^^^^^^^^^^^^^^^^^ + +Upon start up, a peer runs discovery protocol if +``CORE_PEER_DISCOVERY_ROOTNODE`` is specified. +``CORE_PEER_DISCOVERY_ROOTNODE`` is the IP address of another peer on +the network (any peer) that serves as the starting point for discovering +all the peers on the network. The protocol sequence begins with +``DISC_HELLO``, whose ``payload`` is a ``HelloMessage`` object, +containing its endpoint: + +:: + + message HelloMessage { + PeerEndpoint peerEndpoint = 1; + uint64 blockNumber = 2; + } + message PeerEndpoint { + PeerID ID = 1; + string address = 2; + enum Type { + UNDEFINED = 0; + VALIDATOR = 1; + NON_VALIDATOR = 2; + } + Type type = 3; + bytes pkiID = 4; + } + + message PeerID { + string name = 1; + } + +**Definition of fields:** + +- ``PeerID`` is any name given to the peer at start up or defined in + the config file +- ``PeerEndpoint`` describes the endpoint and whether it's a validating + or a non-validating peer +- ``pkiID`` is the cryptographic ID of the peer +- ``address`` is host or IP address and port of the peer in the format + ``ip:port`` +- ``blockNumber`` is the height of the blockchain the peer currently + has + +If the block height received upon ``DISC_HELLO`` is higher than the +current block height of the peer, it immediately initiates the +synchronization protocol to catch up with the network. + +After ``DISC_HELLO``, peer sends ``DISC_GET_PEERS`` periodically to +discover any additional peers joining the network. In response to +``DISC_GET_PEERS``, a peer sends ``DISC_PEERS`` with ``payload`` +containing an array of ``PeerEndpoint``. Other discovery message types +are not used at this point. + +3.1.2 Transaction Messages +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There are 3 types of transactions: Deploy, Invoke and Query. A deploy +transaction installs the specified chaincode on the chain, while invoke +and query transactions call a function of a deployed chaincode. Another +type in consideration is Create transaction, where a deployed chaincode +may be instantiated on the chain and is addressable. This type has not +been implemented as of this writing. + +3.1.2.1 Transaction Data Structure +'''''''''''''''''''''''''''''''''' + +Messages with type ``CHAIN_TRANSACTION`` or ``CHAIN_QUERY`` carry a +``Transaction`` object in the ``payload``: + +:: + + message Transaction { + enum Type { + UNDEFINED = 0; + CHAINCODE_DEPLOY = 1; + CHAINCODE_INVOKE = 2; + CHAINCODE_QUERY = 3; + CHAINCODE_TERMINATE = 4; + } + Type type = 1; + string uuid = 5; + bytes chaincodeID = 2; + bytes payloadHash = 3; + + ConfidentialityLevel confidentialityLevel = 7; + bytes nonce = 8; + bytes cert = 9; + bytes signature = 10; + + bytes metadata = 4; + google.protobuf.Timestamp timestamp = 6; + } + + message TransactionPayload { + bytes payload = 1; + } + + enum ConfidentialityLevel { + PUBLIC = 0; + CONFIDENTIAL = 1; + } + +**Definition of fields:** - ``type`` - The type of the transaction, +which is 1 of the following: - ``UNDEFINED`` - Reserved for future use. +- ``CHAINCODE_DEPLOY`` - Represents the deployment of a new chaincode. - +``CHAINCODE_INVOKE`` - Represents a chaincode function execution that +may read and modify the world state. - ``CHAINCODE_QUERY`` - Represents +a chaincode function execution that may only read the world state. - +``CHAINCODE_TERMINATE`` - Marks a chaincode as inactive so that future +functions of the chaincode can no longer be invoked. - ``chaincodeID`` - +The ID of a chaincode which is a hash of the chaincode source, path to +the source code, constructor function, and parameters. - ``payloadHash`` +- Bytes defining the hash of ``TransactionPayload.payload``. - +``metadata`` - Bytes defining any associated transaction metadata that +the application may use. - ``uuid`` - A unique ID for the transaction. - +``timestamp`` - A timestamp of when the transaction request was received +by the peer. - ``confidentialityLevel`` - Level of data confidentiality. +There are currently 2 levels. Future releases may define more levels. - +``nonce`` - Used for security. - ``cert`` - Certificate of the +transactor. - ``signature`` - Signature of the transactor. - +``TransactionPayload.payload`` - Bytes defining the payload of the +transaction. As the payload can be large, only the payload hash is +included directly in the transaction message. + +More detail on transaction security can be found in section 4. + +3.1.2.2 Transaction Specification +''''''''''''''''''''''''''''''''' + +A transaction is always associated with a chaincode specification which +defines the chaincode and the execution environment such as language and +security context. Currently there is an implementation that uses Golang +for writing chaincode. Other languages may be added in the future. + +:: + + message ChaincodeSpec { + enum Type { + UNDEFINED = 0; + GOLANG = 1; + NODE = 2; + } + Type type = 1; + ChaincodeID chaincodeID = 2; + ChaincodeInput input = 3; + int32 timeout = 4; + string secureContext = 5; + ConfidentialityLevel confidentialityLevel = 6; + bytes metadata = 7; + } + + message ChaincodeID { + string path = 1; + string name = 2; + } + + message ChaincodeInput { + string function = 1; + repeated string args = 2; + } + +**Definition of fields:** - ``chaincodeID`` - The chaincode source code +path and name. - ``input`` - Function name and argument parameters to +call. - ``timeout`` - Time in milliseconds to execute the transaction. - +``confidentialityLevel`` - Confidentiality level of this transaction. - +``secureContext`` - Security context of the transactor. - ``metadata`` - +Any data the application wants to pass along. + +The peer, receiving the ``chaincodeSpec``, wraps it in an appropriate +transaction message and broadcasts to the network. + +3.1.2.3 Deploy Transaction +'''''''''''''''''''''''''' + +Transaction ``type`` of a deploy transaction is ``CHAINCODE_DEPLOY`` and +the payload contains an object of ``ChaincodeDeploymentSpec``. + +:: + + message ChaincodeDeploymentSpec { + ChaincodeSpec chaincodeSpec = 1; + google.protobuf.Timestamp effectiveDate = 2; + bytes codePackage = 3; + } + +**Definition of fields:** - ``chaincodeSpec`` - See section 3.1.2.2, +above. - ``effectiveDate`` - Time when the chaincode is ready to accept +invocations. - ``codePackage`` - gzip of the chaincode source. + +The validating peers always verify the hash of the ``codePackage`` when +they deploy the chaincode to make sure the package has not been tampered +with since the deploy transaction entered the network. + +3.1.2.4 Invoke Transaction +'''''''''''''''''''''''''' + +Transaction ``type`` of an invoke transaction is ``CHAINCODE_INVOKE`` +and the ``payload`` contains an object of ``ChaincodeInvocationSpec``. + +:: + + message ChaincodeInvocationSpec { + ChaincodeSpec chaincodeSpec = 1; + } + +3.1.2.5 Query Transaction +''''''''''''''''''''''''' + +A query transaction is similar to an invoke transaction, but the message +``type`` is ``CHAINCODE_QUERY``. + +3.1.3 Synchronization Messages +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Synchronization protocol starts with discovery, described above in +section 3.1.1, when a peer realizes that it's behind or its current +block is not the same with others. A peer broadcasts either +``SYNC_GET_BLOCKS``, ``SYNC_STATE_GET_SNAPSHOT``, or +``SYNC_STATE_GET_DELTAS`` and receives ``SYNC_BLOCKS``, +``SYNC_STATE_SNAPSHOT``, or ``SYNC_STATE_DELTAS`` respectively. + +The installed consensus plugin (e.g. pbft) dictates how synchronization +protocol is being applied. Each message is designed for a specific +situation: + +**SYNC\_GET\_BLOCKS** requests for a range of contiguous blocks +expressed in the message ``payload``, which is an object of +``SyncBlockRange``. The correlationId specified is included in the +``SyncBlockRange`` of any replies to this message. + +:: + + message SyncBlockRange { + uint64 correlationId = 1; + uint64 start = 2; + uint64 end = 3; + } + +A receiving peer responds with a ``SYNC_BLOCKS`` message whose +``payload`` contains an object of ``SyncBlocks`` + +:: + + message SyncBlocks { + SyncBlockRange range = 1; + repeated Block blocks = 2; + } + +The ``start`` and ``end`` indicate the starting and ending blocks +inclusively. The order in which blocks are returned is defined by the +``start`` and ``end`` values. For example, if ``start``\ =3 and +``end``\ =5, the order of blocks will be 3, 4, 5. If ``start``\ =5 and +``end``\ =3, the order will be 5, 4, 3. + +**SYNC\_STATE\_GET\_SNAPSHOT** requests for the snapshot of the current +world state. The ``payload`` is an object of +``SyncStateSnapshotRequest`` + +:: + + message SyncStateSnapshotRequest { + uint64 correlationId = 1; + } + +The ``correlationId`` is used by the requesting peer to keep track of +the response messages. A receiving peer replies with +``SYNC_STATE_SNAPSHOT`` message whose ``payload`` is an instance of +``SyncStateSnapshot`` + +:: + + message SyncStateSnapshot { + bytes delta = 1; + uint64 sequence = 2; + uint64 blockNumber = 3; + SyncStateSnapshotRequest request = 4; + } + +This message contains the snapshot or a chunk of the snapshot on the +stream, and in which case, the sequence indicate the order starting at +0. The terminating message will have len(delta) == 0. + +**SYNC\_STATE\_GET\_DELTAS** requests for the state deltas of a range of +contiguous blocks. By default, the Ledger maintains 500 transition +deltas. A delta(j) is a state transition between block(i) and block(j) +where i = j-1. The message ``payload`` contains an instance of +``SyncStateDeltasRequest`` + +:: + + message SyncStateDeltasRequest { + SyncBlockRange range = 1; + } + +A receiving peer responds with ``SYNC_STATE_DELTAS``, whose ``payload`` +is an instance of ``SyncStateDeltas`` + +:: + + message SyncStateDeltas { + SyncBlockRange range = 1; + repeated bytes deltas = 2; + } + +A delta may be applied forward (from i to j) or backward (from j to i) +in the state transition. + +3.1.4 Consensus Messages +^^^^^^^^^^^^^^^^^^^^^^^^ + +Consensus deals with transactions, so a ``CONSENSUS`` message is +initiated internally by the consensus framework when it receives a +``CHAIN_TRANSACTION`` message. The framework converts +``CHAIN_TRANSACTION`` into ``CONSENSUS`` then broadcasts to the +validating nodes with the same ``payload``. The consensus plugin +receives this message and process according to its internal algorithm. +The plugin may create custom subtypes to manage consensus finite state +machine. See section 3.4 for more details. + +3.2 Ledger +~~~~~~~~~~ + +The ledger consists of two primary pieces, the blockchain and the world +state. The blockchain is a series of linked blocks that is used to +record transactions within the ledger. The world state is a key-value +database that chaincodes may use to store state when executed by a +transaction. + +3.2.1 Blockchain +^^^^^^^^^^^^^^^^ + +3.2.1.1 Block +''''''''''''' + +The blockchain is defined as a linked list of blocks as each block +contains the hash of the previous block in the chain. The two other +important pieces of information that a block contains are the list of +transactions contained within the block and the hash of the world state +after executing all transactions in the block. + +:: + + message Block { + version = 1; + google.protobuf.Timestamp timestamp = 2; + bytes transactionsHash = 3; + bytes stateHash = 4; + bytes previousBlockHash = 5; + bytes consensusMetadata = 6; + NonHashData nonHashData = 7; + } + + message BlockTransactions { + repeated Transaction transactions = 1; + } + +- ``version`` - Version used to track any protocol changes. +- ``timestamp`` - The timestamp to be filled in by the block proposer. +- ``transactionsHash`` - The merkle root hash of the block's + transactions. +- ``stateHash`` - The merkle root hash of the world state. +- ``previousBlockHash`` - The hash of the previous block. +- ``consensusMetadata`` - Optional metadata that the consensus may + include in a block. +- ``nonHashData`` - A ``NonHashData`` message that is set to nil before + computing the hash of the block, but stored as part of the block in + the database. +- ``BlockTransactions.transactions`` - An array of Transaction + messages. Transactions are not included in the block directly due to + their size. + +3.2.1.2 Block Hashing +''''''''''''''''''''' + +- The ``previousBlockHash`` hash is calculated using the following + algorithm. + +1. Serialize the Block message to bytes using the protocol buffer + library. + +2. Hash the serialized block message to 512 bits of output using the + SHA3 SHAKE256 algorithm as described in `FIPS + 202 `__. + +- The ``transactionHash`` is the root of the transaction merkle tree. + Defining the merkle tree implementation is a TODO. + +- The ``stateHash`` is defined in section 3.2.2.1. + +3.2.1.3 NonHashData +''''''''''''''''''' + +The NonHashData message is used to store block metadata that is not +required to be the same value on all peers. These are suggested values. + +:: + + message NonHashData { + google.protobuf.Timestamp localLedgerCommitTimestamp = 1; + repeated TransactionResult transactionResults = 2; + } + + message TransactionResult { + string uuid = 1; + bytes result = 2; + uint32 errorCode = 3; + string error = 4; + } + +- ``localLedgerCommitTimestamp`` - A timestamp indicating when the + block was commited to the local ledger. + +- ``TransactionResult`` - An array of transaction results. + +- ``TransactionResult.uuid`` - The ID of the transaction. + +- ``TransactionResult.result`` - The return value of the transaction. + +- ``TransactionResult.errorCode`` - A code that can be used to log + errors associated with the transaction. + +- ``TransactionResult.error`` - A string that can be used to log errors + associated with the transaction. + +3.2.1.4 Transaction Execution +''''''''''''''''''''''''''''' + +A transaction defines either the deployment of a chaincode or the +execution of a chaincode. All transactions within a block are run before +recording a block in the ledger. When chaincodes execute, they may +modify the world state. The hash of the world state is then recorded in +the block. + +3.2.2 World State +^^^^^^^^^^^^^^^^^ + +The *world state* of a peer refers to the collection of the *states* of +all the deployed chaincodes. Further, the state of a chaincode is +represented as a collection of key-value pairs. Thus, logically, the +world state of a peer is also a collection of key-value pairs where key +consists of a tuple ``{chaincodeID, ckey}``. Here, we use the term +``key`` to represent a key in the world state i.e., a tuple +``{chaincodeID, ckey}`` and we use the term ``cKey`` to represent a +unique key within a chaincode. + +For the purpose of the description below, ``chaincodeID`` is assumed to +be a valid utf8 string and ``ckey`` and the ``value`` can be a sequence +of one or more arbitrary bytes. + +3.2.2.1 Hashing the world state +''''''''''''''''''''''''''''''' + +During the functioning of a network, many occasions such as committing +transactions and synchronizing peers may require computing a crypto-hash +of the world state observed by a peer. For instance, the consensus +protocol may require to ensure that a *minimum* number of peers in the +network observe the same world state. + +Since, computing the crypto-hash of the world state could be an +expensive operation, this is highly desirable to organize the world +state such that it enables an efficient crypto-hash computation of the +world state when a change occurs in the world state. Further, different +organization designs may be suitable under different workloads +conditions. + +Because the fabric is expected to function under a variety of scenarios +leading to different workloads conditions, a pluggable mechanism is +supported for organizing the world state. + +3.2.2.1.1 Bucket-tree + + +*Bucket-tree* is one of the implementations for organizing the world +state. For the purpose of the description below, a key in the world +state is represented as a concatenation of the two components +(``chaincodeID`` and ``ckey``) separated by a ``nil`` byte i.e., ``key`` += ``chaincodeID``\ +\ ``nil``\ +\ ``cKey``. + +This method models a *merkle-tree* on top of buckets of a *hash table* +in order to compute the crypto-hash of the *world state*. + +At the core of this method, the *key-values* of the world state are +assumed to be stored in a hash-table that consists of a pre-decided +number of buckets (``numBuckets``). A hash function (``hashFunction``) +is employed to determine the bucket number that should contain a given +key. Please note that the ``hashFunction`` does not represent a +crypto-hash method such as SHA3, rather this is a regular programming +language hash function that decides the bucket number for a given key. + +For modeling the merkle-tree, the ordered buckets act as leaf nodes of +the tree - lowest numbered bucket being the left most leaf node in the +tree. For constructing the second-last level of the tree, a pre-decided +number of leaf nodes (``maxGroupingAtEachLevel``), starting from left, +are grouped together and for each such group, a node is inserted at the +second-last level that acts as a common parent for all the leaf nodes in +the group. Note that the number of children for the last parent node may +be less than ``maxGroupingAtEachLevel``. This grouping method of +constructing the next higher level is repeated until the root node of +the tree is constructed. + +An example setup with configuration +``{numBuckets=10009 and maxGroupingAtEachLevel=10}`` will result in a +tree with number of nodes at different level as depicted in the +following table. + ++---------+-------------------+ +| Level | Number of nodes | ++=========+===================+ +| 0 | 1 | ++---------+-------------------+ +| 1 | 2 | ++---------+-------------------+ +| 2 | 11 | ++---------+-------------------+ +| 3 | 101 | ++---------+-------------------+ +| 4 | 1001 | ++---------+-------------------+ +| 5 | 10009 | ++---------+-------------------+ + +For computing the crypto-hash of the world state, the crypto-hash of +each bucket is computed and is assumed to be the crypto-hash of +leaf-nodes of the merkle-tree. In order to compute crypto-hash of a +bucket, the key-values present in the bucket are first serialized and +crypto-hash function is applied on the serialized bytes. For serializing +the key-values of a bucket, all the key-values with a common chaincodeID +prefix are serialized separately and then appending together, in the +ascending order of chaincodeIDs. For serializing the key-values of a +chaincodeID, the following information is concatenated: 1. Length of +chaincodeID (number of bytes in the chaincodeID) - The utf8 bytes of the +chaincodeID - Number of key-values for the chaincodeID - For each +key-value (in sorted order of the ckey) - Length of the ckey - ckey +bytes - Length of the value - value bytes + +For all the numeric types in the above list of items (e.g., Length of +chaincodeID), protobuf's varint encoding is assumed to be used. The +purpose of the above encoding is to achieve a byte representation of the +key-values within a bucket that can not be arrived at by any other +combination of key-values and also to reduce the overall size of the +serialized bytes. + +For example, consider a bucket that contains three key-values namely, +``chaincodeID1_key1:value1, chaincodeID1_key2:value2, and chaincodeID2_key1:value1``. +The serialized bytes for the bucket would logically look as - +``12 + chaincodeID1 + 2 + 4 + key1 + 6 + value1 + 4 + key2 + 6 + value2 + 12 + chaincodeID2 + 1 + 4 + key1 + 6 + value1`` + +If a bucket has no key-value present, the crypto-hash is considered as +``nil``. + +The crypto-hash of an intermediate node and root node are computed just +like in a standard merkle-tree i.e., applying a crypto-hash function on +the bytes obtained by concatenating the crypto-hash of all the children +nodes, from left to right. Further, if a child has a crypto-hash as +``nil``, the crypto-hash of the child is omitted when concatenating the +children crypto-hashes. If the node has a single child, the crypto-hash +of the child is assumed to be the crypto-hash of the node. Finally, the +crypto-hash of the root node is considered as the crypto-hash of the +world state. + +The above method offers performance benefits for computing crypto-hash +when a few key-values change in the state. The major benefits include - +Computation of crypto-hashes of the unchanged buckets can be skipped - +The depth and breadth of the merkle-tree can be controlled by +configuring the parameters ``numBuckets`` and +``maxGroupingAtEachLevel``. Both depth and breadth of the tree has +different implication on the performance cost incurred by and resource +demand of different resources (namely - disk I/O, storage, and memory) + +In a particular deployment, all the peer nodes are expected to use same +values for the configurations +``numBuckets, maxGroupingAtEachLevel, and hashFunction``. Further, if +any of these configurations are to be changed at a later stage, the +configurations should be changed on all the peer nodes so that the +comparison of crypto-hashes across peer nodes is meaningful. Also, this +may require to migrate the existing data based on the implementation. +For example, an implementation is expected to store the last computed +crypto-hashes for all the nodes in the tree which would need to be +recalculated. + +3.3 Chaincode +~~~~~~~~~~~~~ + +Chaincode is an application-level code deployed as a transaction (see +section 3.1.2) to be distributed to the network and managed by each +validating peer as isolated sandbox. Though any virtualization +technology can support the sandbox, currently Docker container is +utilized to run the chaincode. The protocol described in this section +enables different virtualization support implementation to plug and +play. + +3.3.1 Virtual Machine Instantiation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A virtual machine implements the VM interface: + +:: + + type VM interface { + build(ctxt context.Context, id string, args []string, env []string, attachstdin bool, attachstdout bool, reader io.Reader) error + start(ctxt context.Context, id string, args []string, env []string, attachstdin bool, attachstdout bool) error + stop(ctxt context.Context, id string, timeout uint, dontkill bool, dontremove bool) error + } + +The fabric instantiates the VM when it processes a Deploy transaction or +other transactions on the chaincode while the VM for that chaincode is +not running (either crashed or previously brought down due to +inactivity). Each chaincode image is built by the ``build`` function, +started by ``start`` and stopped by ``stop`` function. + +Once the chaincode container is up, it makes a gRPC connection back to +the validating peer that started the chaincode, and that establishes the +channel for Invoke and Query transactions on the chaincode. + +3.3.2 Chaincode Protocol +^^^^^^^^^^^^^^^^^^^^^^^^ + +Communication between a validating peer and its chaincodes is based on a +bidirectional gRPC stream. There is a shim layer on the chaincode +container to handle the message protocol between the chaincode and the +validating peer using protobuf message. + +:: + + message ChaincodeMessage { + + enum Type { + UNDEFINED = 0; + REGISTER = 1; + REGISTERED = 2; + INIT = 3; + READY = 4; + TRANSACTION = 5; + COMPLETED = 6; + ERROR = 7; + GET_STATE = 8; + PUT_STATE = 9; + DEL_STATE = 10; + INVOKE_CHAINCODE = 11; + INVOKE_QUERY = 12; + RESPONSE = 13; + QUERY = 14; + QUERY_COMPLETED = 15; + QUERY_ERROR = 16; + GET_STATE_BY_RANGE = 17; + } + + Type type = 1; + google.protobuf.Timestamp timestamp = 2; + bytes payload = 3; + string uuid = 4; + } + +**Definition of fields:** - ``Type`` is the type of the message. - +``payload`` is the payload of the message. Each payload depends on the +``Type``. - ``uuid`` is a unique identifier of the message. + +The message types are described in the following sub-sections. + +A chaincode implements the ``Chaincode`` interface, which is called by +the validating peer when it processes Deploy, Invoke or Query +transactions. + +:: + + type Chaincode interface { + i Init(stub *ChaincodeStub, function string, args []string) ([]byte, error) + Invoke(stub *ChaincodeStub, function string, args []string) ([]byte, error) + Query(stub *ChaincodeStub, function string, args []string) ([]byte, error) + } + +``Init``, ``Invoke`` and ``Query`` functions take ``function`` and +``args`` as parameters to be used by those methods to support a variety +of transactions. ``Init`` is a constructor function, which will only be +invoked by the Deploy transaction. The ``Query`` function is not allowed +to modify the state of the chaincode; it can only read and calculate the +return value as a byte array. + +3.3.2.1 Chaincode Deploy +'''''''''''''''''''''''' + +Upon deploy (chaincode container is started), the shim layer sends a one +time ``REGISTER`` message to the validating peer with the ``payload`` +containing the ``ChaincodeID``. The validating peer responds with +``REGISTERED`` or ``ERROR`` on success or failure respectively. The shim +closes the connection and exits if it receives an ``ERROR``. + +After registration, the validating peer sends ``INIT`` with the +``payload`` containing a ``ChaincodeInput`` object. The shim calls the +``Init`` function with the parameters from the ``ChaincodeInput``, +enabling the chaincode to perform any initialization, such as setting up +the persistent state. + +The shim responds with ``RESPONSE`` or ``ERROR`` message depending on +the returned value from the chaincode ``Init`` function. If there are no +errors, the chaincode initialization is complete and is ready to receive +Invoke and Query transactions. + +3.3.2.2 Chaincode Invoke +'''''''''''''''''''''''' + +When processing an invoke transaction, the validating peer sends a +``TRANSACTION`` message to the chaincode container shim, which in turn +calls the chaincode ``Invoke`` function, passing the parameters from the +``ChaincodeInput`` object. The shim responds to the validating peer with +``RESPONSE`` or ``ERROR`` message, indicating the completion of the +function. If ``ERROR`` is received, the ``payload`` contains the error +message generated by the chaincode. + +3.3.2.3 Chaincode Query +''''''''''''''''''''''' + +Similar to an invoke transaction, when processing a query, the +validating peer sends a ``QUERY`` message to the chaincode container +shim, which in turn calls the chaincode ``Query`` function, passing the +parameters from the ``ChaincodeInput`` object. The ``Query`` function +may return a state value or an error, which the shim forwards to the +validating peer using ``RESPONSE`` or ``ERROR`` messages respectively. + +3.3.2.4 Chaincode State +''''''''''''''''''''''' + +Each chaincode may define its own persistent state variables. For +example, a chaincode may create assets such as TVs, cars, or stocks +using state variables to hold the assets attributes. During ``Invoke`` +function processing, the chaincode may update the state variables, for +example, changing an asset owner. A chaincode manipulates the state +variables by using the following message types: + +PUT\_STATE + + +Chaincode sends a ``PUT_STATE`` message to persist a key-value pair, +with the ``payload`` containing ``PutStateInfo`` object. + +:: + + message PutStateInfo { + string key = 1; + bytes value = 2; + } + +GET\_STATE + + +Chaincode sends a ``GET_STATE`` message to retrieve the value whose key +is specified in the ``payload``. + +DEL\_STATE + + +Chaincode sends a ``DEL_STATE`` message to delete the value whose key is +specified in the ``payload``. + +GET\_STATE\_BY\_RANGE + + +Chaincode sends a ``GET_STATE_BY_RANGE`` message to get a range of +values. The message ``payload`` contains a ``GetStateByRangeInfo`` +object. + +:: + + message GetStateByRange { + string startKey = 1; + string endKey = 2; + } + +The ``startKey`` and ``endKey`` are inclusive and assumed to be in +lexical order. The validating peer responds with ``RESPONSE`` message +whose ``payload`` is a ``GetStateByRangeResponse`` object. + +:: + + message GetStateByRangeResponse { + repeated GetStateByRangeKeyValue keysAndValues = 1; + bool hasMore = 2; + string ID = 3; + } + message GetStateByRangeKeyValue { + string key = 1; + bytes value = 2; + } + +If ``hasMore=true`` in the response, this indicates that additional keys +are available in the requested range. The chaincode can request the next +set of keys and values by sending a ``GetStateByRangeNext`` message with +an ID that matches the ID returned in the response. + +:: + + message GetStateByRangeNext { + string ID = 1; + } + +When the chaincode is finished reading from the range, it should send a +``GetStateByRangeClose`` message with the ID it wishes to close. + +:: + + message GetStateByRangeClose { + string ID = 1; + } + +INVOKE\_CHAINCODE + + +Chaincode may call another chaincode in the same transaction context by +sending an ``INVOKE_CHAINCODE`` message to the validating peer with the +``payload`` containing a ``ChaincodeSpec`` object. + +QUERY\_CHAINCODE + + +Chaincode may query another chaincode in the same transaction context by +sending a ``QUERY_CHAINCODE`` message with the ``payload`` containing a +``ChaincodeSpec`` object. + +3.4 Pluggable Consensus Framework +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The consensus framework defines the interfaces that every consensus +*plugin* implements: + +- ``consensus.Consenter``: interface that allows consensus plugin to + receive messages from the network. +- ``consensus.CPI``: *Consensus Programming Interface* (``CPI``) is + used by consensus plugin to interact with rest of the stack. This + interface is split in two parts: + + - ``consensus.Communicator``: used to send (broadcast and unicast) + messages to other validating peers. + - ``consensus.LedgerStack``: which is used as an interface to the + execution framework as well as the ledger. + +As described below in more details, ``consensus.LedgerStack`` +encapsulates, among other interfaces, the ``consensus.Executor`` +interface, which is the key part of the consensus framework. Namely, +``consensus.Executor`` interface allows for a (batch of) transaction to +be started, executed, rolled back if necessary, previewed, and +potentially committed. A particular property that every consensus plugin +needs to satisfy is that batches (blocks) of transactions are committed +to the ledger (via ``consensus.Executor.CommitTxBatch``) in total order +across all validating peers (see ``consensus.Executor`` interface +description below for more details). + +Currently, consensus framework consists of 3 packages ``consensus``, +``controller``, and ``helper``. The primary reason for ``controller`` +and ``helper`` packages is to avoid "import cycle" in Go (golang) and +minimize code changes for plugin to update. + +- ``controller`` package specifies the consensus plugin used by a + validating peer. +- ``helper`` package is a shim around a consensus plugin that helps it + interact with the rest of the stack, such as maintaining message + handlers to other peers. + +There are 2 consensus plugins provided: ``pbft`` and ``noops``: + +- ``pbft`` package contains consensus plugin that implements the *PBFT* + [1] consensus protocol. See section 5 for more detail. +- ``noops`` is a ''dummy'' consensus plugin for development and test + purposes. It doesn't perform consensus but processes all consensus + messages. It also serves as a good simple sample to start learning + how to code a consensus plugin. + +3.4.1 ``Consenter`` interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Definition: + +:: + + type Consenter interface { + RecvMsg(msg *pb.Message) error + } + +The plugin's entry point for (external) client requests, and consensus +messages generated internally (i.e. from the consensus module) during +the consensus process. The ``controller.NewConsenter`` creates the +plugin ``Consenter``. ``RecvMsg`` processes the incoming transactions in +order to reach consensus. + +See ``helper.HandleMessage`` below to understand how the peer interacts +with this interface. + +3.4.2 ``CPI`` interface +^^^^^^^^^^^^^^^^^^^^^^^ + +Definition: + +:: + + type CPI interface { + Inquirer + Communicator + SecurityUtils + LedgerStack + } + +``CPI`` allows the plugin to interact with the stack. It is implemented +by the ``helper.Helper`` object. Recall that this object: + +1. Is instantiated when the ``helper.NewConsensusHandler`` is called. +2. Is accessible to the plugin author when they construct their plugin's + ``consensus.Consenter`` object. + +3.4.3 ``Inquirer`` interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Definition: + +:: + + type Inquirer interface { + GetNetworkInfo() (self *pb.PeerEndpoint, network []*pb.PeerEndpoint, err error) + GetNetworkHandles() (self *pb.PeerID, network []*pb.PeerID, err error) + } + +This interface is a part of the ``consensus.CPI`` interface. It is used +to get the handles of the validating peers in the network +(``GetNetworkHandles``) as well as details about the those validating +peers (``GetNetworkInfo``): + +Note that the peers are identified by a ``pb.PeerID`` object. This is a +protobuf message (in the ``protos`` package), currently defined as +(notice that this definition will likely be modified): + +:: + + message PeerID { + string name = 1; + } + +3.4.4 ``Communicator`` interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Definition: + +:: + + type Communicator interface { + Broadcast(msg *pb.Message) error + Unicast(msg *pb.Message, receiverHandle *pb.PeerID) error + } + +This interface is a part of the ``consensus.CPI`` interface. It is used +to communicate with other peers on the network (``helper.Broadcast``, +``helper.Unicast``): + +3.4.5 ``SecurityUtils`` interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Definition: + +:: + + type SecurityUtils interface { + Sign(msg []byte) ([]byte, error) + Verify(peerID *pb.PeerID, signature []byte, message []byte) error + } + +This interface is a part of the ``consensus.CPI`` interface. It is used +to handle the cryptographic operations of message signing (``Sign``) and +verifying signatures (``Verify``) + +3.4.6 ``LedgerStack`` interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Definition: + +:: + + type LedgerStack interface { + Executor + Ledger + RemoteLedgers + } + +A key member of the ``CPI`` interface, ``LedgerStack`` groups +interaction of consensus with the rest of the fabric, such as the +execution of transactions, querying, and updating the ledger. This +interface supports querying the local blockchain and state, updating the +local blockchain and state, and querying the blockchain and state of +other nodes in the consensus network. It consists of three parts: +``Executor``, ``Ledger`` and ``RemoteLedgers`` interfaces. These are +described in the following. + +3.4.7 ``Executor`` interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Definition: + +:: + + type Executor interface { + BeginTxBatch(id interface{}) error + ExecTXs(id interface{}, txs []*pb.Transaction) ([]byte, []error) + CommitTxBatch(id interface{}, transactions []*pb.Transaction, transactionsResults []*pb.TransactionResult, metadata []byte) error + RollbackTxBatch(id interface{}) error + PreviewCommitTxBatchBlock(id interface{}, transactions []*pb.Transaction, metadata []byte) (*pb.Block, error) + } + +The executor interface is the most frequently utilized portion of the +``LedgerStack`` interface, and is the only piece which is strictly +necessary for a consensus network to make progress. The interface allows +for a transaction to be started, executed, rolled back if necessary, +previewed, and potentially committed. This interface is comprised of the +following methods. + +3.4.7.1 Beginning a transaction batch +''''''''''''''''''''''''''''''''''''' + +:: + + BeginTxBatch(id interface{}) error + +This call accepts an arbitrary ``id``, deliberately opaque, as a way for +the consensus plugin to ensure only the transactions associated with +this particular batch are executed. For instance, in the pbft +implementation, this ``id`` is the an encoded hash of the transactions +to be executed. + +3.4.7.2 Executing transactions +'''''''''''''''''''''''''''''' + +:: + + ExecTXs(id interface{}, txs []*pb.Transaction) ([]byte, []error) + +This call accepts an array of transactions to execute against the +current state of the ledger and returns the current state hash in +addition to an array of errors corresponding to the array of +transactions. Note that a transaction resulting in an error has no +effect on whether a transaction batch is safe to commit. It is up to the +consensus plugin to determine the behavior which should occur when +failing transactions are encountered. This call is safe to invoke +multiple times. + +3.4.7.3 Committing and rolling-back transactions +'''''''''''''''''''''''''''''''''''''''''''''''' + +:: + + RollbackTxBatch(id interface{}) error + +This call aborts an execution batch. This will undo the changes to the +current state, and restore the ledger to its previous state. It +concludes the batch begun with ``BeginBatchTx`` and a new one must be +created before executing any transactions. + +:: + + PreviewCommitTxBatchBlock(id interface{}, transactions []*pb.Transaction, metadata []byte) (*pb.Block, error) + +This call is most useful for consensus plugins which wish to test for +non-deterministic transaction execution. The hashable portions of the +block returned are guaranteed to be identical to the block which would +be committed if ``CommitTxBatch`` were immediately invoked. This +guarantee is violated if any new transactions are executed. + +:: + + CommitTxBatch(id interface{}, transactions []*pb.Transaction, transactionsResults []*pb.TransactionResult, metadata []byte) error + +This call commits a block to the blockchain. Blocks must be committed to +a blockchain in total order. ``CommitTxBatch`` concludes the transaction +batch, and a new call to ``BeginTxBatch`` must be made before any new +transactions are executed and committed. + +3.4.8 ``Ledger`` interface +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Definition: + +:: + + type Ledger interface { + ReadOnlyLedger + UtilLedger + WritableLedger + } + +``Ledger`` interface is intended to allow the consensus plugin to +interrogate and possibly update the current state and blockchain. It is +comprised of the three interfaces described below. + +3.4.8.1 ``ReadOnlyLedger`` interface +'''''''''''''''''''''''''''''''''''' + +Definition: + +:: + + type ReadOnlyLedger interface { + GetBlock(id uint64) (block *pb.Block, err error) + GetCurrentStateHash() (stateHash []byte, err error) + GetBlockchainSize() (uint64, error) + } + +``ReadOnlyLedger`` interface is intended to query the local copy of the +ledger without the possibility of modifying it. It is comprised of the +following functions. + +:: + + GetBlockchainSize() (uint64, error) + +This call returns the current length of the blockchain ledger. In +general, this function should never fail, though in the unlikely event +that this occurs, the error is passed to the caller to decide what if +any recovery is necessary. The block with the highest number will have +block number ``GetBlockchainSize()-1``. + +Note that in the event that the local copy of the blockchain ledger is +corrupt or incomplete, this call will return the highest block number in +the chain, plus one. This allows for a node to continue operating from +the current state/block even when older blocks are corrupt or missing. + +:: + + GetBlock(id uint64) (block *pb.Block, err error) + +This call returns the block from the blockchain with block number +``id``. In general, this call should not fail, except when the block +queried exceeds the current blocklength, or when the underlying +blockchain has somehow become corrupt. A failure of ``GetBlock`` has a +possible resolution of using the state transfer mechanism to retrieve +it. + +:: + + GetCurrentStateHash() (stateHash []byte, err error) + +This call returns the current state hash for the ledger. In general, +this function should never fail, though in the unlikely event that this +occurs, the error is passed to the caller to decide what if any recovery +is necessary. + +3.4.8.2 ``UtilLedger`` interface +'''''''''''''''''''''''''''''''' + +Definition: + +:: + + type UtilLedger interface { + HashBlock(block *pb.Block) ([]byte, error) + VerifyBlockchain(start, finish uint64) (uint64, error) + } + +``UtilLedger`` interface defines some useful utility functions which are +provided by the local ledger. Overriding these functions in a mock +interface can be useful for testing purposes. This interface is +comprised of two functions. + +:: + + HashBlock(block *pb.Block) ([]byte, error) + +Although ``*pb.Block`` has a ``GetHash`` method defined, for mock +testing, overriding this method can be very useful. Therefore, it is +recommended that the ``GetHash`` method never be directly invoked, but +instead invoked via this ``UtilLedger.HashBlock`` interface. In general, +this method should never fail, but the error is still passed to the +caller to decide what if any recovery is appropriate. + +:: + + VerifyBlockchain(start, finish uint64) (uint64, error) + +This utility method is intended for verifying large sections of the +blockchain. It proceeds from a high block ``start`` to a lower block +``finish``, returning the block number of the first block whose +``PreviousBlockHash`` does not match the block hash of the previous +block as well as an error. Note, this generally indicates the last good +block number, not the first bad block number. + +3.4.8.3 ``WritableLedger`` interface +'''''''''''''''''''''''''''''''''''' + +Definition: + +:: + + type WritableLedger interface { + PutBlock(blockNumber uint64, block *pb.Block) error + ApplyStateDelta(id interface{}, delta *statemgmt.StateDelta) error + CommitStateDelta(id interface{}) error + RollbackStateDelta(id interface{}) error + EmptyState() error + } + +``WritableLedger`` interface allows for the caller to update the +blockchain. Note that this is *NOT* intended for use in normal operation +of a consensus plugin. The current state should be modified by executing +transactions using the ``Executor`` interface, and new blocks will be +generated when transactions are committed. This interface is instead +intended primarily for state transfer or corruption recovery. In +particular, functions in this interface should *NEVER* be exposed +directly via consensus messages, as this could result in violating the +immutability promises of the blockchain concept. This interface is +comprised of the following functions. + +- :: + + PutBlock(blockNumber uint64, block *pb.Block) error + + This function takes a provided, raw block, and inserts it into the + blockchain at the given blockNumber. Note that this intended to be an + unsafe interface, so no error or sanity checking is performed. + Inserting a block with a number higher than the current block height + is permitted, similarly overwriting existing already committed blocks + is also permitted. Remember, this does not affect the auditability or + immutability of the chain, as the hashing techniques make it + computationally infeasible to forge a block earlier in the chain. Any + attempt to rewrite the blockchain history is therefore easily + detectable. This is generally only useful to the state transfer API. + +- :: + + ApplyStateDelta(id interface{}, delta *statemgmt.StateDelta) error + + This function takes a state delta, and applies it to the current + state. The delta will be applied to transition a state forward or + backwards depending on the construction of the state delta. Like the + ``Executor`` methods, ``ApplyStateDelta`` accepts an opaque interface + ``id`` which should also be passed into ``CommitStateDelta`` or + ``RollbackStateDelta`` as appropriate. + +- :: + + CommitStateDelta(id interface{}) error + + This function commits the state delta which was applied in + ``ApplyStateDelta``. This is intended to be invoked after the caller + to ``ApplyStateDelta`` has verified the state via the state hash + obtained via ``GetCurrentStateHash()``. This call takes the same + ``id`` which was passed into ``ApplyStateDelta``. + +- :: + + RollbackStateDelta(id interface{}) error + + This function unapplies a state delta which was applied in + ``ApplyStateDelta``. This is intended to be invoked after the caller + to ``ApplyStateDelta`` has detected the state hash obtained via + ``GetCurrentStateHash()`` is incorrect. This call takes the same + ``id`` which was passed into ``ApplyStateDelta``. + +- :: + + EmptyState() error + + This function will delete the entire current state, resulting in a + pristine empty state. It is intended to be called before loading an + entirely new state via deltas. This is generally only useful to the + state transfer API. + +3.4.9 ``RemoteLedgers`` interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Definition: + +:: + + type RemoteLedgers interface { + GetRemoteBlocks(peerID uint64, start, finish uint64) (<-chan *pb.SyncBlocks, error) + GetRemoteStateSnapshot(peerID uint64) (<-chan *pb.SyncStateSnapshot, error) + GetRemoteStateDeltas(peerID uint64, start, finish uint64) (<-chan *pb.SyncStateDeltas, error) + } + +The ``RemoteLedgers`` interface exists primarily to enable state +transfer and to interrogate the blockchain state at other replicas. Just +like the ``WritableLedger`` interface, it is not intended to be used in +normal operation and is designed to be used for catchup, error recovery, +etc. For all functions in this interface it is the caller's +responsibility to enforce timeouts. This interface contains the +following functions. + +- :: + + GetRemoteBlocks(peerID uint64, start, finish uint64) (<-chan *pb.SyncBlocks, error) + + This function attempts to retrieve a stream of ``*pb.SyncBlocks`` + from the peer designated by ``peerID`` for the range from ``start`` + to ``finish``. In general, ``start`` should be specified with a + higher block number than ``finish``, as the blockchain must be + validated from end to beginning. The caller must validate that the + desired block is being returned, as it is possible that slow results + from another request could appear on this channel. Invoking this call + for the same ``peerID`` a second time will cause the first channel to + close. + +- :: + + GetRemoteStateSnapshot(peerID uint64) (<-chan *pb.SyncStateSnapshot, error) + + This function attempts to retrieve a stream of + ``*pb.SyncStateSnapshot`` from the peer designated by ``peerID``. To + apply the result, the existing state should first be emptied via the + ``WritableLedger`` ``EmptyState`` call, then the contained deltas in + the stream should be applied sequentially. + +- :: + + GetRemoteStateDeltas(peerID uint64, start, finish uint64) (<-chan *pb.SyncStateDeltas, error) + + This function attempts to retrieve a stream of + ``*pb.SyncStateDeltas`` from the peer designated by ``peerID`` for + the range from ``start`` to ``finish``. The caller must validated + that the desired block delta is being returned, as it is possible + that slow results from another request could appear on this channel. + Invoking this call for the same ``peerID`` a second time will cause + the first channel to close. + +3.4.10 ``controller`` package +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +3.4.10.1 controller.NewConsenter +'''''''''''''''''''''''''''''''' + +Signature: + +:: + + func NewConsenter(cpi consensus.CPI) (consenter consensus.Consenter) + +This function reads the ``peer.validator.consensus`` value in +``core.yaml`` configuration file, which is the configuration file for +the ``peer`` process. The value of the ``peer.validator.consensus`` key +defines whether the validating peer will run with the ``noops`` +consensus plugin or the ``pbft`` one. (Notice that this should +eventually be changed to either ``noops`` or ``custom``. In case of +``custom``, the validating peer will run with the consensus plugin +defined in ``consensus/config.yaml``.) + +The plugin author needs to edit the function's body so that it routes to +the right constructor for their package. For example, for ``pbft`` we +point to the ``pbft.GetPlugin`` constructor. + +This function is called by ``helper.NewConsensusHandler`` when setting +the ``consenter`` field of the returned message handler. The input +argument ``cpi`` is the output of the ``helper.NewHelper`` constructor +and implements the ``consensus.CPI`` interface. + +3.4.11 ``helper`` package +^^^^^^^^^^^^^^^^^^^^^^^^^ + +3.4.11.1 High-level overview +'''''''''''''''''''''''''''' + +A validating peer establishes a message handler +(``helper.ConsensusHandler``) for every connected peer, via the +``helper.NewConsensusHandler`` function (a handler factory). Every +incoming message is inspected on its type (``helper.HandleMessage``); if +it's a message for which consensus needs to be reached, it's passed on +to the peer's consenter object (``consensus.Consenter``). Otherwise it's +passed on to the next message handler in the stack. + +3.4.11.2 helper.ConsensusHandler +'''''''''''''''''''''''''''''''' + +Definition: + +:: + + type ConsensusHandler struct { + chatStream peer.ChatStream + consenter consensus.Consenter + coordinator peer.MessageHandlerCoordinator + done chan struct{} + peerHandler peer.MessageHandler + } + +Within the context of consensus, we focus only on the ``coordinator`` +and ``consenter`` fields. The ``coordinator``, as the name implies, is +used to coordinate between the peer's message handlers. This is, for +instance, the object that is accessed when the peer wishes to +``Broadcast``. The ``consenter`` receives the messages for which +consensus needs to be reached and processes them. + +Notice that ``fabric/peer/peer.go`` defines the ``peer.MessageHandler`` +(interface), and ``peer.MessageHandlerCoordinator`` (interface) types. + +3.4.11.3 helper.NewConsensusHandler +''''''''''''''''''''''''''''''''''' + +Signature: + +:: + + func NewConsensusHandler(coord peer.MessageHandlerCoordinator, stream peer.ChatStream, initiatedStream bool, next peer.MessageHandler) (peer.MessageHandler, error) + +Creates a ``helper.ConsensusHandler`` object. Sets the same +``coordinator`` for every message handler. Also sets the ``consenter`` +equal to: ``controller.NewConsenter(NewHelper(coord))`` + +3.4.11.4 helper.Helper +'''''''''''''''''''''' + +Definition: + +:: + + type Helper struct { + coordinator peer.MessageHandlerCoordinator + } + +Contains the reference to the validating peer's ``coordinator``. Is the +object that implements the ``consensus.CPI`` interface for the peer. + +3.4.11.5 helper.NewHelper +''''''''''''''''''''''''' + +Signature: + +:: + + func NewHelper(mhc peer.MessageHandlerCoordinator) consensus.CPI + +Returns a ``helper.Helper`` object whose ``coordinator`` is set to the +input argument ``mhc`` (the ``coordinator`` field of the +``helper.ConsensusHandler`` message handler). This object implements the +``consensus.CPI`` interface, thus allowing the plugin to interact with +the stack. + +3.4.11.6 helper.HandleMessage +''''''''''''''''''''''''''''' + +Recall that the ``helper.ConsensusHandler`` object returned by +``helper.NewConsensusHandler`` implements the ``peer.MessageHandler`` +interface: + +:: + + type MessageHandler interface { + RemoteLedger + HandleMessage(msg *pb.Message) error + SendMessage(msg *pb.Message) error + To() (pb.PeerEndpoint, error) + Stop() error + } + +Within the context of consensus, we focus only on the ``HandleMessage`` +method. Signature: + +:: + + func (handler *ConsensusHandler) HandleMessage(msg *pb.Message) error + +The function inspects the ``Type`` of the incoming ``Message``. There +are four cases: + +1. Equal to ``pb.Message_CONSENSUS``: passed to the handler's + ``consenter.RecvMsg`` function. +2. Equal to ``pb.Message_CHAIN_TRANSACTION`` (i.e. an external + deployment request): a response message is sent to the user first, + then the message is passed to the ``consenter.RecvMsg`` function. +3. Equal to ``pb.Message_CHAIN_QUERY`` (i.e. a query): passed to the + ``helper.doChainQuery`` method so as to get executed locally. +4. Otherwise: passed to the ``HandleMessage`` method of the next handler + down the stack. + +3.5 Events +~~~~~~~~~~ + +The event framework provides the ability to generate and consume +predefined and custom events. There are 3 basic components: - Event +stream - Event adapters - Event structures + +3.5.1 Event Stream +^^^^^^^^^^^^^^^^^^ + +An event stream is a gRPC channel capable of sending and receiving +events. Each consumer establishes an event stream to the event framework +and expresses the events that it is interested in. the event producer +only sends appropriate events to the consumers who have connected to the +producer over the event stream. + +The event stream initializes the buffer and timeout parameters. The +buffer holds the number of events waiting for delivery, and the timeout +has 3 options when the buffer is full: + +- If timeout is less than 0, drop the newly arriving events +- If timeout is 0, block on the event until the buffer becomes + available +- If timeout is greater than 0, wait for the specified timeout and drop + the event if the buffer remains full after the timeout + +3.5.1.1 Event Producer +'''''''''''''''''''''' + +The event producer exposes a function to send an event, +``Send(e *pb.Event)``, where ``Event`` is either a pre-defined ``Block`` +or a ``Generic`` event. More events will be defined in the future to +include other elements of the fabric. + +:: + + message Generic { + string eventType = 1; + bytes payload = 2; + } + +The ``eventType`` and ``payload`` are freely defined by the event +producer. For example, JSON data may be used in the ``payload``. The +``Generic`` event may also be emitted by the chaincode or plugins to +communicate with consumers. + +3.5.1.2 Event Consumer +'''''''''''''''''''''' + +The event consumer enables external applications to listen to events. +Each event consumer registers an event adapter with the event stream. +The consumer framework can be viewed as a bridge between the event +stream and the adapter. A typical use of the event consumer framework +is: + +:: + + adapter = + consumerClient = NewEventsClient(, adapter) + consumerClient.Start() + ... + ... + consumerClient.Stop() + +3.5.2 Event Adapters +^^^^^^^^^^^^^^^^^^^^ + +The event adapter encapsulates three facets of event stream interaction: +- an interface that returns the list of all events of interest - an +interface called by the event consumer framework on receipt of an event +- an interface called by the event consumer framework when the event bus +terminates + +The reference implementation provides Golang specific language binding. + +:: + + EventAdapter interface { + GetInterestedEvents() ([]*ehpb.Interest, error) + Recv(msg *ehpb.Event) (bool,error) + Disconnected(err error) + } + +Using gRPC as the event bus protocol allows the event consumer framework +to be ported to different language bindings without affecting the event +producer framework. + +3.5.3 Event Structure +^^^^^^^^^^^^^^^^^^^^^ + +This section details the message structures of the event system. +Messages are described directly in Golang for simplicity. + +The core message used for communication between the event consumer and +producer is the Event. + +:: + + message Event { + oneof Event { + //consumer events + Register register = 1; + + //producer events + Block block = 2; + Generic generic = 3; + } + } + +Per the above definition, an event has to be one of ``Register``, +``Block`` or ``Generic``. + +As mentioned in the previous sections, a consumer creates an event bus +by establishing a connection with the producer and sending a +``Register`` event. The ``Register`` event is essentially an array of +``Interest`` messages declaring the events of interest to the consumer. + +:: + + message Interest { + enum ResponseType { + //don't send events (used to cancel interest) + DONTSEND = 0; + //send protobuf objects + PROTOBUF = 1; + //marshall into JSON structure + JSON = 2; + } + string eventType = 1; + ResponseType responseType = 2; + } + +Events can be sent directly as protobuf structures or can be sent as +JSON structures by specifying the ``responseType`` appropriately. + +Currently, the producer framework can generate a ``Block`` or a +``Generic`` event. A ``Block`` is a message used for encapsulating +properties of a block in the blockchain. + +4. Security +----------- + +This section discusses the setting depicted in the figure below. In +particular, the system consists of the following entities: membership +management infrastructure, i.e., a set of entities that are responsible +for identifying an individual user (using any form of identification +considered in the system, e.g., credit cards, id-cards), open an account +for that user to be able to register, and issue the necessary +credentials to successfully create transactions and deploy or invoke +chaincode successfully through the fabric. |figure-architecture| \* +Peers, that are classified as validating peers, and non-validating +peers. Validating peers (also known as validators) order and process +(check validity, execute, and add to the blockchain) user-messages +(transactions) submitted to the network. Non validating peers (also +known as peers) receive user transactions on behalf of users, and after +some fundamental validity checks, they forward the transactions to their +neighboring validating peers. Peers maintain an up-to-date copy of the +blockchain, but in contradiction to validators, they do not execute +transactions (a process also known as *transaction validation*). \* End +users of the system, that have registered to our membership service +administration, after having demonstrated ownership of what is +considered *identity* in the system, and have obtained credentials to +install the client-software and submit transactions to the system. \* +Client-software, the software that needs to be installed at the client +side for the latter to be able to complete his registration to our +membership service and submit transactions to the system. \* Online +wallets, entities that are trusted by a user to maintain that user's +credentials, and submit transactions solely upon user request to the +network. Online wallets come with their own software at the client-side, +that is usually light-weight, as the client only needs to authenticate +himself and his requests to the wallet. While it can be the case that +peers can play the role of *online wallet* for a set of users, in the +following sessions the security of online wallets is detailed +separately. + +Users who wish to make use of the fabric, open an account at the +membership management administration, by proving ownership of identity +as discussed in previous sections, new chaincodes are announced to the +blockchain network by the chaincode creator (developer) through the +means of a deployment transaction that the client-software would +construct on behalf of the developer. Such transaction is first received +by a peer or validator, and afterwards circulated in the entire network +of validators, this transaction is executed and finds its place to the +blockchain network. Users can also invoke a function of an already +deployed chain-code through an invocation transaction. + +The next section provides a summary of the business goals of the system +that drive the security requirements. We then overview the security +components and their operation and show how this design fulfills the +security requirements. + +4.1 Business security requirements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section presents business security requirements that are relevant +to the context of the fabric. **Incorporation of identity and role +management.** + +In order to adequately support real business applications it is +necessary to progress beyond ensuring cryptographic continuity. A +workable B2B system must consequently move towards addressing +proven/demonstrated identities or other attributes relevant to +conducting business. Business transactions and consumer interactions +with financial institutions need to be unambiguously mapped to account +holders. Business contracts typically require demonstrable affiliation +with specific institutions and/or possession of other specific +properties of transacting parties. Accountability and non-frameability +are two reasons that identity management is a critical component of such +systems. + +Accountability means that users of the system, individuals, or +corporations, who misbehave can be traced back and be set accountable +for their actions. In many cases, members of a B2B system are required +to use their identities (in some form) to participate in the system, in +a way such that accountability is guaranteed. Accountability and +non-frameability are both essential security requirements in B2B systems +and they are closely related. That is, a B2B system should guarantee +that an honest user of such system cannot be framed to be accused as +responsible for transactions originated by other users. + +In addition a B2B system should be renewable and flexible in order to +accommodate changes of participants’s roles and/or affiliations. + +**Transactional privacy.** + +In B2B relationships there is a strong need for transactional privacy, +i.e., allowing the end-user of a system to control the degree to which +it interacts and shares information with its environment. For example, a +corporation doing business through a transactional B2B system requires +that its transactions are not visible to other corporations or +industrial partners that are not authorized to share classified +information with. + +Transactional privacy in the fabric is offered by the mechanisms to +achieve two properties with respect to non authorized users: + +- Transaction anonymity, where the owner of a transaction is hidden + among the so called *anonymity set*, which in the fabric, is the set + of users. + +- Transaction unlinkability, where two or more transactions of the same + user should not be linked as such. + +Clearly depending on the context, non-authorized users can be anyone +outside the system, or a subset of users. + +Transactional privacy is strongly associated to the confidentiality of +the content of a contractual agreement between two or more members of a +B2B system, as well as to the anonymity and unlinkability of any +authentication mechanism that should be in place within transactions. + +**Reconciling transactional privacy with identity management.** + +As described later in this document, the approach taken here to +reconcile identity management with user privacy and to enable +competitive institutions to transact effectively on a common blockchain +(for both intra- and inter-institutional transactions) is as follows: + +1. add certificates to transactions to implement a “permissioned” + blockchain + +2. utilize a two-level system: + +3. (relatively) static enrollment certificates (ECerts), acquired via + registration with an enrollment certificate authority (CA). + +4. transaction certificates (TCerts) that faithfully but pseudonymously + represent enrolled users, acquired via a transaction CA. + +5. offer mechanisms to conceal the content of transactions to + unauthorized members of the system. + +**Audit support.** Commercial systems are occasionally subjected to +audits. Auditors in such cases should be given the means to check a +certain transaction, or a certain group of transactions, the activity of +a particular user of the system, or the operation of the system itself. +Thus, such capabilities should be offered by any system featuring +transactions containing contractual agreements between business +partners. + +4.2 User Privacy through Membership Services +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Membership Services consists of an infrastructure of several entities +that together manage the identity and privacy of users on the network. +These services validate user’s identity, register the user in the +system, and provide all the credentials needed for him/her to be an +active and compliant participant able to create and/or invoke +transactions. A Public Key Infrastructure (PKI) is a framework based on +public key cryptography that ensures not only the secure exchange of +data over public networks but also affirms the identity of the other +party. A PKI manages the generation, distribution and revocation of keys +and digital certificates. Digital certificates are used to establish +user credentials and to sign messages. Signing messages with a +certificate ensures that the message has not been altered. Typically a +PKI has a Certificate Authority (CA), a Registration Authority (RA), a +certificate database, and a certificate storage. The RA is a trusted +party that authenticates users and vets the legitimacy of data, +certificates or other evidence submitted to support the user’s request +for one or more certificates that reflect that user’s identity or other +properties. A CA, upon advice from an RA, issues digital certificates +for specific uses and is certified directly or hierarchically by a root +CA. Alternatively, the user-facing communications and due diligence +responsibilities of the RA can be subsumed as part of the CA. Membership +Services is composed of the entities shown in the following figure. +Introduction of such full PKI reinforces the strength of this system for +B2B (over, e.g. Bitcoin). + +.. figure:: ./images/sec-memserv-components.png + :alt: Figure 1 + + Figure 1 + +*Root Certificate Authority (Root CA):* entity that represents the trust +anchor for the PKI scheme. Digital certificates verification follows a +chain of trust. The Root CA is the top-most CA in the PKI hierarchy. + +*Registration Authority (RA):* a trusted entity that can ascertain the +validity and identity of users who want to participate in the +permissioned blockchain. It is responsible for out-of-band communication +with the user to validate his/her identity and role. It creates +registration credentials needed for enrollment and information on root +of trust. + +*Enrollment Certificate Authority (ECA):* responsible for issuing +Enrollment Certificates (ECerts) after validating the registration +credentials provided by the user. + +*Transaction Certificate Authority (TCA):* responsible for issuing +Transaction Certificates (TCerts) after validating the enrollment +credentials provided by the user. + +*TLS Certificate Authority (TLS-CA):* responsible for issuing TLS +certificates and credentials that allow the user to make use of its +network. It validates the credential(s) or evidence provided by the user +that justifies issuance of a TLS certificate that includes specific +information pertaining to the user. + +In this specification, membership services is expressed through the +following associated certificates issued by the PKI: + +*Enrollment Certificates (ECerts)* ECerts are long-term certificates. +They are issued for all roles, i.e. users, non-validating peers, and +validating peers. In the case of users, who submit transactions for +candidate incorporation into the blockchain and who also own TCerts +(discussed below), there are two possible structure and usage models for +ECerts: + +- Model A: ECerts contain the identity/enrollmentID of their owner and + can be used to offer only nominal entity-authentication for TCert + requests and/or within transactions. They contain the public part of + two key pairs – a signature key-pair and an encryption/key agreement + key-pair. ECerts are accessible to everyone. + +- Model B: ECerts contain the identity/enrollmentID of their owner and + can be used to offer only nominal entity-authentication for TCert + requests. They contain the public part of a signature key-pair, i.e., + a signature verification public key. ECerts are preferably accessible + to only TCA and auditors, as relying parties. They are invisible to + transactions, and thus (unlike TCerts) their signature key pairs do + not play a non-repudiation role at that level. + +*Transaction Certificates (TCerts)* TCerts are short-term certificates +for each transaction. They are issued by the TCA upon authenticated +user-request. They securely authorize a transaction and may be +configured to not reveal the identities of who is involved in the +transaction or to selectively reveal such identity/enrollmentID +information. They include the public part of a signature key-pair, and +may be configured to also include the public part of a key agreement key +pair. They are issued only to users. They are uniquely associated to the +owner – they may be configured so that this association is known only by +the TCA (and to authorized auditors). TCerts may be configured to not +carry information of the identity of the user. They enable the user not +only to anonymously participate in the system but also prevent +linkability of transactions. + +However, auditability and accountability requirements assume that the +TCA is able to retrieve TCerts of a given identity, or retrieve the +owner of a specific TCert. For details on how TCerts are used in +deployment and invocation transactions see Section 4.3, Transaction +Security offerings at the infrastructure level. + +TCerts can accommodate encryption or key agreement public keys (as well +as digital signature verification public keys). If TCerts are thus +equipped, then enrollment certificates need not also contain encryption +or key agreement public keys. + +Such a key agreement public key, Key\_Agreement\_TCertPub\_Key, can be +generated by the transaction certificate authority (TCA) using a method +that is the same as that used to generate the +Signature\_Verification\_TCertPub\_Key, but using an index value of +TCertIndex + 1 rather than TCertIndex, where TCertIndex is hidden within +the TCert by the TCA for recovery by the TCert owner. + +The structure of a Transaction Certificate (TCert) is as follows: \* +TCertID – transaction certificate ID (preferably generated by TCA +randomly in order to avoid unintended linkability via the Hidden +Enrollment ID field). \* Hidden Enrollment ID: +AES\_EncryptK(enrollmentID), where key K = [HMAC(Pre-K, TCertID)]256-bit +truncation and where three distinct key distribution scenarios for Pre-K +are defined below as (a), (b) and (c). \* Hidden Private Keys +Extraction: AES\_EncryptTCertOwner\_EncryptKey(TCertIndex \|\| known +padding/parity check vector) where \|\| denotes concatenation, and where +each batch has a unique (per batch) time-stamp/random offset that is +added to a counter (initialized at 1 in this implementation) in order to +generate TCertIndex. The counter can be incremented by 2 each time in +order to accommodate generation by the TCA of the public keys and +recovery by the TCert owner of the private keys of both types, i.e., +signature key pairs and key agreement key pairs. \* Sign Verification +Public Key – TCert signature verification public key. \* Key Agreement +Public Key – TCert key agreement public key. \* Validity period – the +time window during which the transaction certificate can be used for the +outer/external signature of a transaction. + +There are at least three useful ways to consider configuring the key +distribution scenario for the Hidden Enrollment ID field: *(a)* Pre-K is +distributed during enrollment to user clients, peers and auditors, and +is available to the TCA and authorized auditors. It may, for example, be +derived from Kchain (described subsequently in this specification) or be +independent of key(s) used for chaincode confidentiality. + +*(b)* Pre-K is available to validators, the TCA and authorized auditors. +K is made available by a validator to a user (under TLS) in response to +a successful query transaction. The query transaction can have the same +format as the invocation transaction. Corresponding to Example 1 below, +the querying user would learn the enrollmentID of the user who created +the Deployment Transaction if the querying user owns one of the TCerts +in the ACL of the Deployment Transaction. Corresponding to Example 2 +below, the querying user would learn the enrollmentID of the user who +created the Deployment Transaction if the enrollmentID of the TCert used +to query matches one of the affiliations/roles in the Access Control +field of the Deployment Transaction. + +*Example 1:* + +.. figure:: ./images/sec-example-1.png + :alt: Example 1 + + Example 1 + +*Example 2:* + +.. figure:: ./images/sec-example-2.png + :alt: Example 2 + + Example 2 + +*(c)* Pre-K is available to the TCA and authorized auditors. The +TCert-specific K can be distributed the TCert owner (under TLS) along +with the TCert, for each TCert in the batch. This enables targeted +release by the TCert owner of K (and thus trusted notification of the +TCert owner’s enrollmentID). Such targeted release can use key agreement +public keys of the intended recipients and/or PKchain where SKchain is +available to validators as described subsequently in this specification. +Such targeted release to other contract participants can be incorporated +into a transaction or done out-of-band. + +If the TCerts are used in conjunction with ECert Model A above, then +using (c) where K is not distributed to the TCert owner may suffice. If +the TCerts are used in conjunction with ECert Model A above, then the +Key Agreement Public Key field of the TCert may not be necessary. + +The Transaction Certificate Authority (TCA) returns TCerts in batches, +each batch contains the KeyDF\_Key (Key-Derivation-Function Key) which +is not included within every TCert but delivered to the client with the +batch of TCerts (using TLS). The KeyDF\_Key allows the TCert owner to +derive TCertOwner\_EncryptKey which in turn enables recovery of +TCertIndex from AES\_EncryptTCertOwner\_EncryptKey(TCertIndex \|\| known +padding/parity check vector). + +*TLS-Certificates (TLS-Certs)* TLS-Certs are certificates used for +system/component-to-system/component communications. They carry the +identity of their owner and are used for network level security. + +This implementation of membership services provides the following basic +functionality: there is no expiration/revocation of ECerts; expiration +of TCerts is provided via the validity period time window; there is no +revocation of TCerts. The ECA, TCA, and TLS CA certificates are +self-signed, where the TLS CA is provisioned as a trust anchor. + +4.2.1 User/Client Enrollment Process +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The next figure has a high-level description of the user enrollment +process. It has an offline and an online phase. + +.. figure:: ./images/sec-registration-high-level.png + :alt: Registration + + Registration + +*Offline Process:* in Step 1, each user/non-validating peer/validating +peer has to present strong identification credentials (proof of ID) to a +Registration Authority (RA) offline. This has to be done out-of-band to +provide the evidence needed by the RA to create (and store) an account +for the user. In Step 2, the RA returns the associated username/password +and trust anchor (TLS-CA Cert in this implementation) to the user. If +the user has access to a local client then this is one way the client +can be securely provisioned with the TLS-CA certificate as trust anchor. + +*Online Phase:* In Step 3, the user connects to the client to request to +be enrolled in the system. The user sends his username and password to +the client. On behalf of the user, the client sends the request to the +PKI framework, Step 4, and receives a package, Step 5, containing +several certificates, some of which should correspond to private/secret +keys held by the client. Once the client verifies that the all the +crypto material in the package is correct/valid, it stores the +certificates in local storage and notifies the user. At this point the +user enrollment has been completed. + +.. figure:: ./images/sec-registration-detailed.png + :alt: Figure 4 + + Figure 4 + +Figure 4 shows a detailed description of the enrollment process. The PKI +framework has the following entities – RA, ECA, TCA and TLS-CA. After +Step 1, the RA calls the function “AddEntry” to enter the +(username/password) in its database. At this point the user has been +formally registered into the system database. The client needs the +TLS-CA certificate (as trust anchor) to verify that the TLS handshake is +set up appropriately with the server. In Step 4, the client sends the +registration request to the ECA along with its enrollment public key and +additional identity information such as username and password (under the +TLS record layer protocol). The ECA verifies that such user really +exists in the database. Once it establishes this assurance the user has +the right to submit his/her enrollment public key and the ECA will +certify it. This enrollment information is of a one-time use. The ECA +updates the database marking that this registration request information +(username/password) cannot be used again. The ECA constructs, signs and +sends back to the client an enrollment certificate (ECert) that contains +the user’s enrollment public key (Step 5). It also sends the ECA +Certificate (ECA-Cert) needed in future steps (client will need to prove +to the TCA that his/her ECert was created by the proper ECA). (Although +the ECA-Cert is self-signed in the initial implementation, the TCA and +TLS-CA and ECA are co-located.) The client verifies, in Step 6, that the +public key inside the ECert is the one originally submitted by the +client (i.e. that the ECA is not cheating). It also verifies that all +the expected information within the ECert is present and properly +formed. + +Similarly, In Step 7, the client sends a registration request to the +TLS-CA along with its public key and identity information. The TLS-CA +verifies that such user is in the database. The TLS-CA generates, and +signs a TLS-Cert that contains the user’s TLS public key (Step 8). +TLS-CA sends the TLS-Cert and its certificate (TLS-CA Cert). Step 9 is +analogous to Step 6, the client verifies that the public key inside the +TLS Cert is the one originally submitted by the client and that the +information in the TLS Cert is complete and properly formed. In Step 10, +the client saves all certificates in local storage for both +certificates. At this point the user enrollment has been completed. + +In this implementation the enrollment process for validators is the same +as that for peers. However, it is possible that a different +implementation would have validators enroll directly through an on-line +process. + +|Figure 5| |Figure 6| + +*Client:* Request for TCerts batch needs to include (in addition to +count), ECert and signature of request using ECert private key (where +Ecert private key is pulled from Local Storage). + +*TCA generates TCerts for batch:* Generates key derivation function key, +KeyDF\_Key, as HMAC(TCA\_KDF\_Key, EnrollPub\_Key). Generates each TCert +public key (using TCertPub\_Key = EnrollPub\_Key + ExpansionValue G, +where 384-bit ExpansionValue = HMAC(Expansion\_Key, TCertIndex) and +384-bit Expansion\_Key = HMAC(KeyDF\_Key, “2”)). Generates each +AES\_EncryptTCertOwner\_EncryptKey(TCertIndex \|\| known padding/parity +check vector), where \|\| denotes concatenation and where +TCertOwner\_EncryptKey is derived as [HMAC(KeyDF\_Key, “1”)]256-bit +truncation. + +*Client:* Deriving TCert private key from a TCert in order to be able to +deploy or invoke or query: KeyDF\_Key and ECert private key need to be +pulled from Local Storage. KeyDF\_Key is used to derive +TCertOwner\_EncryptKey as [HMAC(KeyDF\_Key, “1”)]256-bit truncation; +then TCertOwner\_EncryptKey is used to decrypt the TCert field +AES\_EncryptTCertOwner\_EncryptKey(TCertIndex \|\| known padding/parity +check vector); then TCertIndex is used to derive TCert private key: +TCertPriv\_Key = (EnrollPriv\_Key + ExpansionValue) modulo n, where +384-bit ExpansionValue = HMAC(Expansion\_Key, TCertIndex) and 384-bit +Expansion\_Key = HMAC(KeyDF\_Key, “2”). + +4.2.2 Expiration and revocation of certificates +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +It is practical to support expiration of transaction certificates. The +time window during which a transaction certificate can be used is +expressed by a ‘validity period’ field. The challenge regarding support +of expiration lies in the distributed nature of the system. That is, all +validating entities must share the same information; i.e. be consistent +with respect to the expiration of the validity period associated with +the transactions to be executed and validated. To guarantee that the +expiration of validity periods is done in a consistent manner across all +validators, the concept of validity period identifier is introduced. +This identifier acts as a logical clock enabling the system to uniquely +identify a validity period. At genesis time the “current validity +period” of the chain gets initialized by the TCA. It is essential that +this validity period identifier is given monotonically increasing values +over time, such that it imposes a total order among validity periods. + +A special type of transactions, system transactions, and the validity +period identified are used together to announce the expiration of a +validity period to the Blockchain. System transactions refer to +contracts that have been defined in the genesis block and are part of +the infrastructure. The validity period identified is updated +periodically by the TCA invoking a system chaincode. Note that only the +TCA should be allowed to update the validity period. The TCA sets the +validity period for each transaction certificate by setting the +appropriate integer values in the following two fields that define a +range: ‘not-before’ and ‘not-after’ fields. + +TCert Expiration: At the time of processing a TCert, validators read +from the state table associated with the ledger the value of ‘current +validity period’ to check if the outer certificate associated with the +transaction being evaluated is currently valid. That is, the current +value in the state table has to be within the range defined by TCert +sub-fields ‘not-before’ and ‘not-after’. If this is the case, the +validator continues processing the transaction. In the case that the +current value is not within range, the TCert has expired or is not yet +valid and the validator should stop processing the transaction. + +ECert Expiration: Enrollment certificates have different validity period +length(s) than those in transaction certificates. + +Revocation is supported in the form of Certificate Revocation Lists +(CRLs). CRLs identify revoked certificates. Changes to the CRLs, +incremental differences, are announced through the Blockchain. + +4.3 Transaction security offerings at the infrastructure level +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Transactions in the fabric are user-messages submitted to be included in +the ledger. As discussed in previous sections, these messages have a +specific structure, and enable users to deploy new chaincodes, invoke +existing chaincodes, or query the state of existing chaincodes. +Therefore, the way transactions are formed, announced and processed +plays an important role to the privacy and security offerings of the +entire system. + +On one hand our membership service provides the means to authenticate +transactions as having originated by valid users of the system, to +disassociate transactions with user identities, but while efficiently +tracing the transactions a particular individual under certain +conditions (law enforcement, auditing). In other words, membership +services offer to transactions authentication mechanisms that marry +user-privacy with accountability and non-repudiation. + +On the other hand, membership services alone cannot offer full privacy +of user-activities within the fabric. First of all, for privacy +provisions offered by the fabric to be complete, privacy-preserving +authentication mechanisms need to be accompanied by transaction +confidentiality. This becomes clear if one considers that the content of +a chaincode, may leak information on who may have created it, and thus +break the privacy of that chaincode's creator. The first subsection +discusses transaction confidentiality. + +.. raw:: html + + + +.. raw:: html + + + +Enforcing access control for the invocation of chaincode is an important +security requirement. The fabric exposes to the application (e.g., +chaincode creator) the means for the application to perform its own +invocation access control, while leveraging the fabric's membership +services. Section 4.4 elaborates on this. + +.. raw:: html + + + +Replay attacks is another crucial aspect of the security of the +chaincode, as a malicious user may copy a transaction that was added to +the Blockchain in the past, and replay it in the network to distort its +operation. This is the topic of Section 4.3.3. + +The rest of this Section presents an overview of how security mechanisms +in the infrastructure are incorporated in the transactions' lifecycle, +and details each security mechanism separately. + +4.3.1 Security Lifecycle of Transactions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Transactions are created on the client side. The client can be either +plain client, or a more specialized application, i.e., piece of software +that handles (server) or invokes (client) specific chaincodes through +the blockchain. Such applications are built on top of the platform +(client) and are detailed in Section 4.4. + +Developers of new chaincodes create a new deploy transaction by passing +to the fabric infrastructure: \* the confidentiality/security version or +type they want the transaction to conform with, \* the set of users who +wish to be given access to parts of the chaincode and a proper +representation of their (read) access rights \* the chaincode +specification, \* code metadata, containing information that should be +passed to the chaincode at the time of its execution (e.g., +configuration parameters), and \* transaction metadata, that is attached +to the transaction structure, and is only used by the application that +deployed the chaincode. + +Invoke and query transactions corresponding to chaincodes with +confidentiality restrictions are created using a similar approach. The +transactor provides the identifier of the chaincode to be executed, the +name of the function to be invoked and its arguments. Optionally, the +invoker can pass to the transaction creation function, code invocation +metadata, that will be provided to the chaincode at the time of its +execution. Transaction metadata is another field that the application of +the invoker or the invoker himself can leverage for their own purposes. + +Finally transactions at the client side, are signed by a certificate of +their creator and released to the network of validators. Validators +receive the confidential transactions, and pass them through the +following phases: \* *pre-validation* phase, where validators validate +the transaction certificate against the accepted root certificate +authority, verify transaction certificate signature included in the +transaction (statically), and check whether the transaction is a replay +(see, later section for details on replay attack protection). \* +*consensus* phase, where the validators add this transaction to the +total order of transactions (ultimately included in the ledger) \* +*pre-execution* phase, where validators verify the validity of the +transaction / enrollment certificate against the current validity +period, decrypt the transaction (if the transaction is encrypted), and +check that the transaction's plaintext is correctly formed(e.g., +invocation access control is respected, included TCerts are correctly +formed); mini replay-attack check is also performed here within the +transactions of the currently processed block. \* *execution* phase, +where the (decrypted) chaincode is passed to a container, along with the +associated code metadata, and is executed \* *commit* phase, where +(encrypted) updates of that chaincodes state is committed to the ledger +with the transaction itself. + +4.3.2 Transaction confidentiality +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Transaction confidentiality requires that under the request of the +developer, the plain-text of a chaincode, i.e., code, description, is +not accessible or inferable (assuming a computational attacker) by any +unauthorized entities(i.e., user or peer not authorized by the +developer). For the latter, it is important that for chaincodes with +confidentiality requirements the content of both *deploy* and *invoke* +transactions remains concealed. In the same spirit, non-authorized +parties, should not be able to associate invocations (invoke +transactions) of a chaincode to the chaincode itself (deploy +transaction) or these invocations to each other. + +Additional requirements for any candidate solution is that it respects +and supports the privacy and security provisions of the underlying +membership service. In addition, it should not prevent the enforcement +of any invocation access control of the chain-code functions in the +fabric, or the implementation of enforcement of access-control +mechanisms on the application (See Subsection 4.4). + +In the following is provided the specification of transaction +confidentiality mechanisms at the granularity of users. The last +subsection provides some guidelines on how to extend this functionality +at the level of validators. Information on the features supported in +current release and its security provisions, you can find in Section +4.7. + +The goal is to achieve a design that will allow for granting or +restricting access to an entity to any subset of the following parts of +a chain-code: 1. chaincode content, i.e., complete (source) code of the +chaincode, 2. chaincode function headers, i.e., the prototypes of the +functions included in a chaincode, 3. chaincode [invocations &] state, +i.e., successive updates to the state of a specific chaincode, when one +or more functions of its are invoked 4. all the above + +Notice, that this design offers the application the capability to +leverage the fabric's membership service infrastructure and its public +key infrastructure to build their own access control policies and +enforcement mechanisms. + +4.3.2.1 Confidentiality against users +''''''''''''''''''''''''''''''''''''' + +To support fine-grained confidentiality control, i.e., restrict +read-access to the plain-text of a chaincode to a subset of users that +the chaincode creator defines, a chain is bound to a single long-term +encryption key-pair (PKchain, SKchain). Though initially this key-pair +is to be stored and maintained by each chain's PKI, in later releases, +however, this restriction will be moved away, as chains (and the +associated key-pairs) can be triggered through the Blockchain by any +user with *special* (admin) privileges (See, Section 4.3.2.2). + +**Setup**. At enrollment phase, users obtain (as before) an enrollment +certificate, denoted by Certui for user ui, while each validator vj +obtain its enrollment certificate denoted by Certvj. Enrollment would +grant users and validators the following credentials: + +1. Users: + +a. claim and grant themselves signing key-pair (spku, ssku), + +b. claim and grant themselves encryption key-pair (epku, esku), + +c. obtain the encryption (public) key of the chain PKchain + +2. Validators: + +a. claim and grant themselves signing key-pair (spkv, sskv), + +b. claim and grant themselves an encryption key-pair (epkv, eskv), + +c. obtain the decryption (secret) key of the chain SKchain + +Thus, enrollment certificates contain the public part of two key-pairs: +\* one signature key-pair [denoted by (spkvj,sskvj) for validators and +by (spkui, sskui) for users], and \* an encryption key-pair [denoted by +(epkvj,eskvj) for validators and (epkui, eskui) for users] + +Chain, validator and user enrollment public keys are accessible to +everyone. + +| In addition to enrollment certificates, users who wish to anonymously + participate in transactions issue transaction certificates. For + simplicity transaction certificates of a user ui are denoted by + TCertui. Transaction certificates include the public part of a + signature key-pair denoted by +| (tpkui,tskui). + +The following section provides a high level description of how +transaction format accommodates read-access restrictions at the +granularity of users. + +**Structure of deploy transaction.** The following figure depicts the +structure of a typical deploy transaction with confidentiality enabled. + +.. figure:: ./images/sec-usrconf-deploy.png + :alt: FirstRelease-deploy + + FirstRelease-deploy + +One can notice that a deployment transaction consists of several +sections: \* Section *general-info*: contains the administration details +of the transaction, i.e., which chain this transaction corresponds to +(chained), the type of transaction (that is set to ''deplTrans''), the +version number of confidentiality policy implemented, its creator +identifier (expressed by means of transaction certificate TCert of +enrollment certificate Cert), and a Nonce, that facilitates primarily +replay-attack resistance techniques. \* Section *code-info*: contains +information on the chain-code source code, and function headers. As +shown in the figure below, there is a symmetric key used for the +source-code of the chaincode (KC), and another symmetric key used for +the function prototypes (KH). A signature of the creator of the +chaincode is included on the plain-text code such that the latter cannot +be detached from the transaction and replayed by another party. \* +Section *chain-validators*: where appropriate key material is passed to +the validators for the latter to be able to (i) decrypt the chain-code +source (KC), (ii) decrypt the headers, and (iii) encrypt the state when +the chain-code has been invoked accordingly(KS). In particular, the +chain-code creator generates an encryption key-pair for the chain-code +it deploys (PKC, SKC). It then uses PKC to encrypt all the keys +associated to the chain-code: + +.. raw:: html + +
+ +[(''code'',KC) ,(''headr'',KH),(''code-state'',KS), SigTCertuc(\*)]PKc, + +.. raw:: html + +
+ +and passes the secret key SKC to the validators using the chain-specific +public key: + +.. raw:: html + +
+ +[(''chaincode'',SKC), SigTCertuc(\*)]PKchain. + +.. raw:: html + +
+ +- Section *contract-users*: where the public encryption keys of the + contract users, i.e., users who are given read-access to parts of the + chaincode, are used to encrypt the keys associated to their access + rights: + +1. SKc for the users to be able to read any message associated to that + chain-code (invocation, state, etc), + +2. KC for the user to be able to read only the contract code, + +3. KH for the user to only be able to read the headers, + +4. KS for the user to be able to read the state associated to that + contract. + +Finally users are given the contract's public key PKc, for them to be +able to encrypt information related to that contract for the validators +(or any in possession of SKc) to be able to read it. Transaction +certificate of each contract user is appended to the transaction and +follows that user's message. This is done for users to be able to easily +search the blockchain for transactions they have been part of. Notice +that the deployment transaction also appends a message to the creator uc +of the chain-code, for the latter to be able to retrieve this +transaction through parsing the ledger and without keeping any state +locally. + +The entire transaction is signed by a certificate of the chaincode +creator, i.e., enrollment or transaction certificate as decided by the +latter. Two noteworthy points: \* Messages that are included in a +transaction in an encrypted format, i.e., code-functions, code-hdrs, are +signed before they are encrypted using the same TCert the entire +transaction is signed with, or even with a different TCert or the ECert +of the user (if the transaction deployment should carry the identity of +its owner. A binding to the underlying transaction carrier should be +included in the signed message, e.g., the hash of the TCert the +transaction is signed, such that mix&match attacks are not possible. +Though we detail such attacks in Section 4.4, in these cases an attacker +who sees a transaction should not be able to isolate the ciphertext +corresponding to, e.g., code-info, and use it for another transaction of +her own. Clearly, such an ability would disrupt the operation of the +system, as a chaincode that was first created by user A, will now also +belong to malicious user B (who is not even able to read it). \* To +offer the ability to the users to cross-verify they are given access to +the correct key, i.e., to the same key as the other contract users, +transaction ciphertexts that are encrypted with a key K are accompanied +by a commitment to K, while the opening of this commitment value is +passed to all users who are entitled access to K in contract-users, and +chain-validator sections. In this way, anyone who is entitled access to +that key can verify that the key has been properly passed to it. This +part is omitted in the figure above to avoid confusion. + +**Structure of invoke transaction.** A transaction invoking the +chain-code triggering the execution of a function of the chain-code with +user-specified arguments is structured as depicted in the figure below. + +.. figure:: ./images/sec-usrconf-invoke.png + :alt: FirstRelease-deploy + + FirstRelease-deploy + +Invocation transaction as in the case of deployment transaction consists +of a *general-info* section, a *code-info* section, a section for the +*chain-validators*, and one for the *contract users*, signed altogether +with one of the invoker's transaction certificates. + +- General-info follows the same structure as the corresponding section + of the deployment transaction. The only difference relates to the + transaction type that is now set to ''InvocTx'', and the chain-code + identifier or name that is now encrypted under the chain-specific + encryption (public) key. + +- Code-info exhibits the same structure as the one of the deployment + transaction. Code payload, as in the case of deployment transaction, + consists of function invocation details (the name of the function + invoked, and associated arguments), code-metadata provided by the + application and the transaction's creator (invoker's u) certificate, + TCertu. Code payload is signed by the transaction certificate TCertu + of the invoker u, as in the case of deploy transactions. As in the + case of deploy transactions, code-metadata, and tx-metadata, are + fields that are provided by the application and can be used (as + described in Section 4.4), for the latter to implement their own + access control mechanisms and roles. + +- Finally, contract-users and chain-validator sections provide the key + the payload is encrypted with, the invoker's key, and the chain + encryption key respectively. Upon receiving such transactions, the + validators decrypt [code-name]PKchain using the chain-specific secret + key SKchain and obtain the invoked chain-code identifier. Given the + latter, validators retrieve from their local storage the chaincode's + decryption key SKc, and use it to decrypt chain-validators' message, + that would equip them with the symmetric key KI the invocation + transaction's payload was encrypted with. Given the latter, + validators decrypt code-info, and execute the chain-code function + with the specified arguments, and the code-metadata attached(See, + Section 4.4 for more details on the use of code-metadata). While the + chain-code is executed, updates of the state of that chain-code are + possible. These are encrypted using the state-specific key Ks that + was defined during that chain-code's deployment. In particular, Ks is + used the same way KiTx is used in the design of our current release + (See, Section 4.7). + +**Structure of query transaction.** Query transactions have the same +format as invoke transactions. The only difference is that Query +transactions do not affect the state of the chaincode, and thus there is +no need for the state to be retrieved (decrypted) and/or updated +(encrypted) after the execution of the chaincode completes. + +4.3.2.2 Confidentiality against validators +'''''''''''''''''''''''''''''''''''''''''' + +This section deals with ways of how to support execution of certain +transactions under a different (or subset) sets of validators in the +current chain. This section inhibits IP restrictions and will be +expanded in the following few weeks. + +4.3.3 Replay attack resistance +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In replay attacks the attacker "replays" a message it "eavesdropped" on +the network or ''saw'' on the Blockchain. Replay attacks are a big +problem here, as they can incur into the validating entities re-doing a +computationally intensive process (chaincode invocation) and/or affect +the state of the corresponding chaincode, while it requires minimal or +no power from the attacker side. To make matters worse, if a transaction +was a payment transaction, replays could potentially incur into the +payment being performed more than once, without this being the original +intention of the payer. Existing systems resist replay attacks as +follows: \* Record hashes of transactions in the system. This solution +would require that validators maintain a log of the hash of each +transaction that has ever been announced through the network, and +compare a new transaction against their locally stored transaction +record. Clearly such approach cannot scale for large networks, and could +easily result into validators spending a lot of time to do the check of +whether a transaction has been replayed, than executing the actual +transaction. \* Leverage state that is maintained per user identity +(Ethereum). Ethereum keeps some state, e.g., counter (initially set to +1) for each identity/pseudonym in the system. Users also maintain their +own counter (initially set to 0) for each identity/pseudonym of theirs. +Each time a user sends a transaction using an identity/pseudonym of his, +he increases his local counter by one and adds the resulting value to +the transaction. The transaction is subsequently signed by that user +identity and released to the network. When picking up this transaction, +validators check the counter value included within and compare it with +the one they have stored locally; if the value is the same, they +increase the local value of that identity's counter and accept the +transaction. Otherwise, they reject the transaction as invalid or +replay. Although this would work well in cases where we have limited +number of user identities/pseudonyms (e.g., not too large), it would +ultimately not scale in a system where users use a different identifier +(transaction certificate) per transaction, and thus have a number of +user pseudonyms proportional to the number of transactions. + +Other asset management systems, e.g., Bitcoin, though not directly +dealing with replay attacks, they resist them. In systems that manage +(digital) assets, state is maintained on a per asset basis, i.e., +validators only keep a record of who owns what. Resistance to replay +attacks come as a direct result from this, as replays of transactions +would be immediately be deemed as invalid by the protocol (since can +only be shown to be derived from older owners of an asset/coin). While +this would be appropriate for asset management systems, this does not +abide with the needs of a Blockchain systems with more generic use than +asset management. + +In the fabric, replay attack protection uses a hybrid approach. That is, +users add in the transaction a nonce that is generated in a different +manner depending on whether the transaction is anonymous (followed and +signed by a transaction certificate) or not (followed and signed by a +long term enrollment certificate). More specifically: + +- Users submitting a transaction with their enrollment certificate + should include in that transaction a nonce that is a function of the + nonce they used in the previous transaction they issued with the same + certificate (e.g., a counter function or a hash). The nonce included + in the first transaction of each enrollment certificate can be either + pre-fixed by the system (e.g., included in the genesis block) or + chosen by the user. In the first case, the genesis block would need + to include nonceall , i.e., a fixed number and the nonce used by user + with identity IDA for his first enrollment certificate signed + transaction would be + + .. raw:: html + +
+ + nonceround0IDA <- hash(IDA, nonceall), + + .. raw:: html + +
+ + where IDA appears in the enrollment certificate. From that point + onward successive transactions of that user with enrollment + certificate would include a nonce as follows + + .. raw:: html + +
+ + nonceroundiIDA <- hash(nonceround{i-1}IDA), + + .. raw:: html + +
+ + that is the nonce of the ith transaction would be using the hash of + the nonce used in the {i-1}th transaction of that certificate. + Validators here continue to process a transaction they receive, as + long as it satisfies the condition mentioned above. Upon successful + validation of transaction's format, the validators update their + database with that nonce. + +**Storage overhead**: + +1. on the user side: only the most recently used nonce, + +2. on validator side: O(n), where n is the number of users. + +- Users submitting a transaction with a transaction certificate should + include in the transaction a random nonce, that would guarantee that + two transactions do not result into the same hash. Validators add the + hash of this transaction in their local database if the transaction + certificate used within it has not expired. To avoid storing large + amounts of hashes, validity periods of transaction certificates are + leveraged. In particular validators maintain an updated record of + received transactions' hashes within the current or future validity + period. + +**Storage overhead** (only makes sense for validators here): O(m), where +m is the approximate number of transactions within a validity period and +corresponding validity period identifier (see below). + +4.4 Access control features on the application +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An application, is a piece of software that runs on top of a Blockchain +client software, and, performs a special task over the Blockchain, i.e., +restaurant table reservation. Application software have a version of +developer, enabling the latter to generate and manage a couple of +chaincodes that are necessary for the business this application serves, +and a client-version that would allow the application's end-users to +make use of the application, by invoking these chain-codes. The use of +the Blockchain can be transparent to the application end-users or not. + +This section describes how an application leveraging chaincodes can +implement its own access control policies, and guidelines on how our +Membership services PKI can be leveraged for the same purpose. + +The presentation is divided into enforcement of invocation access +control, and enforcement of read-access control by the application. + +4.4.1 Invocation access control +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To allow the application to implement its own invocation access control +at the application layer securely, special support by the fabric must be +provided. In the following we elaborate on the tools exposed by the +fabric to the application for this purpose, and provide guidelines on +how these should be used by the application for the latter to enforce +access control securely. + +**Support from the infrastructure.** For the chaincode creator, let it +be, *uc*, to be able to implement its own invocation access control at +the application layer securely, special support by the fabric must be +provided. More specifically fabric layer gives access to following +capabilities: + +1. The client-application can request the fabric to sign and verify any + message with specific transaction certificates or enrollment + certificate the client owns; this is expressed via the Certificate + Handler interface + +2. The client-application can request the fabric a unique *binding* to + be used to bind authentication data of the application to the + underlying transaction transporting it; this is expressed via the + Transaction Handler interface + +3. Support for a transaction format, that allows for the application to + specify metadata, that are passed to the chain-code at deployment, + and invocation time; the latter denoted by code-metadata. + +The **Certificate Handler** interface allows to sign and verify any +message using signing key-pair underlying the associated certificate. +The certificate can be a TCert or an ECert. + +:: + + // CertificateHandler exposes methods to deal with an ECert/TCert + type CertificateHandler interface { + + // GetCertificate returns the certificate's DER + GetCertificate() []byte + + // Sign signs msg using the signing key corresponding to the certificate + Sign(msg []byte) ([]byte, error) + + // Verify verifies msg using the verifying key corresponding to the certificate + Verify(signature []byte, msg []byte) error + + // GetTransactionHandler returns a new transaction handler relative to this certificate + GetTransactionHandler() (TransactionHandler, error) + } + +The **Transaction Handler** interface allows to create transactions and +give access to the underlying *binding* that can be leveraged to link +application data to the underlying transaction. Bindings are a concept +that have been introduced in network transport protocols (See, +https://tools.ietf.org/html/rfc5056), known as *channel bindings*, that +*allows applications to establish that the two end-points of a secure +channel at one network layer are the same as at a higher layer by +binding authentication at the higher layer to the channel at the lower +layer. This allows applications to delegate session protection to lower +layers, which has various performance benefits.* Transaction bindings +offer the ability to uniquely identify the fabric layer of the +transaction that serves as the container that application data uses to +be added to the ledger. + +:: + + // TransactionHandler represents a single transaction that can be uniquely determined or identified by the output of the GetBinding method. + // This transaction is linked to a single Certificate (TCert or ECert). + type TransactionHandler interface { + + // GetCertificateHandler returns the certificate handler relative to the certificate mapped to this transaction + GetCertificateHandler() (CertificateHandler, error) + + // GetBinding returns a binding to the underlying transaction (container) + GetBinding() ([]byte, error) + + // NewChaincodeDeployTransaction is used to deploy chaincode + NewChaincodeDeployTransaction(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string) (*obc.Transaction, error) + + // NewChaincodeExecute is used to execute chaincode's functions + NewChaincodeExecute(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) + + // NewChaincodeQuery is used to query chaincode's functions + NewChaincodeQuery(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) + } + +For version 1, *binding* consists of the *hash*\ (TCert, Nonce), where +TCert, is the transaction certificate used to sign the entire +transaction, while Nonce, is the nonce number used within. + +The **Client** interface is more generic, and offers a mean to get +instances of the previous interfaces. + +:: + + type Client interface { + + ... + + // GetEnrollmentCertHandler returns a CertificateHandler whose certificate is the enrollment certificate + GetEnrollmentCertificateHandler() (CertificateHandler, error) + + // GetTCertHandlerNext returns a CertificateHandler whose certificate is the next available TCert + GetTCertificateHandlerNext() (CertificateHandler, error) + + // GetTCertHandlerFromDER returns a CertificateHandler whose certificate is the one passed + GetTCertificateHandlerFromDER(der []byte) (CertificateHandler, error) + + } + +To support application-level access control lists for controlling +chaincode invocation, the fabric's transaction and chaincode +specification format have an additional field to store +application-specific metadata. This field is depicted in both figures 1, +by code-metadata. The content of this field is decided by the +application, at the transaction creation time. The fabric layer treats +it as an unstructured stream of bytes. + +:: + + + message ChaincodeSpec { + + ... + + ConfidentialityLevel confidentialityLevel; + bytes metadata; + + ... + } + + + message Transaction { + ... + + bytes payload; + bytes metadata; + + ... + } + +To assist chaincode execution, at the chain-code invocation time, the +validators provide the chaincode with additional information, like the +metadata and the binding. + +**Application invocation access control.** This section describes how +the application can leverage the means provided by the fabric to +implement its own access control on its chain-code functions. In the +scenario considered here, the following entities are identified: + +1. **C**: is a chaincode that contains a single function, e.g., called + *hello*; + +2. **uc**: is the **C** deployer; + +3. **ui**: is a user who is authorized to invoke **C**'s functions. User + uc wants to ensure that only ui can invoke the function *hello*. + +*Deployment of a Chaincode:* At deployment time, uc has full control on +the deployment transaction's metadata, and can be used to store a list +of ACLs (one per function), or a list of roles that are needed by the +application. The format which is used to store these ACLs is up to the +deployer's application, as the chain-code is the one who would need to +parse the metadata at execution time. To define each of these +lists/roles, uc can use any TCerts/Certs of the ui (or, if applicable, +or other users who have been assigned that privilege or role). Let this +be TCertui. The exchange of TCerts or Certs among the developer and +authorized users is done through an out-of-band channel. + +Assume that the application of uc's requires that to invoke the *hello* +function, a certain message *M* has to be authenticated by an authorized +invoker (ui, in our example). One can distinguish the following two +cases: + +1. *M* is one of the chaincode's function arguments; + +2. *M* is the invocation message itself, i.e., function-name, + function-arguments. + +*Chaincode invocation:* To invoke C, ui's application needs to sign *M* +using the TCert/ECert, that was used to identify ui's participation in +the chain-code at the associated deployment transaction's metadata, +i.e., TCertui. More specifically, ui's client application does the +following: + +1. Retrieves a CertificateHandler for Certui, *cHandler*; + +2. obtains a new TransactionHandler to issue the execute transaction, + *txHandler* relative to his next available TCert or his ECert; + +3. gets *txHandler*'s *binding* by invoking *txHandler.getBinding()*; + +4. signs *'*\ M\* \|\| txBinding'\* by invoking *cHandler.Sign('*\ M\* + \|\| txBinding')\ *, let *\ sigma\* be the output of the signing + function; + +5. issues a new execute transaction by invoking, + *txHandler.NewChaincodeExecute(...)*. Now, *sigma* can be included in + the transaction as one of the arguments that are passed to the + function (case 1) or as part of the code-metadata section of the + payload(case 2). + +*Chaincode processing:* The validators, who receive the execute +transaction issued ui, will provide to *hello* the following +information: + +1. The *binding* of the execute transaction, that can be independently + computed at the validator side; + +2. The *metadata* of the execute transaction (code-metadata section of + the transaction); + +3. The *metadata* of the deploy transaction (code-metadata component of + the corresponding deployment transaction). + +Notice that *sigma* is either part of the arguments of the invoked +function, or stored inside the code-metadata of the invocation +transaction (properly formatted by the client-application). Application +ACLs are included in the code-metadata section, that is also passed to +the chain-code at execution time. Function *hello* is responsible for +checking that *sigma* is indeed a valid signature issued by TCertui, on +'*M* \|\| *txBinding'*. + +4.4.2 Read access control +^^^^^^^^^^^^^^^^^^^^^^^^^ + +This section describes how the fabric's infrastructure offers support to +the application to enforce its own read-access control policies at the +level of users. As in the case of invocation access control, the first +part describes the infrastructure features that can be leveraged by the +application for this purpose, and the last part details on the way +applications should use these tools. + +For the purpose of this discussion, we leverage a similar example as +before, i.e., + +1. **C**: is a chaincode that contains a single function, e.g., called + *hello*; + +2. **uA**: is the **C**'s deployer, also known as application; + +3. **ur**: is a user who is authorized to read **C**'s functions. User + uA wants to ensure that only ur can read the function *hello*. + +**Support from the infrastructure.** For **uA** to be able to implement +its own read access control at the application layer securely, our +infrastructure is required to support the transaction format for code +deployment and invocation, as depicted in the two figures below. + +.. figure:: ./images/sec-usrconf-deploy-interm.png + :alt: SecRelease-RACappDepl title="Deployment transaction format + supporting application-level read access control." + + SecRelease-RACappDepl title="Deployment transaction format supporting + application-level read access control." + +.. figure:: ./images/sec-usrconf-invoke-interm.png + :alt: SecRelease-RACappInv title="Invocation transaction format + supporting application-level read access control." + + SecRelease-RACappInv title="Invocation transaction format supporting + application-level read access control." + +More specifically fabric layer is required to provide the following +functionality: + +1. Provide minimal encryption capability such that data is only + decryptable by a validator's (infrastructure) side; this means that + the infrastructure should move closer to our future version, where an + asymmetric encryption scheme is used for encrypting transactions. + More specifically, an asymmetric key-pair is used for the chain, + denoted by Kchain in the Figures above, but detailed in Section + Transaction Confidentiality. + +2. The client-application can request the infrastructure sitting on the + client-side to encrypt/decrypt information using a specific public + encryption key, or that client's long-term decryption key. + +3. The transaction format offers the ability to the application to store + additional transaction metadata, that can be passed to the + client-application after the latter's request. Transaction metadata, + as opposed to code-metadata, is not encrypted or provided to the + chain-code at execution time. Validators treat these metadata as a + list of bytes they are not responsible for checking validity of. + +**Application read-access control.** For this reason the application may +request and obtain access to the public encryption key of the user +**ur**; let that be **PKur**. Optionally, **ur** may be providing **uA** +with a certificate of its, that would be leveraged by the application, +say, TCertur; given the latter, the application would, e.g., be able to +trace that user's transactions w.r.t. the application's chain-codes. +TCertur, and PKur, are exchanged in an out-of-band channel. + +At deployment time, application **uA** performs the following steps: + +1. Uses the underlying infrastructure to encrypt the information of + **C**, the application would like to make accessible to **ur**, using + PKur. Let Cur be the resulting ciphertext. + +2. (optional) Cur can be concatenated with TCertur + +3. Passes the overall string as ''Tx-metadata'' of the confidential + transaction to be constructed. + +At invocation time, the client-application on ur's node, would be able, +by obtaining the deployment transaction to retrieve the content of +**C**. It just needs to retrieve the **tx-metadata** field of the +associated deployment transaction, and trigger the decryption +functionality offered by our Blockchain infrastrucure's client, for Cur. +Notice that it is the application's responsibility to encrypt the +correct **C** for ur. Also, the use of **tx-metadata** field can be +generalized to accommodate application-needs. E.g., it can be that +invokers leverage the same field of invocation transactions to pass +information to the developer of the application, etc. + +\ **Important Note:** It is essential to note that validators **do not +provide** any decryption oracle to the chain-code throughout its +execution. Its infrastructure is though responsible for decrypting the +payload of the chain-code itself (as well as the code-metadata fields +near it), and provide those to containers for deployment/execution. + +4.5 Online wallet service +~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section describes the security design of a wallet service, which in +this case is a node with which end-users can register, store their key +material and through which they can perform transactions. Because the +wallet service is in possession of the user's key material, it is clear +that without a secure authorization mechanism in place a malicious +wallet service could successfully impersonate the user. We thus +emphasize that this design corresponds to a wallet service that is +**trusted** to only perform transactions on behalf of its clients, with +the consent of the latter. There are two cases for the registration of +an end-user to an online wallet service: + +1. When the user has registered with the registration authority and + acquired his/her ````, but has not installed the + client to trigger and complete the enrollment process; +2. When the user has already installed the client, and completed the + enrollment phase. + +Initially, the user interacts with the online wallet service to issue +credentials that would allow him to authenticate to the wallet service. +That is, the user is given a username, and password, where username +identifies the user in the membership service, denoted by AccPub, and +password is the associated secret, denoted by AccSec, that is **shared** +by both user and service. + +To enroll through the online wallet service, a user must provide the +following request object to the wallet service: + +:: + + AccountRequest /* account request of u \*/ + { + OBCSecCtx , /* credentials associated to network \*/ + AccPubu, /* account identifier of u \*/ + AccSecProofu /* proof of AccSecu\*/ + } + +OBCSecCtx refers to user credentials, which depending on the stage of +his enrollment process, can be either his enrollment ID and password, +```` or his enrollment certificate and associated +secret key(s) (ECertu, sku), where sku denotes for simplicity signing +and decryption secret of the user. The content of AccSecProofu is an +HMAC on the rest fields of request using the shared secret. Nonce-based +methods similar to what we have in the fabric can be used to protect +against replays. OBCSecCtx would give the online wallet service the +necessary information to enroll the user or issue required TCerts. + +For subsequent requests, the user u should provide to the wallet service +a request of similar format. + +:: + + TransactionRequest /* account request of u \*/ + { + TxDetails, /* specifications for the new transaction \*/ + AccPubu, /* account identifier of u \*/ + AccSecProofu /* proof of AccSecu \*/ + } + +Here, TxDetails refer to the information needed by the online service to +construct a transaction on behalf of the user, i.e., the type, and +user-specified content of the transaction. + +AccSecProofu is again an HMAC on the rest fields of request using the +shared secret. Nonce-based methods similar to what we have in the fabric +can be used to protect against replays. + +TLS connections can be used in each case with server side authentication +to secure the request at the network layer (confidentiality, replay +attack protection, etc) + +4.6 Network security (TLS) +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The TLS CA should be capable of issuing TLS certificates to +(non-validating) peers, validators, and individual clients (or browsers +capable of storing a private key). Preferably, these certificates are +distinguished by type, per above. TLS certificates for CAs of the +various types (such as TLS CA, ECA, TCA) could be issued by an +intermediate CA (i.e., a CA that is subordinate to the root CA). Where +there is not a particular traffic analysis issue, any given TLS +connection can be mutually authenticated, except for requests to the TLS +CA for TLS certificates. + +In the current implementation the only trust anchor is the TLS CA +self-signed certificate in order to accommodate the limitation of a +single port to communicate with all three (co-located) servers, i.e., +the TLS CA, the TCA and the ECA. Consequently, the TLS handshake is +established with the TLS CA, which passes the resultant session keys to +the co-located TCA and ECA. The trust in validity of the TCA and ECA +self-signed certificates is therefore inherited from trust in the TLS +CA. In an implementation that does not thus elevate the TLS CA above +other CAs, the trust anchor should be replaced with a root CA under +which the TLS CA and all other CAs are certified. + +4.7 Restrictions in the current release +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section lists the restrictions of the current release of the +fabric. A particular focus is given on client operations and the design +of transaction confidentiality, as depicted in Sections 4.7.1 and 4.7.2. + +- Client side enrollment and transaction creation is performed entirely + by a non-validating peer that is trusted not to impersonate the user. + See, Section 4.7.1 for more information. +- A minimal set of confidentiality properties where a chaincode is + accessible by any entity that is member of the system, i.e., + validators and users who have registered through Hyperledger Fabric's + Membership Services and is not accessible by anyone else. The latter + include any party that has access to the storage area where the + ledger is maintained, or other entities that are able to see the + transactions that are announced in the validator network. The design + of the first release is detailed in subsection 4.7.2 +- The code utilizes self-signed certificates for entities such as the + enrollment CA (ECA) and the transaction CA (TCA) +- Replay attack resistance mechanism is not available +- Invocation access control can be enforced at the application layer: + it is up to the application to leverage the infrastructure's tools + properly for security to be guaranteed. This means, that if the + application fails to *bind* the transaction binding offered by the + fabric, secure transaction processing may be at risk. + +4.7.1 Simplified client +^^^^^^^^^^^^^^^^^^^^^^^ + +Client-side enrollment and transaction creation are performed entirely +by a non-validating peer that plays the role of an online wallet. In +particular, the end-user leverages their registration credentials to +open an account to a non-validating peer and uses these credentials to +further authorize the peer to build transactions on the user's behalf. +It needs to be noted, that such a design does not provide secure +**authorization** for the peer to submit transactions on behalf of the +user, as a malicious peer could impersonate the user. Details on the +specifications of a design that deals with the security issues of online +wallet can be found is Section 4.5. Currently the maximum number of +peers a user can register to and perform transactions through is one. + +4.7.2 Simplified transaction confidentiality +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**Disclaimer:** The current version of transaction confidentiality is +minimal, and will be used as an intermediate step to reach a design that +allows for fine grained (invocation) access control enforcement in a +subsequent release. + +In its current form, confidentiality of transactions is offered solely +at the chain-level, i.e., that the content of a transaction included in +a ledger, is readable by all members of that chain, i.e., validators and +users. At the same time, application auditors who are not members of the +system can be given the means to perform auditing by passively observing +the blockchain data, while guaranteeing that they are given access +solely to the transactions related to the application under audit. State +is encrypted in a way that such auditing requirements are satisfied, +while not disrupting the proper operation of the underlying consensus +network. + +More specifically, currently symmetric key encryption is supported in +the process of offering transaction confidentiality. In this setting, +one of the main challenges that is specific to the blockchain setting, +is that validators need to run consensus over the state of the +blockchain, that, aside from the transactions themselves, also includes +the state updates of individual contracts or chaincode. Though this is +trivial to do for non-confidential chaincode, for confidential +chaincode, one needs to design the state encryption mechanism such that +the resulting ciphertexts are semantically secure, and yet, identical if +the plaintext state is the same. + +To overcome this challenge, the fabric utilizes a key hierarchy that +reduces the number of ciphertexts that are encrypted under the same key. +At the same time, as some of these keys are used for the generation of +IVs, this allows the validating parties to generate exactly the same +ciphertext when executing the same transaction (this is necessary to +remain agnostic to the underlying consensus algorithm) and offers the +possibility of controlling audit by disclosing to auditing entities only +the most relevant keys. + +**Method description:** Membership service generates a symmetric key for +the ledger (Kchain) that is distributed at registration time to all the +entities of the blockchain system, i.e., the clients and the validating +entities that have issued credentials through the membership service of +the chain. At enrollment phase, user obtain (as before) an enrollment +certificate, denoted by Certui for user ui , while each validator vj +obtains its enrollment certificate denoted by Certvj. + +Entity enrollment would be enhanced, as follows. In addition to +enrollment certificates, users who wish to anonymously participate in +transactions issue transaction certificates. For simplicity transaction +certificates of a user ui are denoted by TCertui. Transaction +certificates include the public part of a signature key-pair denoted by +(tpkui,tskui). + +In order to defeat crypto-analysis and enforce confidentiality, the +following key hierarchy is considered for generation and validation of +confidential transactions: To submit a confidential transaction (Tx) to +the ledger, a client first samples a nonce (N), which is required to be +unique among all the transactions submitted to the blockchain, and +derive a transaction symmetric key (KTx) by applying the HMAC function +keyed with Kchain and on input the nonce, KTx= HMAC(Kchain, N). From +KTx, the client derives two AES keys: KTxCID as HMAC(KTx, c1), KTxP as +HMAC(KTx, c2)) to encrypt respectively the chain-code name or identifier +CID and code (or payload) P. c1, c2 are public constants. The nonce, the +Encrypted Chaincode ID (ECID) and the Encrypted Payload (EP) are added +in the transaction Tx structure, that is finally signed and so +authenticated. Figure below shows how encryption keys for the client's +transaction are generated. Arrows in this figure denote application of +an HMAC, keyed by the key at the source of the arrow and using the +number in the arrow as argument. Deployment/Invocation transactions' +keys are indicated by d/i respectively. + +.. figure:: ./images/sec-firstrel-1.png + :alt: FirstRelease-clientSide + + FirstRelease-clientSide + +To validate a confidential transaction Tx submitted to the blockchain by +a client, a validating entity first decrypts ECID and EP by re-deriving +KTxCID and KTxP from Kchain and Tx.Nonce as done before. Once the +Chaincode ID and the Payload are recovered the transaction can be +processed. + +.. figure:: ./images/sec-firstrel-2.png + :alt: FirstRelease-validatorSide + + FirstRelease-validatorSide + +When V validates a confidential transaction, the corresponding chaincode +can access and modify the chaincode's state. V keeps the chaincode's +state encrypted. In order to do so, V generates symmetric keys as +depicted in the figure above. Let iTx be a confidential transaction +invoking a function deployed at an early stage by the confidential +transaction dTx (notice that iTx can be dTx itself in the case, for +example, that dTx has a setup function that initializes the chaincode's +state). Then, V generates two symmetric keys KIV and Kstate as follows: + +1. It computes as KdTx , i.e., the transaction key of the corresponding + deployment transaction, and then Nstate = HMAC(Kdtx ,hash(Ni)), where + Ni is the nonce appearing in the invocation transaction, and *hash* a + hash function. +2. It sets Kstate = HMAC(KdTx, c3 \|\| Nstate), truncated opportunely + deeding on the underlying cipher used to encrypt; c3 is a constant + number +3. It sets KIV = HMAC(KdTx, c4 \|\| Nstate); c4 is a constant number + +In order to encrypt a state variable S, a validator first generates the +IV as HMAC(KIV, crtstate) properly truncated, where crtstate is a +counter value that increases each time a state update is requested for +the same chaincode invocation. The counter is discarded after the +execution of the chaincode terminates. After IV has been generated, V +encrypts with authentication (i.e., GSM mode) the value of S +concatenated with Nstate(Actually, Nstate doesn't need to be encrypted +but only authenticated). To the resulting ciphertext (CT), Nstate and +the IV used is appended. In order to decrypt an encrypted state CT\|\| +Nstate' , a validator first generates the symmetric keys KdTX' ,Kstate' +using Nstate' and then decrypts CT. + +Generation of IVs: In order to be agnostic to any underlying consensus +algorithm, all the validating parties need a method to produce the same +exact ciphertexts. In order to do so, the validators need to use the +same IVs. Reusing the same IV with the same symmetric key completely +breaks the security of the underlying cipher. Therefore, the process +described before is followed. In particular, V first derives an IV +generation key KIV by computing HMAC(KdTX, c4 \|\| Nstate ), where c4 is +a constant number, and keeps a counter crtstate for the pair (dTx, iTx) +with is initially set to 0. Then, each time a new ciphertext has to be +generated, the validator generates a new IV by computing it as the +output of HMAC(KIV, crtstate) and then increments the crtstate by one. + +Another benefit that comes with the above key hierarchy is the ability +to enable controlled auditing. For example, while by releasing Kchain +one would provide read access to the whole chain, by releasing only +Kstate for a given pair of transactions (dTx,iTx) access would be +granted to a state updated by iTx, and so on. + +The following figures demonstrate the format of a deployment and +invocation transaction currently available in the code. + +.. figure:: ./images/sec-firstrel-depl.png + :alt: FirstRelease-deploy + + FirstRelease-deploy + +.. figure:: ./images/sec-firstrel-inv.png + :alt: FirstRelease-deploy + + FirstRelease-deploy + +One can notice that both deployment and invocation transactions consist +of two sections: + +- Section *general-info*: contains the administration details of the + transaction, i.e., which chain this transaction corresponds to (is + chained to), the type of transaction (that is set to ''deploymTx'' or + ''invocTx''), the version number of confidentiality policy + implemented, its creator identifier (expressed by means of TCert of + Cert) and a nonce (facilitates primarily replay-attack resistance + techniques). + +- Section *code-info*: contains information on the chain-code source + code. For deployment transaction this is essentially the chain-code + identifier/name and source code, while for invocation chain-code is + the name of the function invoked and its arguments. As shown in the + two figures code-info in both transactions are encrypted ultimately + using the chain-specific symmetric key Kchain. + +5. Byzantine Consensus +---------------------- + +The ``pbft`` package is an implementation of the seminal +`PBFT `__ consensus protocol +[1], which provides consensus among validators despite a threshold of +validators acting as *Byzantine*, i.e., being malicious or failing in an +unpredictable manner. In the default configuration, PBFT tolerates up to +t + +The fabric API design covers the categories below, though the +implementation is incomplete for some of them in the current release. +The `REST API <#62-rest-api>`__ section will describe the APIs currently +supported. + +- Identity - Enrollment to acquire or to revoke a certificate +- Address - Target and source of a transaction +- Transaction - Unit of execution on the ledger +- Chaincode - Program running on the ledger +- Blockchain - Contents of the ledger +- Network - Information about the blockchain peer network +- Storage - External store for files or documents +- Event Stream - Sub/pub events on the blockchain + +6.1 REST Service +~~~~~~~~~~~~~~~~ + +The REST service can be enabled (via configuration) on either validating +or non-validating peers, but it is recommended to only enable the REST +service on non-validating peers on production networks. + +:: + + func StartOpenchainRESTServer(server *oc.ServerOpenchain, devops *oc.Devops) + +This function reads the ``rest.address`` value in the ``core.yaml`` +configuration file, which is the configuration file for the ``peer`` +process. The value of the ``rest.address`` key defines the default +address and port on which the peer will listen for HTTP REST requests. + +It is assumed that the REST service receives requests from applications +which have already authenticated the end user. + +6.2 REST API +~~~~~~~~~~~~ + +You can work with the REST API through any tool of your choice. For +example, the curl command line utility or a browser based client such as +the Firefox Rest Client or Chrome Postman. You can likewise trigger REST +requests directly through `Swagger `__. To obtain +the REST API Swagger description, click +`here `__. +The currently available APIs are summarized in the following section. + +6.2.1 REST Endpoints +^^^^^^^^^^^^^^^^^^^^ + +- `Block <#6211-block-api>`__ +- GET /chain/blocks/{block-id} +- `Blockchain <#6212-blockchain-api>`__ +- GET /chain +- `Chaincode <#6213-chaincode-api>`__ +- POST /chaincode +- `Network <#6214-network-api>`__ +- GET /network/peers +- `Registrar <#6215-registrar-api-member-services>`__ +- POST /registrar +- GET /registrar/{enrollmentID} +- DELETE /registrar/{enrollmentID} +- GET /registrar/{enrollmentID}/ecert +- GET /registrar/{enrollmentID}/tcert +- `Transactions <#6216-transactions-api>`__ +- GET /transactions/{UUID} + +6.2.1.1 Block API +''''''''''''''''' + +- **GET /chain/blocks/{block-id}** + +Use the Block API to retrieve the contents of various blocks from the +blockchain. The returned Block message structure is defined in section +`3.2.1.1 <#3211-block>`__. + +Block Retrieval Request: + +:: + + GET host:port/chain/blocks/173 + +Block Retrieval Response: + +:: + + { + "transactions": [ + { + "type": 3, + "chaincodeID": "EgRteWNj", + "payload": "Ch4IARIGEgRteWNjGhIKBmludm9rZRIBYRIBYhICMTA=", + "uuid": "f5978e82-6d8c-47d1-adec-f18b794f570e", + "timestamp": { + "seconds": 1453758316, + "nanos": 206716775 + }, + "cert": "MIIB/zCCAYWgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMTI1MjE0MTE3WhcNMTYwNDI0MjE0MTE3WjArMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQ4wDAYDVQQDEwVsdWthczB2MBAGByqGSM49AgEGBSuBBAAiA2IABC/BBkt8izf6Ew8UDd62EdWFikJhyCPY5VO9Wxq9JVzt3D6nubx2jO5JdfWt49q8V1Aythia50MZEDpmKhtM6z7LHOU1RxuxdjcYDOvkNJo6pX144U4N1J8/D3A+97qZpKN/MH0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDA9BgYqAwQFBgcBAf8EMABNbPHZ0e/2EToi0H8mkouuUDwurgBYuUB+vZfeMewBre3wXG0irzMtfwHlfECRDDAKBggqhkjOPQQDAwNoADBlAjAoote5zYFv91lHzpbEwTfJL/+r+CG7oMVFUFuoSlvBSCObK2bDIbNkW4VQ+ZC9GTsCMQC5GCgy2oZdHw/x7XYzG2BiqmRkLRTiCS7vYCVJXLivU65P984HopxW0cEqeFM9co0=", + "signature": "MGUCMCIJaCT3YRsjXt4TzwfmD9hg9pxYnV13kWgf7e1hAW5Nar//05kFtpVlq83X+YtcmAIxAK0IQlCgS6nqQzZEGCLd9r7cg1AkQOT/RgoWB8zcaVjh3bCmgYHsoPAPgMsi3TJktg==" + } + ], + "stateHash": "7ftCvPeHIpsvSavxUoZM0u7o67MPU81ImOJIO7ZdMoH2mjnAaAAafYy9MIH3HjrWM1/Zla/Q6LsLzIjuYdYdlQ==", + "previousBlockHash": "lT0InRg4Cvk4cKykWpCRKWDZ9YNYMzuHdUzsaeTeAcH3HdfriLEcTuxrFJ76W4jrWVvTBdI1etxuIV9AO6UF4Q==", + "nonHashData": { + "localLedgerCommitTimestamp": { + "seconds": 1453758316, + "nanos": 250834782 + } + } + } + +6.2.1.2 Blockchain API +'''''''''''''''''''''' + +- **GET /chain** + +Use the Chain API to retrieve the current state of the blockchain. The +returned BlockchainInfo message is defined below. + +:: + + message BlockchainInfo { + uint64 height = 1; + bytes currentBlockHash = 2; + bytes previousBlockHash = 3; + } + +- ``height`` - Number of blocks in the blockchain, including the + genesis block. + +- ``currentBlockHash`` - The hash of the current or last block. + +- ``previousBlockHash`` - The hash of the previous block. + +Blockchain Retrieval Request: + +:: + + GET host:port/chain + +Blockchain Retrieval Response: + +:: + + { + "height": 174, + "currentBlockHash": "lIfbDax2NZMU3rG3cDR11OGicPLp1yebIkia33Zte9AnfqvffK6tsHRyKwsw0hZFZkCGIa9wHVkOGyFTcFxM5w==", + "previousBlockHash": "Vlz6Dv5OSy0OZpJvijrU1cmY2cNS5Ar3xX5DxAi/seaHHRPdssrljDeppDLzGx6ZVyayt8Ru6jO+E68IwMrXLQ==" + } + +6.2.1.3 Chaincode API +''''''''''''''''''''' + +- **POST /chaincode** + +Use the Chaincode API to deploy, invoke, and query chaincodes. The +deploy request requires the client to supply a ``path`` parameter, +pointing to the directory containing the chaincode in the file system. +The response to a deploy request is either a message containing a +confirmation of successful chaincode deployment or an error, containing +a reason for the failure. It also contains the generated chaincode +``name`` in the ``message`` field, which is to be used in subsequent +invocation and query transactions to uniquely identify the deployed +chaincode. + +To deploy a chaincode, supply the required ChaincodeSpec payload, +defined in section `3.1.2.2 <#3122-transaction-specification>`__. + +Deploy Request: + +:: + + POST host:port/chaincode + + { + "jsonrpc": "2.0", + "method": "deploy", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "path":"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" + }, + "input": { + "function":"init", + "args":["a", "1000", "b", "2000"] + } + }, + "id": "1" + } + +Deploy Response: + +:: + + { + "jsonrpc": "2.0", + "result": { + "status": "OK", + "message": "52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" + }, + "id": 1 + } + +With security enabled, modify the required payload to include the +``secureContext`` element passing the enrollment ID of a logged in user +as follows: + +Deploy Request with security enabled: + +:: + + POST host:port/chaincode + + { + "jsonrpc": "2.0", + "method": "deploy", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "path":"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" + }, + "input": { + "function":"init", + "args":["a", "1000", "b", "2000"] + }, + "secureContext": "lukas" + }, + "id": "1" + } + +The invoke request requires the client to supply a ``name`` parameter, +which was previously returned in the response from the deploy +transaction. The response to an invocation request is either a message +containing a confirmation of successful execution or an error, +containing a reason for the failure. + +To invoke a function within a chaincode, supply the required +ChaincodeSpec payload, defined in section +`3.1.2.2 <#3122-transaction-specification>`__. + +Invoke Request: + +:: + + POST host:port/chaincode + + { + "jsonrpc": "2.0", + "method": "invoke", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" + }, + "input": { + "function":"invoke", + "args":["a", "b", "100"] + } + }, + "id": "3" + } + +Invoke Response: + +:: + + { + "jsonrpc": "2.0", + "result": { + "status": "OK", + "message": "5a4540e5-902b-422d-a6ab-e70ab36a2e6d" + }, + "id": 3 + } + +With security enabled, modify the required payload to include the +``secureContext`` element passing the enrollment ID of a logged in user +as follows: + +Invoke Request with security enabled: + +:: + + { + "jsonrpc": "2.0", + "method": "invoke", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" + }, + "input": { + "function":"invoke", + "args":["a", "b", "100"] + }, + "secureContext": "lukas" + }, + "id": "3" + } + +The query request requires the client to supply a ``name`` parameter, +which was previously returned in the response from the deploy +transaction. The response to a query request depends on the chaincode +implementation. The response will contain a message containing a +confirmation of successful execution or an error, containing a reason +for the failure. In the case of successful execution, the response will +also contain values of requested state variables within the chaincode. + +To invoke a query function within a chaincode, supply the required +ChaincodeSpec payload, defined in section +`3.1.2.2 <#3122-transaction-specification>`__. + +Query Request: + +:: + + POST host:port/chaincode/ + + { + "jsonrpc": "2.0", + "method": "query", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" + }, + "input": { + "function":"query", + "args":["a"] + } + }, + "id": "5" + } + +Query Response: + +:: + + { + "jsonrpc": "2.0", + "result": { + "status": "OK", + "message": "-400" + }, + "id": 5 + } + +With security enabled, modify the required payload to include the +``secureContext`` element passing the enrollment ID of a logged in user +as follows: + +Query Request with security enabled: + +:: + + { + "jsonrpc": "2.0", + "method": "query", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" + }, + "input": { + "function":"query", + "args":["a"] + }, + "secureContext": "lukas" + }, + "id": "5" + } + +6.2.1.4 Network API +''''''''''''''''''' + +Use the Network API to retrieve information about the network of peer +nodes comprising the blockchain fabric. + +The /network/peers endpoint returns a list of all existing network +connections for the target peer node. The list includes both validating +and non-validating peers. The list of peers is returned as type +``PeersMessage``, containing an array of ``PeerEndpoint``, defined in +section `3.1.1 <#311-discovery-messages>`__. + +:: + + message PeersMessage { + repeated PeerEndpoint peers = 1; + } + +Network Request: + +:: + + GET host:port/network/peers + +Network Response: + +:: + + { + "peers": [ + { + "ID": { + "name": "vp1" + }, + "address": "172.17.0.4:7051", + "type": 1, + "pkiID": "rUA+vX2jVCXev6JsXDNgNBMX03IV9mHRPWo6h6SI0KLMypBJLd+JoGGlqFgi+eq/" + }, + { + "ID": { + "name": "vp3" + }, + "address": "172.17.0.5:7051", + "type": 1, + "pkiID": "OBduaZJ72gmM+B9wp3aErQlofE0ulQfXfTHh377ruJjOpsUn0MyvsJELUTHpAbHI" + }, + { + "ID": { + "name": "vp2" + }, + "address": "172.17.0.6:7051", + "type": 1, + "pkiID": "GhtP0Y+o/XVmRNXGF6pcm9KLNTfCZp+XahTBqVRmaIumJZnBpom4ACayVbg4Q/Eb" + } + ] + } + +6.2.1.5 Registrar API (member services) +''''''''''''''''''''''''''''''''''''''' + +- **POST /registrar** +- **GET /registrar/{enrollmentID}** +- **DELETE /registrar/{enrollmentID}** +- **GET /registrar/{enrollmentID}/ecert** +- **GET /registrar/{enrollmentID}/tcert** + +Use the Registrar APIs to manage end user registration with the +certificate authority (CA). These API endpoints are used to register a +user with the CA, determine whether a given user is registered, and to +remove any login tokens for a target user from local storage, preventing +them from executing any further transactions. The Registrar APIs are +also used to retrieve user enrollment and transaction certificates from +the system. + +The ``/registrar`` endpoint is used to register a user with the CA. The +required Secret payload is defined below. The response to the +registration request is either a confirmation of successful registration +or an error, containing a reason for the failure. + +:: + + message Secret { + string enrollId = 1; + string enrollSecret = 2; + } + +- ``enrollId`` - Enrollment ID with the certificate authority. +- ``enrollSecret`` - Enrollment password with the certificate + authority. + +Enrollment Request: + +:: + + POST host:port/registrar + + { + "enrollId": "lukas", + "enrollSecret": "NPKYL39uKbkj" + } + +Enrollment Response: + +:: + + { + "OK": "Login successful for user 'lukas'." + } + +The ``GET /registrar/{enrollmentID}`` endpoint is used to confirm +whether a given user is registered with the CA. If so, a confirmation +will be returned. Otherwise, an authorization error will result. + +Verify Enrollment Request: + +:: + + GET host:port/registrar/jim + +Verify Enrollment Response: + +:: + + { + "OK": "User jim is already logged in." + } + +Verify Enrollment Request: + +:: + + GET host:port/registrar/alex + +Verify Enrollment Response: + +:: + + { + "Error": "User alex must log in." + } + +The ``DELETE /registrar/{enrollmentID}`` endpoint is used to delete +login tokens for a target user. If the login tokens are deleted +successfully, a confirmation will be returned. Otherwise, an +authorization error will result. No payload is required for this +endpoint. + +Remove Enrollment Request: + +:: + + DELETE host:port/registrar/lukas + +Remove Enrollment Response: + +:: + + { + "OK": "Deleted login token and directory for user lukas." + } + +The ``GET /registrar/{enrollmentID}/ecert`` endpoint is used to retrieve +the enrollment certificate of a given user from local storage. If the +target user has already registered with the CA, the response will +include a URL-encoded version of the enrollment certificate. If the +target user has not yet registered, an error will be returned. If the +client wishes to use the returned enrollment certificate after +retrieval, keep in mind that it must be URL-decoded. + +Enrollment Certificate Retrieval Request: + +:: + + GET host:port/registrar/jim/ecert + +Enrollment Certificate Retrieval Response: + +:: + + { + "OK": "-----BEGIN+CERTIFICATE-----%0AMIIBzTCCAVSgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwNPQkMwHhcNMTYwMTIxMDYzNjEwWhcNMTYwNDIw%0AMDYzNjEwWjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNP%0AQkMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARSLgjGD0omuJKYrJF5ClyYb3sGEGTU%0AH1mombSAOJ6GAOKEULt4L919sbSSChs0AEvTX7UDf4KNaKTrKrqo4khCoboMg1VS%0AXVTTPrJ%2BOxSJTXFZCohVgbhWh6ZZX2tfb7%2BjUDBOMA4GA1UdDwEB%2FwQEAwIHgDAM%0ABgNVHRMBAf8EAjAAMA0GA1UdDgQGBAQBAgMEMA8GA1UdIwQIMAaABAECAwQwDgYG%0AUQMEBQYHAQH%2FBAE0MAoGCCqGSM49BAMDA2cAMGQCMGz2RR0NsJOhxbo0CeVts2C5%0A%2BsAkKQ7v1Llbg78A1pyC5uBmoBvSnv5Dd0w2yOmj7QIwY%2Bn5pkLiwisxWurkHfiD%0AxizmN6vWQ8uhTd3PTdJiEEckjHKiq9pwD%2FGMt%2BWjP7zF%0A-----END+CERTIFICATE-----%0A" + } + +The ``/registrar/{enrollmentID}/tcert`` endpoint retrieves the +transaction certificates for a given user that has registered with the +certificate authority. If the user has registered, a confirmation +message will be returned containing an array of URL-encoded transaction +certificates. Otherwise, an error will result. The desired number of +transaction certificates is specified with the optional 'count' query +parameter. The default number of returned transaction certificates is 1; +and 500 is the maximum number of certificates that can be retrieved with +a single request. If the client wishes to use the returned transaction +certificates after retrieval, keep in mind that they must be +URL-decoded. + +Transaction Certificate Retrieval Request: + +:: + + GET host:port/registrar/jim/tcert + +Transaction Certificate Retrieval Response: + +:: + + { + "OK": [ + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQfwJORRED9RAsmSl%2FEowq1STBb%0A%2FoFteymZ96RUr%2BsKmF9PNrrUNvFZFhvukxZZjqhEcGiQqFyRf%2FBnVN%2BbtRzMo38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwSRWQFmErr0SmQO9AFP4GJYzQ%0APQMmcsCjKiJf%2Bw1df%2FLnXunCsCUlf%2FalIUaeSrT7MAoGCCqGSM49BAMDA0gAMEUC%0AIQC%2FnE71FBJd0hwNTLXWmlCJff4Yi0J%2BnDi%2BYnujp%2Fn9nQIgYWg0m0QFzddyJ0%2FF%0AKzIZEJlKgZTt8ZTlGg3BBrgl7qY%3D%0A-----END+CERTIFICATE-----%0A" + ] + } + +Transaction Certificate Retrieval Request: + +:: + + GET host:port/registrar/jim/tcert?count=5 + +Transaction Certificate Retrieval Response: + +:: + + { + "OK": [ + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A" + ] + } + +6.2.1.6 Transactions API +'''''''''''''''''''''''' + +- **GET /transactions/{UUID}** + +Use the Transaction API to retrieve an individual transaction matching +the UUID from the blockchain. The returned transaction message is +defined in section `3.1.2.1 <#3121-transaction-data-structure>`__. + +Transaction Retrieval Request: + +:: + + GET host:port/transactions/f5978e82-6d8c-47d1-adec-f18b794f570e + +Transaction Retrieval Response: + +:: + + { + "type": 3, + "chaincodeID": "EgRteWNj", + "payload": "Ch4IARIGEgRteWNjGhIKBmludm9rZRIBYRIBYhICMTA=", + "uuid": "f5978e82-6d8c-47d1-adec-f18b794f570e", + "timestamp": { + "seconds": 1453758316, + "nanos": 206716775 + }, + "cert": "MIIB/zCCAYWgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMTI1MjE0MTE3WhcNMTYwNDI0MjE0MTE3WjArMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQ4wDAYDVQQDEwVsdWthczB2MBAGByqGSM49AgEGBSuBBAAiA2IABC/BBkt8izf6Ew8UDd62EdWFikJhyCPY5VO9Wxq9JVzt3D6nubx2jO5JdfWt49q8V1Aythia50MZEDpmKhtM6z7LHOU1RxuxdjcYDOvkNJo6pX144U4N1J8/D3A+97qZpKN/MH0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDA9BgYqAwQFBgcBAf8EMABNbPHZ0e/2EToi0H8mkouuUDwurgBYuUB+vZfeMewBre3wXG0irzMtfwHlfECRDDAKBggqhkjOPQQDAwNoADBlAjAoote5zYFv91lHzpbEwTfJL/+r+CG7oMVFUFuoSlvBSCObK2bDIbNkW4VQ+ZC9GTsCMQC5GCgy2oZdHw/x7XYzG2BiqmRkLRTiCS7vYCVJXLivU65P984HopxW0cEqeFM9co0=", + "signature": "MGUCMCIJaCT3YRsjXt4TzwfmD9hg9pxYnV13kWgf7e1hAW5Nar//05kFtpVlq83X+YtcmAIxAK0IQlCgS6nqQzZEGCLd9r7cg1AkQOT/RgoWB8zcaVjh3bCmgYHsoPAPgMsi3TJktg==" + } + +6.3 CLI +~~~~~~~ + +The CLI includes a subset of the available APIs to enable developers to +quickly test and debug chaincodes or query for status of transactions. +CLI is implemented in Golang and operable on multiple OS platforms. The +currently available CLI commands are summarized in the following +section. + +6.3.1 CLI Commands +^^^^^^^^^^^^^^^^^^ + +To see what CLI commands are currently available in the implementation, +execute the following: + +:: + + $ peer + +You will receive a response similar to below: + +:: + + Usage: + peer [command] + + Available Commands: + node node specific commands. + network network specific commands. + chaincode chaincode specific commands. + help Help about any command + + Flags: + -h, --help[=false]: help for peer + --logging-level="": Default logging level and overrides, see core.yaml for full syntax + + Use "peer [command] --help" for more information about a command. + +Some of the available command line arguments for the ``peer`` command +are listed below: + +- ``-c`` - constructor: function to trigger in order to initialize the + chaincode state upon deployment. + +- ``-l`` - language: specifies the implementation language of the + chaincode. Currently, only Golang is supported. + +- ``-n`` - name: chaincode identifier returned from the deployment + transaction. Must be used in subsequent invoke and query + transactions. + +- ``-p`` - path: identifies chaincode location in the local file + system. Must be used as a parameter in the deployment transaction. + +- ``-u`` - username: enrollment ID of a logged in user invoking the + transaction. + +Not all of the above commands are fully implemented in the current +release. The fully supported commands that are helpful for chaincode +development and debugging are described below. + +Note, that any configuration settings for the peer node listed in the +``core.yaml`` configuration file, which is the configuration file for +the ``peer`` process, may be modified on the command line with an +environment variable. For example, to set the ``peer.id`` or the +``peer.addressAutoDetect`` settings, one may pass the +``CORE_PEER_ID=vp1`` and ``CORE_PEER_ADDRESSAUTODETECT=true`` on the +command line. + +6.3.1.1 node start +'''''''''''''''''' + +The CLI ``node start`` command will execute the peer process in either +the development or production mode. The development mode is meant for +running a single peer node locally, together with a local chaincode +deployment. This allows a chaincode developer to modify and debug their +code without standing up a complete network. An example for starting the +peer in development mode follows: + +:: + + peer node start --peer-chaincodedev + +To start the peer process in production mode, modify the above command +as follows: + +:: + + peer node start + +6.3.1.2 network login +''''''''''''''''''''' + +The CLI ``network login`` command will login a user, that is already +registered with the CA, through the CLI. To login through the CLI, issue +the following command, where ``username`` is the enrollment ID of a +registered user. + +:: + + peer network login + +The example below demonstrates the login process for user ``jim``. + +:: + + peer network login jim + +The command will prompt for a password, which must match the enrollment +password for this user registered with the certificate authority. If the +password entered does not match the registered password, an error will +result. + +:: + + 22:21:31.246 [main] login -> INFO 001 CLI client login... + 22:21:31.247 [main] login -> INFO 002 Local data store for client loginToken: /var/hyperledger/production/client/ + Enter password for user 'jim': ************ + 22:21:40.183 [main] login -> INFO 003 Logging in user 'jim' on CLI interface... + 22:21:40.623 [main] login -> INFO 004 Storing login token for user 'jim'. + 22:21:40.624 [main] login -> INFO 005 Login successful for user 'jim'. + +You can also pass a password for the user with ``-p`` parameter. An +example is below. + +:: + + peer network login jim -p 123456 + +6.3.1.3 chaincode deploy +'''''''''''''''''''''''' + +The CLI ``deploy`` command creates the docker image for the chaincode +and subsequently deploys the package to the validating peer. An example +is below. + +:: + + peer chaincode deploy -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' + +With security enabled, the command must be modified to pass an +enrollment id of a logged in user with the ``-u`` parameter. An example +is below. + +:: + + peer chaincode deploy -u jim -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' + +**Note:** If your GOPATH environment variable contains more than one +element, the chaincode must be found in the first one or deployment will +fail. + +6.3.1.4 chaincode invoke +'''''''''''''''''''''''' + +The CLI ``invoke`` command executes a specified function within the +target chaincode. An example is below. + +:: + + peer chaincode invoke -n -c '{"Function": "invoke", "Args": ["a", "b", "10"]}' + +With security enabled, the command must be modified to pass an +enrollment id of a logged in user with the ``-u`` parameter. An example +is below. + +:: + + peer chaincode invoke -u jim -n -c '{"Function": "invoke", "Args": ["a", "b", "10"]}' + +6.3.1.5 chaincode query +''''''''''''''''''''''' + +The CLI ``query`` command triggers a specified query method within the +target chaincode. The response that is returned depends on the chaincode +implementation. An example is below. + +:: + + peer chaincode query -l golang -n -c '{"Function": "query", "Args": ["a"]}' + +With security enabled, the command must be modified to pass an +enrollment id of a logged in user with the ``-u`` parameter. An example +is below. + +:: + + peer chaincode query -u jim -l golang -n -c '{"Function": "query", "Args": ["a"]}' + +7. Application Model +-------------------- + +7.1 Composition of an Application +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + +
+ +.. raw:: html + + + +An application follows a MVC-B architecture – Model, View, Control, +BlockChain. + +.. raw:: html + +

+ +.. raw:: html + +

+ +.. raw:: html + +

    + +.. raw:: html + +
  • + +VIEW LOGIC – Mobile or Web UI interacting with control logic. + +.. raw:: html + +
  • + +.. raw:: html + +
  • + +CONTROL LOGIC – Coordinates between UI, Data Model and APIs to drive +transitions and chain-code. + +.. raw:: html + +
  • + +.. raw:: html + +
  • + +DATA MODEL – Application Data Model – manages off-chain data, including +Documents and large files. + +.. raw:: html + +
  • + +.. raw:: html + +
  • + +BLOCKCHAIN LOGIC – Blockchain logic are extensions of the Controller +Logic and Data Model, into the Blockchain realm. Controller logic is +enhanced by chaincode, and the data model is enhanced with transactions +on the blockchain. + +.. raw:: html + +
  • + +.. raw:: html + +
+ +.. raw:: html + +

+ +For example, a Bluemix PaaS application using Node.js might have a Web +front-end user interface or a native mobile app with backend model on +Cloudant data service. The control logic may interact with 1 or more +chaincodes to process transactions on the blockchain. + +.. raw:: html + +

+ +7.2 Sample Application +~~~~~~~~~~~~~~~~~~~~~~ + +8. Future Directions +-------------------- + +8.1 Enterprise Integration +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +8.2 Performance and Scalability +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +8.3 Additional Consensus Plugins +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +8.4 Additional Languages +~~~~~~~~~~~~~~~~~~~~~~~~ + +9.1 Authors +~~~~~~~~~~~ + +The following authors have written sections of this document: Binh Q +Nguyen, Elli Androulaki, Angelo De Caro, Sheehan Anderson, Manish Sethi, +Thorsten Kramp, Alessandro Sorniotti, Marko Vukolic, Florian Simon +Schubert, Jason K Yellick, Konstantinos Christidis, Srinivasan +Muralidharan, Anna D Derbakova, Dulce Ponceleon, David Kravitz, Diego +Masini. + +9.2 Reviewers +~~~~~~~~~~~~~ + +The following reviewers have contributed to this document: Frank Lu, +John Wolpert, Bishop Brock, Nitin Gaur, Sharon Weed, Konrad Pabjan. + +9.3 Acknowledgements +~~~~~~~~~~~~~~~~~~~~ + +The following contributors have provided invaluable technical input to +this specification: Gennaro Cuomo, Joseph A Latone, Christian Cachin + +10. References +-------------- + +- [1] Miguel Castro, Barbara Liskov: Practical Byzantine fault + tolerance and proactive recovery. ACM Trans. Comput. Syst. 20(4): + 398-461 (2002) + +- [2] Christian Cachin, Rachid Guerraoui, Luís E. T. Rodrigues: + Introduction to Reliable and Secure Distributed Programming (2. ed.). + Springer 2011, ISBN 978-3-642-15259-7, pp. I-XIX, 1-367 + +- [3] Tushar Deepak Chandra, Vassos Hadzilacos, Sam Toueg: The Weakest + Failure Detector for Solving Consensus. J. ACM 43(4): 685-722 (1996) + +- [4] Cynthia Dwork, Nancy A. Lynch, Larry J. Stockmeyer: Consensus in + the presence of partial synchrony. J. ACM 35(2): 288-323 (1988) + +- [5] Manos Kapritsos, Yang Wang, Vivien Quéma, Allen Clement, Lorenzo + Alvisi, Mike Dahlin: All about Eve: Execute-Verify Replication for + Multi-Core Servers. OSDI 2012: 237-250 + +- [6] Pierre-Louis Aublin, Rachid Guerraoui, Nikola Knezevic, Vivien + Quéma, Marko Vukolic: The Next 700 BFT Protocols. ACM Trans. Comput. + Syst. 32(4): 12:1-12:45 (2015) + +- [7] Christian Cachin, Simon Schubert, Marko Vukolić: `Non-determinism + in Byzantine Fault-Tolerant + Replication `__ + +.. |figure-architecture| image:: ./images/sec-sec-arch.png +.. |Figure 5| image:: ./images/sec-request-tcerts-deployment.png +.. |Figure 6| image:: ./images/sec-request-tcerts-invocation.png +.. |Reference architecture| image:: images/refarch-api.png + diff --git a/docs/source/protocol-spec_zh.rst b/docs/source/protocol-spec_zh.rst new file mode 100644 index 00000000000..7351d3e8fce --- /dev/null +++ b/docs/source/protocol-spec_zh.rst @@ -0,0 +1,3522 @@ +协议规范 +======== + +前言 +---- + +这份文档是带有权限的区块链的工业界实现的协议规范。它不会详细的解释实现细节,而是描述系统和应用之间的接口和关系。 + +目标读者 +~~~~~~~~ + +这份规范的目标读者包括: + +- 想实现符合这份规范的区块链的厂商 +- 想扩展 fabric 功能的工具开发者 +- 想利用区块链技术来丰富他们应用的应用开发者 + +作者 +~~~~ + +下面这些作者编写了这份分档: Binh Q Nguyen, Elli Androulaki, Angelo De +Caro, Sheehan Anderson, Manish Sethi, Thorsten Kramp, Alessandro +Sorniotti, Marko Vukolic, Florian Simon Schubert, Jason K Yellick, +Konstantinos Christidis, Srinivasan Muralidharan, Anna D Derbakova, +Dulce Ponceleon, David Kravitz, Diego Masini. + +评审 +~~~~ + +下面这些评审人评审了这份文档: Frank Lu, John Wolpert, Bishop Brock, +Nitin Gaur, Sharon Weed, Konrad Pabjan. + +致谢 +~~~~ + +下面这些贡献者对这份规范提供了技术支持: Gennaro Cuomo, Joseph A Latone, +Christian Cachin +\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ + +目录 +---- + +1. 介绍 +^^^^^^^ + +- 1.1 什么是 fabric ? +- 1.2 为什么是 fabric ? +- 1.3 术语 + +2. Fabric +^^^^^^^^^ + +- 2.1 架构 +- 2.1.1 Membership 服务 +- 2.1.2 Blockchain 服务 +- 2.1.3 Chaincode 服务 +- 2.1.4 事件 +- 2.1.5 应用程序接口 +- 2.1.6 命令行界面 +- 2.2 拓扑 +- 2.2.1 单验证 Peer +- 2.2.2 多验证 Peers +- 2.2.3 多链 + +3. 协议 +^^^^^^^ + +- 3.1 消息 +- 3.1.1 发现消息 +- 3.1.2 交易消息 +- 3.1.2.1 交易数据结构 +- 3.1.2.2 交易规范 +- 3.1.2.3 交易部署 +- 3.1.2.4 交易调用 +- 3.1.2.5 交易查询 +- 3.1.3 同步消息 +- 3.1.4 共识消息 +- 3.2 总账 +- 3.2.1 区块链 +- 3.2.1.1 块 +- 3.2.1.2 块 Hashing +- 3.2.1.3 非散列数据(NonHashData) +- 3.2.1.4 交易 +- 3.2.2 世界状态(World State) +- 3.2.2.1 世界状态的 Hashing +- 3.2.2.1.1 Bucket-tree +- 3.3 Chaincode +- 3.3.1 Virtual Machine 实例化 +- 3.3.2 Chaincode 协议 +- 3.3.2.1 Chaincode 部署 +- 3.3.2.2 Chaincode 调用 +- 3.3.2.3 Chaincode 查询 +- 3.3.2.4 Chaincode 状态 +- 3.4 可插拔的共识框架 +- 3.4.1 共识者接口 +- 3.4.2 共识程序接口 +- 3.4.3 Inquirer 接口 +- 3.4.4 Communicator 接口 +- 3.4.5 SecurityUtils 接口 +- 3.4.6 LedgerStack 接口 +- 3.4.7 Executor 接口 +- 3.4.7.1 开始批量交易 +- 3.4.7.2 执行交易 +- 3.4.7.3 提交与回滚交易 +- 3.4.8 Ledger 接口 +- 3.4.8.1 ReadOnlyLedger 接口 +- 3.4.8.2 UtilLedger 接口 +- 3.4.8.3 WritableLedger 接口 +- 3.4.9 RemoteLedgers 接口 +- 3.4.10 Controller 包 +- 3.4.11 Helper 包 +- 3.5 事件 +- 3.5.1 事件流 +- 3.5.2 事件结构 +- 3.5.3 事件适配器 + +4. 安全 +^^^^^^^ + +- + + 4. 安全 + +- 4.1 商业安全需求 +- 4.2 使用成员管理的用户隐私 +- 4.2.1 用户/客户端注册过程 +- 4.2.2 过期和废止证书 +- 4.3 基础设施层面提供的交易安全 +- 4.3.1 交易的安全生命周期 +- 4.3.2 交易保密性 +- 4.3.2.1 针对用户的保密 +- 4.3.2.2 针对验证器的保密 +- 4.3.3 防重放攻击 +- 4.4 应用的访问控制功能 +- 4.4.1 调用访问控制 +- 4.4.2 读访问控制 +- 4.5 在线钱包服务 +- 4.6 网络安全(TLS) +- 4.7 当前版本的限制 +- 4.7.1 简化客户端 +- 4.7.2 简化交易保密 + +5. 拜占庭共识 +^^^^^^^^^^^^^ + +- 5.1 概览 +- 5.2 Core PBFT + +6. 应用编程接口 +^^^^^^^^^^^^^^^ + +- 6.1 REST 服务 +- 6.2 REST API +- 6.3 CLI + +7. 应用模型 +^^^^^^^^^^^ + +- 7.1 应用组成 +- 7.2 应用样例 + +8. 未来发展方向 +^^^^^^^^^^^^^^^ + +- 8.1 企业集成 +- 8.2 性能与可扩展性 +- 8.3 附加的共识插件 +- 8.4 附加的语言 + +9. References +^^^^^^^^^^^^^ + +-------------- + +1. 介绍 +------- + +这份文档规范了适用于工业界的区块链的概念,架构和协议。 + +1.1 什么是 fabric? +~~~~~~~~~~~~~~~~~~ + +fabric +是在系统中数字事件,交易调用,不同参与者共享的总账。总账只能通过共识的参与者来更新,而且一旦被记录,信息永远不能被修改。每一个记录的事件都可以根据参与者的协议进行加密验证。 + +交易是安全的,私有的并且可信的。每个参与者通过向网络membership服务证明自己的身份来访问系统。交易是通过发放给各个的参与者,不可连接的,提供在网络上完全匿名的证书来生成的。交易内容通过复杂的密钥加密来保证只有参与者才能看到,确保业务交易私密性。 + +总账可以按照规定规则来审计全部或部分总账分录。在与参与者合作中,审计员可以通过基于时间的证书来获得总账的查看,连接交易来提供实际的资产操作。 + +fabric +是区块链技术的一种实现,比特币是可以在fabric上构建的一种简单应用。它通过模块化的架构来允许组件的“插入-运行”来实现这份协议规范。它具有强大的容器技术来支持任何主流的语言来开发智能合约。利用熟悉的和被证明的技术是fabric的座右铭。 + +1.2 为什么是 fabric? +~~~~~~~~~~~~~~~~~~~~ + +早期的区块链技术提供一个目的集合,但是通常对具体的工业应用支持的不是很好。为了满足现代市场的需求,fabric +是基于工业关注点针对特定行业的多种多样的需求来设计的,并引入了这个领域内的开拓者的经验,如扩展性。fabric +为权限网络,隐私,和多个区块链网络的私密信息提供一种新的方法。 + +1.3 术语 +~~~~~~~~ + +以下术语在此规范的有限范围内定义,以帮助读者清楚准确的了解这里所描述的概念。 + +**交易(Transaction)** +是区块链上执行功能的一个请求。功能是使用\ **链码(Chaincode)**\ 来实现的。 + +**交易者(Transactor)** 是向客户端应用这样发出交易的实体。 + +**总账(Ledger)** 是一系列包含交易和当前\ **世界状态(World +State)**\ 的加密的链接块。 + +**世界状态(World State)** 是包含交易执行结果的变量集合。 + +**链码(Chaincode)** +是作为交易的一部分保存在总账上的应用级的代码(如\ `智能合约 `__\ )。链码运行的交易可能会改变世界状态。 + +**验证Peer(Validating Peer)** +是网络中负责达成共识,验证交易并维护总账的一个计算节点。 + +**非验证Peer(Non-validating Peer)** +是网络上作为代理把交易员连接到附近验证节点的计算节点。非验证Peer只验证交易但不执行它们。它还承载事件流服务和REST服务。 + +**带有权限的总账(Permissioned Ledger)** +是一个由每个实体或节点都是网络成员所组成的区块链网络。匿名节点是不允许连接的。 + +**隐私(Privacy)** +是链上的交易者需要隐瞒自己在网络上身份。虽然网络的成员可以查看交易,但是交易在没有得到特殊的权限前不能连接到交易者。 + +**保密(Confidentiality)** 是交易的内容不能被非利益相关者访问到的功能。 + +**可审计性(Auditability)** +作为商业用途的区块链需要遵守法规,很容易让监管机构审计交易记录。所以区块链是必须的。 + +2. Fabric +--------- + +fabric是由下面这个小节所描述的核心组件所组成的。 + +2.1 架构 +~~~~~~~~ + +这个架构参考关注在三个类别中:会员(Membership),区块链(Blockchan)和链码(chaincode)。这些类别是逻辑结构,而不是物理上的把不同的组件分割到独立的进程,地址空间,(虚拟)机器中。 + +.. figure:: images/refarch.png + :alt: Reference architecture + + Reference architecture + +2.1.1 成员服务 +~~~~~~~~~~~~~~ + +成员服务为网络提供身份管理,隐私,保密和可审计性的服务。在一个不带权限的区块链中,参与者是不需要被授权的,且所有的节点都可以同样的提交交易并把它们汇集到可接受的块中,既:它们没有角色的区分。成员服务通过公钥基础设施(Public +Key Infrastructure +(PKI))和去中心化的/共识技术使得不带权限的区块链变成带权限的区块链。在后者中,通过实体注册来获得长时间的,可能根据实体类型生成的身份凭证(登记证书enrollment +certificates)。在用户使用过程中,这样的证书允许交易证书颁发机构(Transaction +Certificate Authority +(TCA))颁发匿名证书。这样的证书,如交易证书,被用来对提交交易授权。交易证书存储在区块链中,并对审计集群授权,否则交易是不可链接的。 + +2.1.2 区块链服务 +~~~~~~~~~~~~~~~~ + +区块链服务通过 HTTP/2 +上的点对点(peer-to-peer)协议来管理分布式总账。为了提供最高效的哈希算法来维护世界状态的复制,数据结构进行了高度的优化。每个部署中可以插入和配置不同的共识算法(PBFT, +Raft, PoW, PoS)。 + +2.1.3 链码服务 +~~~~~~~~~~~~~~ + +链码服务提供一个安全的,轻量的沙箱在验证节点上执行链码。环境是一个“锁定的”且安全的包含签过名的安全操作系统镜像和链码语言,Go,Java +和 Node.js 的运行时和 SDK 层。可以根据需要来启用其他语言。 + +2.1.4 事件 +~~~~~~~~~~ + +验证 peers +和链码可以向在网络上监听并采取行动的应用发送事件。这是一些预定义好的事件集合,链码可以生成客户化的事件。事件会被一个或多个事件适配器消费。之后适配器可能会把事件投递到其他设备,如 +Web hooks 或 Kafka。 + +2.1.5 应用编程接口(API) +~~~~~~~~~~~~~~~~~~~~~~~ + +fabric的主要接口是 REST API,并通过 Swagger 2.0 来改变。API +允许注册用户,区块链查询和发布交易。链码与执行交易的堆间的交互和交易的结果查询会由 +API 集合来规范。 + +2.1.6 命令行界面(CLI) +~~~~~~~~~~~~~~~~~~~~~ + +CLI包含REST API的一个子集使得开发者能更快的测试链码或查询交易状态。CLI +是通过 Go 语言来实现,并可在多种操作系统上操作。 + +2.2 拓扑 +~~~~~~~~ + +fabric 的一个部署是由成员服务,多个验证 peers、非验证 peers +和一个或多个应用所组成一个链。也可以有多个链,各个链具有不同的操作参数和安全要求。 + +2.2.1 单验证Peer +~~~~~~~~~~~~~~~~ + +功能上讲,一个非验证 peer 是验证 peer 的子集;非验证 peer +上的功能都可以在验证 peer +上启用,所以在最简单的网络上只有一个验证peer组成。这个配置通常使用在开发环境:单个验证 +peer 在编辑-编译-调试周期中被启动。 + +.. figure:: images/top-single-peer.png + :alt: Single Validating Peer + + Single Validating Peer + +单个验证 peer +不需要共识,默认情况下使用\ ``noops``\ 插件来处理接收到的交易。这使得在开发中,开发人员能立即收到返回。 + +2.2.2 多验证 Peer +~~~~~~~~~~~~~~~~~ + +生产或测试网络需要有多个验证和非验证 peers 组成。非验证 peer 可以为验证 +peer 分担像 API 请求处理或事件处理这样的压力。 + +.. figure:: images/top-multi-peer.png + :alt: Multiple Validating Peers + + Multiple Validating Peers + +网状网络(每个验证peer需要和其它验证peer都相连)中的验证 peer +来传播信息。一个非验证 peer 连接到附近的,允许它连接的验证 +peer。当应用可能直接连接到验证 peer 时,非验证 peer 是可选的。 + +2.2.3 多链 +~~~~~~~~~~ + +验证和非验证 peer +的各个网络组成一个链。可以根据不同的需求创建不同的链,就像根据不同的目的创建不同的 +Web 站点。 + +3. 协议 +------- + +fabric的点对点(peer-to-peer)通信是建立在允许双向的基于流的消息\ `gRPC `__\ 上的。它使用\ `Protocol +Buffers `__\ 来序列化peer之间传输的数据结构。Protocol +buffers +是语言无关,平台无关并具有可扩展机制来序列化结构化的数据的技术。数据结构,消息和服务是使用 +`proto3 +language `__\ 注释来描述的。 + +3.1 消息 +~~~~~~~~ + +消息在节点之间通过\ ``Message``\ proto 结构封装来传递的,可以分为 4 +种类型:发现(Discovery), 交易(Transaction), +同步(Synchronization)和共识(Consensus)。每种类型在\ ``payload``\ 中定义了多种子类型。 + +:: + + message Message { + enum Type { + UNDEFINED = 0; + + DISC_HELLO = 1; + DISC_DISCONNECT = 2; + DISC_GET_PEERS = 3; + DISC_PEERS = 4; + DISC_NEWMSG = 5; + + CHAIN_STATUS = 6; + CHAIN_TRANSACTION = 7; + CHAIN_GET_TRANSACTIONS = 8; + CHAIN_QUERY = 9; + + SYNC_GET_BLOCKS = 11; + SYNC_BLOCKS = 12; + SYNC_BLOCK_ADDED = 13; + + SYNC_STATE_GET_SNAPSHOT = 14; + SYNC_STATE_SNAPSHOT = 15; + SYNC_STATE_GET_DELTAS = 16; + SYNC_STATE_DELTAS = 17; + + RESPONSE = 20; + CONSENSUS = 21; + } + Type type = 1; + bytes payload = 2; + google.protobuf.Timestamp timestamp = 3; + } + +``payload``\ 是由不同的消息类型所包含的不同的像\ ``Transaction``\ 或\ ``Response``\ 这样的对象的不透明的字节数组。例如:\ ``type``\ 为\ ``CHAIN_TRANSACTION``\ 那么\ ``payload``\ 就是一个\ ``Transaction``\ 对象。 + +3.1.1 发现消息 +~~~~~~~~~~~~~~ + +在启动时,如果\ ``CORE_PEER_DISCOVERY_ROOTNODE``\ 被指定,那么 peer +就会运行发现协议。\ ``CORE_PEER_DISCOVERY_ROOTNODE``\ 是网络(任意peer)中扮演用来发现所有 +peer 的起点角色的另一个 peer 的 IP +地址。协议序列以\ ``payload``\ 是一个包含: + +:: + + message HelloMessage { + PeerEndpoint peerEndpoint = 1; + uint64 blockNumber = 2; + } + message PeerEndpoint { + PeerID ID = 1; + string address = 2; + enum Type { + UNDEFINED = 0; + VALIDATOR = 1; + NON_VALIDATOR = 2; + } + Type type = 3; + bytes pkiID = 4; + } + + message PeerID { + string name = 1; + } + +这样的端点的\ ``HelloMessage``\ 对象的\ ``DISC_HELLO``\ 消息开始的。 + +**域的定义:** + +- ``PeerID`` 是在启动时或配置文件中定义的 peer 的任意名字 +- ``PeerEndpoint`` 描述了端点和它是验证还是非验证 peer +- ``pkiID`` 是 peer 的加密ID +- ``address`` 以\ ``ip:port``\ 这样的格式表示的 peer 的主机名或IP和端口 +- ``blockNumber`` 是 peer 的区块链的当前的高度 + +如果收到的\ ``DISC_HELLO`` 消息的块的高度比当前 peer +的块的高度高,那么它马上初始化同步协议来追上当前的网络。 + +``DISC_HELLO``\ 之后,peer +会周期性的发送\ ``DISC_GET_PEERS``\ 来发现任意想要加入网络的 +peer。收到\ ``DISC_GET_PEERS``\ 后,peer 会发送\ ``payload`` +包含\ ``PeerEndpoint``\ 的数组的\ ``DISC_PEERS``\ 作为响应。这是不会使用其它的发现消息类型。 + +3.1.2 交易消息 +~~~~~~~~~~~~~~ + +有三种不同的交易类型:部署(Deploy),调用(Invoke)和查询(Query)。部署交易向链上安装指定的链码,调用和查询交易会调用部署号的链码。另一种需要考虑的类型是创建(Create)交易,其中部署好的链码是可以在链上实例化并寻址的。这种类型在写这份文档时还没有被实现。 + +3.1.2.1 交易的数据结构 +~~~~~~~~~~~~~~~~~~~~~~ + +``CHAIN_TRANSACTION``\ 和\ ``CHAIN_QUERY``\ 类型的消息会在\ ``payload``\ 带有\ ``Transaction``\ 对象: + +:: + + message Transaction { + enum Type { + UNDEFINED = 0; + CHAINCODE_DEPLOY = 1; + CHAINCODE_INVOKE = 2; + CHAINCODE_QUERY = 3; + CHAINCODE_TERMINATE = 4; + } + Type type = 1; + string uuid = 5; + bytes chaincodeID = 2; + bytes payloadHash = 3; + + ConfidentialityLevel confidentialityLevel = 7; + bytes nonce = 8; + bytes cert = 9; + bytes signature = 10; + + bytes metadata = 4; + google.protobuf.Timestamp timestamp = 6; + } + + message TransactionPayload { + bytes payload = 1; + } + + enum ConfidentialityLevel { + PUBLIC = 0; + CONFIDENTIAL = 1; + } + +**域的定义:** - ``type`` - 交易的类型, 为1时表示: - ``UNDEFINED`` - +为未来的使用所保留. - ``CHAINCODE_DEPLOY`` - 代表部署新的链码. - +``CHAINCODE_INVOKE`` - 代表一个链码函数被执行并修改了世界状态 - +``CHAINCODE_QUERY`` - 代表一个链码函数被执行并可能只读取了世界状态 - +``CHAINCODE_TERMINATE`` - 标记的链码不可用,所以链码中的函数将不能被调用 +- ``chaincodeID`` - 链码源码,路径,构造函数和参数哈希所得到的ID - +``payloadHash`` - ``TransactionPayload.payload``\ 所定义的哈希字节. - +``metadata`` - 应用可能使用的,由自己定义的任意交易相关的元数据 - +``uuid`` - 交易的唯一ID - ``timestamp`` - peer 收到交易时的时间戳 - +``confidentialityLevel`` - +数据保密的级别。当前有两个级别。未来可能会有多个级别。 - ``nonce`` - +为安全而使用 - ``cert`` - 交易者的证书 - ``signature`` - 交易者的签名 - +``TransactionPayload.payload`` - +交易的payload所定义的字节。由于payload可以很大,所以交易消息只包含payload的哈希 + +交易安全的详细信息可以在第四节找到 + +3.1.2.2 交易规范 +~~~~~~~~~~~~~~~~ + +一个交易通常会关联链码定义及其执行环境(像语言和安全上下文)的链码规范。现在,有一个使用Go语言来编写链码的实现。将来可能会添加新的语言。 + +:: + + message ChaincodeSpec { + enum Type { + UNDEFINED = 0; + GOLANG = 1; + NODE = 2; + } + Type type = 1; + ChaincodeID chaincodeID = 2; + ChaincodeInput ctorMsg = 3; + int32 timeout = 4; + string secureContext = 5; + ConfidentialityLevel confidentialityLevel = 6; + bytes metadata = 7; + } + + message ChaincodeID { + string path = 1; + string name = 2; + } + + message ChaincodeInput { + string function = 1; + repeated string args = 2; + } + +**域的定义:** - ``chaincodeID`` - 链码源码的路径和名字 - ``ctorMsg`` - +调用的函数名及参数 - ``timeout`` - 执行交易所需的时间(以毫秒表示) - +``confidentialityLevel`` - 这个交易的保密级别 - ``secureContext`` - +交易者的安全上下文 - ``metadata`` - 应用想要传递下去的任何数据 + +当 peer 收到\ ``chaincodeSpec``\ 后以合适的交易消息包装它并广播到网络 + +3.1.2.3 部署交易 +~~~~~~~~~~~~~~~~ + +部署交易的类型是\ ``CHAINCODE_DEPLOY``\ ,且它的payload包含\ ``ChaincodeDeploymentSpec``\ 对象。 + +:: + + message ChaincodeDeploymentSpec { + ChaincodeSpec chaincodeSpec = 1; + google.protobuf.Timestamp effectiveDate = 2; + bytes codePackage = 3; + } + +**域的定义:** - ``chaincodeSpec`` - 参看上面的3.1.2.2节. - +``effectiveDate`` - 链码准备好可被调用的时间 - ``codePackage`` - +链码源码的gzip + +当验证 peer +部署链码时,它通常会校验\ ``codePackage``\ 的哈希来保证交易被部署到网络后没有被篡改。 + +3.1.2.4 调用交易 +~~~~~~~~~~~~~~~~ + +调用交易的类型是\ ``CHAINCODE_DEPLOY``\ ,且它的payload包含\ ``ChaincodeInvocationSpec``\ 对象。 + +:: + + message ChaincodeInvocationSpec { + ChaincodeSpec chaincodeSpec = 1; + } + +3.1.2.5 查询交易 +~~~~~~~~~~~~~~~~ + +查询交易除了消息类型是\ ``CHAINCODE_QUERY``\ 其它和调用交易一样 + +3.1.3 同步消息 +~~~~~~~~~~~~~~ + +同步协议以3.1.1节描述的,当 peer 知道它自己的区块落后于其它 peer +或和它们不一样后所发起的。peer +广播\ ``SYNC_GET_BLOCKS``\ ,\ ``SYNC_STATE_GET_SNAPSHOT``\ 或\ ``SYNC_STATE_GET_DELTAS``\ 并分别接收\ ``SYNC_BLOCKS``, +``SYNC_STATE_SNAPSHOT``\ 或 ``SYNC_STATE_DELTAS``\ 。 + +安装的共识插件(如:pbft)决定同步协议是如何被应用的。每个消息是针对具体的状态来设计的: + +**SYNC\_GET\_BLOCKS** +是一个\ ``SyncBlockRange``\ 对象,包含一个连续区块的范围的\ ``payload``\ 的请求。 + +:: + + message SyncBlockRange { + uint64 correlationId = 1; + uint64 start = 2; + uint64 end = 3; + } + +接收peer使用包含 +``SyncBlocks``\ 对象的\ ``payload``\ 的\ ``SYNC_BLOCKS``\ 信息来响应 + +:: + + message SyncBlocks { + SyncBlockRange range = 1; + repeated Block blocks = 2; + } + +``start``\ 和\ ``end``\ 标识包含的区块的开始和结束,返回区块的顺序由\ ``start``\ 和\ ``end``\ 的值定义。如:当\ ``start``\ =3,\ ``end``\ =5时区块的顺序将会是3,4,5。当\ ``start``\ =5,\ ``end``\ =3时区块的顺序将会是5,4,3。 + +**SYNC\_STATE\_GET\_SNAPSHOT** 请求当前世界状态的快照。 +``payload``\ 是一个\ ``SyncStateSnapshotRequest``\ 对象 + +:: + + message SyncStateSnapshotRequest { + uint64 correlationId = 1; + } + +``correlationId``\ 是请求 peer 用来追踪响应消息的。接受 peer +回复\ ``payload``\ 为\ ``SyncStateSnapshot``\ 实例的\ ``SYNC_STATE_SNAPSHOT``\ 信息 + +:: + + message SyncStateSnapshot { + bytes delta = 1; + uint64 sequence = 2; + uint64 blockNumber = 3; + SyncStateSnapshotRequest request = 4; + } + +这条消息包含快照或以0开始的快照流序列中的一块。终止消息是len(delta) == +0的块 + +**SYNC\_STATE\_GET\_DELTAS** +请求连续区块的状态变化。默认情况下总账维护500笔交易变化。 +delta(j)是block(i)和block(j)之间的状态转变,其中i=j-1。 +``payload``\ 包含\ ``SyncStateDeltasRequest``\ 实例 + +:: + + message SyncStateDeltasRequest { + SyncBlockRange range = 1; + } + +接收 peer 使用包含 +``SyncStateDeltas``\ 实例的\ ``payload``\ 的\ ``SYNC_STATE_DELTAS``\ 信息来响应 + +:: + + message SyncStateDeltas { + SyncBlockRange range = 1; + repeated bytes deltas = 2; + } + +delta可能以顺序(从i到j)或倒序(从j到i)来表示状态转变 + +3.1.4 共识消息 +~~~~~~~~~~~~~~ + +共识处理交易,一个\ ``CONSENSUS``\ 消息是由共识框架接收到\ ``CHAIN_TRANSACTION``\ 消息时在内部初始化的。框架把\ ``CHAIN_TRANSACTION``\ 转换为 +``CONSENSUS``\ 然后以相同的\ ``payload``\ 广播到验证 +peer。共识插件接收这条消息并根据内部算法来处理。插件可能创建自定义的子类型来管理共识有穷状态机。3.4节会介绍详细信息。 + +3.2 总账 +~~~~~~~~ + +总账由两个主要的部分组成,一个是区块链,一个是世界状态。区块链是在总账中的一系列连接好的用来记录交易的区块。世界状态是一个用来存储交易执行状态的键-值(key-value)数据库 + +3.2.1 区块链 +~~~~~~~~~~~~ + +3.2.1.1 区块 +^^^^^^^^^^^^ + +区块链是由一个区块链表定义的,每个区块包含它在链中前一个区块的哈希。区块包含的另外两个重要信息是它包含区块执行所有交易后的交易列表和世界状态的哈希 + +:: + + message Block { + version = 1; + google.protobuf.Timestamp timestamp = 2; + bytes transactionsHash = 3; + bytes stateHash = 4; + bytes previousBlockHash = 5; + bytes consensusMetadata = 6; + NonHashData nonHashData = 7; + } + + message BlockTransactions { + repeated Transaction transactions = 1; + } + +**域的定义:** \* ``version`` - 用来追踪协议变化的版本号 \* ``timestamp`` +- 由区块提议者填充的时间戳 \* ``transactionsHash`` - 区块中交易的merkle +root hash \* ``stateHash`` - 世界状态的merkle root hash \* +``previousBlockHash`` - 前一个区块的hash \* ``consensusMetadata`` - +共识可能会引入的一些可选的元数据 \* ``nonHashData`` - +``NonHashData``\ 消息会在计算区块的哈希前设置为nil,但是在数据库中存储为区块的一部分 +\* ``BlockTransactions.transactions`` - +交易消息的数组,由于交易的大小,它们不会被直接包含在区块中 + +3.2.1.2 区块哈希 +^^^^^^^^^^^^^^^^ + +- ``previousBlockHash``\ 哈希是通过下面算法计算的 + +1. 使用protocol buffer库把区块消息序列化为字节码 + +2. 使用\ `FIPS + 202 `__\ 描述的SHA3 + SHAKE256算法来对序列化后的区块消息计算大小为512位的哈希值 + +- ``transactionHash``\ 是交易merkle树的根。定义merkle + tree实现是一个代办 + +- ``stateHash``\ 在3.2.2.1节中定义. + +3.2.1.3 非散列数据(NonHashData) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +NonHashData消息是用来存储不需要所有 peer +都具有相同值的块元数据。他们是建议值。 + +:: + + message NonHashData { + google.protobuf.Timestamp localLedgerCommitTimestamp = 1; + repeated TransactionResult transactionResults = 2; + } + + message TransactionResult { + string uuid = 1; + bytes result = 2; + uint32 errorCode = 3; + string error = 4; + } + +- ``localLedgerCommitTimestamp`` - 标识区块提交到本地总账的时间戳 + +- ``TransactionResult`` - 交易结果的数组 + +- ``TransactionResult.uuid`` - 交易的ID + +- ``TransactionResult.result`` - 交易的返回值 + +- ``TransactionResult.errorCode`` - + 可以用来记录关联交易的错误信息的代码 + +- ``TransactionResult.error`` - 用来记录关联交易的错误信息的字符串 + +3.2.1.4 交易执行 +^^^^^^^^^^^^^^^^ + +一个交易定义了它们部署或执行的链码。区块中的所有交易都可以在记录到总账中的区块之前运行。当链码执行时,他们可能会改变世界状态。之后世界状态的哈希会被记录在区块中。 + +3.2.2 世界状态 +~~~~~~~~~~~~~~ + +peer +的\ *世界状态*\ 涉及到所有被部署的链码的\ *状态*\ 集合。进一步说,链码的状态由键值对集合来表示。所以,逻辑上说,peer +的世界状态也是键值对的集合,其中键由元组\ ``{chaincodeID, ckey}``\ 组成。这里我们使用术语\ ``key``\ 来标识世界状态的键,如:元组\ ``{chaincodeID, ckey}`` +,而且我们使用\ ``cKey``\ 来标识链码中的唯一键。 + +为了下面描述的目的,假定\ ``chaincodeID``\ 是有效的utf8字符串,且\ ``ckey``\ 和\ ``value``\ 是一个或多个任意的字节的序列 + +3.2.2.1 世界状态的哈希 +^^^^^^^^^^^^^^^^^^^^^^ + +当网络活动时,很多像交易提交和同步 peer 这样的场合可能需要计算 peer +观察到的世界状态的加密-哈希。例如,共识协议可能需要保证网络中\ *最小*\ 数量的 +peer 观察到同样的世界状态。 + +因为计算世界状态的加密-哈希是一个非常昂贵的操作,组织世界状态来使得当它改变时能高效的计算加密-哈希是非常可取的。将来,可以根据不同的负载条件来设计不同的组织形式。 + +由于fabric是被期望在不同的负载条件下都能正常工作,所以需要一个可拔插的机制来支持世界状态的组织。 + +3.2.2.1.1 Bucket-tree +^^^^^^^^^^^^^^^^^^^^^ + +*Bucket-tree* +是世界状态的组织方式的实现。为了下面描述的目的,世界状态的键被表示成两个组件(\ ``chaincodeID`` +and ``ckey``) 的通过nil字节的级联,如:\ ``key`` = +``chaincodeID``\ +\ ``nil``\ +\ ``cKey``\ 。 + +这个方法的模型是一个\ *merkle-tree*\ 在\ *hash +table*\ 桶的顶部来计算\ *世界状态*\ 的加密-哈希 + +这个方法的核心是世界状态的\ *key-values*\ 被假定存储在由预先决定的桶的数量(\ ``numBuckets``)所组成的哈希表中。一个哈希函数(\ ``hashFunction``) +被用来确定包含给定键的桶数量。注意\ ``hashFunction``\ 不代表SHA3这样的加密-哈希方法,而是决定给定的键的桶的数量的正规的编程语言散列函数。 + +为了对 +merkle-tree建模,有序桶扮演了树上的叶子节点-编号最低的桶是树中的最左边的叶子节点。为了构造树的最后第二层,叶子节点的预定义数量 +(``maxGroupingAtEachLevel``),从左边开始把每个这样的分组组合在一起,一个节点被当作组中所有叶子节点的共同父节点来插入到最后第二层中。注意最后的父节点的数量可能会少于\ ``maxGroupingAtEachLevel``\ 这个构造方式继续使用在更高的层级上直到树的根节点被构造。 + +下面这个表展示的在\ ``{numBuckets=10009 and maxGroupingAtEachLevel=10}``\ 的配置下会得到的树在不同层级上的节点数。 + ++---------+-------------------+ +| Level | Number of nodes | ++=========+===================+ +| 0 | 1 | ++---------+-------------------+ +| 1 | 2 | ++---------+-------------------+ +| 2 | 11 | ++---------+-------------------+ +| 3 | 101 | ++---------+-------------------+ +| 4 | 1001 | ++---------+-------------------+ +| 5 | 10009 | ++---------+-------------------+ + +为了计算世界状态的加密-哈希,需要计算每个桶的加密-哈希,并假设它们是merkle-tree的叶子节点的加密-哈希。为了计算桶的加密-哈希,存储在桶中的键值对首先被序列化为字节码并在其上应用加密-哈希函数。为了序列化桶的键值对,所有具有公共chaincodeID前缀的键值对分别序列化并以chaincodeID的升序的方式追加在一起。为了序列化一个chaincodeID的键值对,会涉及到下面的信息: + +1. chaincodeID的长度(chaincodeID的字节数) + +- chaincodeID的utf8字节码 +- chaincodeID的键值对数量 +- 对于每个键值对(以ckey排序) + + - ckey的长度 + - ckey的字节码 + - 值的长度 + - 值的字节码 + +对于上面列表的所有数值类型项(如:chaincodeID的长度),使用protobuf的变体编码方式。上面这种编码方式的目的是为了桶中的键值对的字节表示方式不会被任意其他键值对的组合所产生,并减少了序列化字节码的总体大小。 + +例如:考虑具有\ ``chaincodeID1_key1:value1, chaincodeID1_key2:value2, 和 chaincodeID2_key1:value1``\ 这样名字的键值对的桶。序列化后的桶看上去会像:\ ``12 + chaincodeID1 + 2 + 4 + key1 + 6 + value1 + 4 + key2 + 6 + value2 + 12 + chaincodeID2 + 1 + 4 + key1 + 6 + value1`` + +如果桶中没有键值对,那么加密-哈希为\ ``nil``\ 。 + +中间节点和根节点的加密-哈希与标准merkle-tree的计算方法一样,即:应用加密-哈希函数到所有子节点的加密-哈希从左到右级联后得到的字节码。进一步说,如果一个子节点的加密-哈希为\ ``nil``\ ,那么这个子节点的加密-哈希在级联子节点的加密-哈希是就被省略。如果它只有一个子节点,那么它的加密-哈希就是子节点的加密-哈希。最后,根节点的加密-哈希就是世界状态的加密-哈希。 + +上面这种方法在状态中少数键值对改变时计算加密-哈希是有性能优势的。主要的优势包括: +- 那些没有变化的桶的计算会被跳过 - +merkle-tree的宽度和深度可以通过配置\ ``numBuckets``\ 和\ ``maxGroupingAtEachLevel``\ 参数来控制。树的不同深度和宽度对性能和不同的资源都会产生不同的影响。 + +在一个具体的部署中,所有的 peer +都期望使用相同的\ ``numBuckets, maxGroupingAtEachLevel, 和 hashFunction``\ 的配置。进一步说,如果任何一个配置在之后的阶段被改变,那么这些改变需要应用到所有的 +peer 中,来保证 peer +节点之间的加密-哈希的比较是有意义的。即使,这可能会导致基于实现的已有数据的迁移。例如:一种实现希望存储树中所有节点最后计算的加密-哈希,那么它就需要被重新计算。 + +3.3 链码(Chaincode) +~~~~~~~~~~~~~~~~~~~~~ + +链码是在交易(参看3.1.2节)被部署时分发到网络上,并被所有验证 peer +通过隔离的沙箱来管理的应用级代码。尽管任意的虚拟技术都可以支持沙箱,现在是通过Docker容器来运行链码的。这节中描述的协议可以启用不同虚拟实现的插入与运行。 + +3.3.1 虚拟机实例化 +~~~~~~~~~~~~~~~~~~ + +一个实现VM接口的虚拟机 + +:: + + type VM interface { + build(ctxt context.Context, id string, args []string, env []string, attachstdin bool, attachstdout bool, reader io.Reader) error + start(ctxt context.Context, id string, args []string, env []string, attachstdin bool, attachstdout bool) error + stop(ctxt context.Context, id string, timeout uint, dontkill bool, dontremove bool) error + } + +fabric在处理链码上的部署交易或其他交易时,如果这个链码的VM未启动(崩溃或之前的不活动导致的关闭)时实例化VM。每个链码镜像通过\ ``build``\ 函数构建,通过\ ``start``\ 函数启动,并使用\ ``stop``\ 函数停止。 + +一旦链码容器被启动,它使用gRPC来连接到启动这个链码的验证 +peer,并为链码上的调用和查询交易建立通道。 + +3.3.2 链码协议 +~~~~~~~~~~~~~~ + +验证 peer +和它的链码之间是通过gRPC流来通信的。链码容器上有shim层来处理链码与验证 +peer 之间的protobuf消息协议。 + +:: + + message ChaincodeMessage { + + enum Type { + UNDEFINED = 0; + REGISTER = 1; + REGISTERED = 2; + INIT = 3; + READY = 4; + TRANSACTION = 5; + COMPLETED = 6; + ERROR = 7; + GET_STATE = 8; + PUT_STATE = 9; + DEL_STATE = 10; + INVOKE_CHAINCODE = 11; + INVOKE_QUERY = 12; + RESPONSE = 13; + QUERY = 14; + QUERY_COMPLETED = 15; + QUERY_ERROR = 16; + GET_STATE_BY_RANGE = 17; + } + + Type type = 1; + google.protobuf.Timestamp timestamp = 2; + bytes payload = 3; + string uuid = 4; + } + +**域的定义:** - ``Type`` 是消息的类型 - ``payload`` 是消息的payload. +每个payload取决于\ ``Type``. - ``uuid`` 消息唯一的ID + +消息的类型在下面的小节中描述 + +链码实现被验证 peer +在处理部署,调用或查询交易时调用的\ ``Chaincode``\ 接口 + +:: + + type Chaincode interface { + Init(stub *ChaincodeStub, function string, args []string) ([]byte, error) + Invoke(stub *ChaincodeStub, function string, args []string) (error) + Query(stub *ChaincodeStub, function string, args []string) ([]byte, error) + } + +``Init``, ``Invoke`` 和 ``Query``\ 函数使用\ ``function`` and +``args``\ 参数来支持多种交易。\ ``Init``\ 是构造函数,它只在部署交易时被执行。\ ``Query``\ 函数是不允许修改链码的状态的;它只能读取和计算并以byte数组的形式返回。 + +3.3.2.1 链码部署 +~~~~~~~~~~~~~~~~ + +当部署时(链码容器已经启动),shim层发送一次性的具有包含\ ``ChaincodeID``\ 的\ ``payload``\ 的\ ``REGISTER``\ 消息给验证 +peer。然后 peer +以\ ``REGISTERED``\ 或\ ``ERROR``\ 来响应成功或失败。当收到\ ``ERROR``\ 后shim关闭连接并退出。 + +注册之后,验证 peer +发送具有包含\ ``ChaincodeInput``\ 对象的\ ``INIT``\ 消息。shim使用从\ ``ChaincodeInput``\ 获得的参数来调用\ ``Init``\ 函数,通过像设置持久化状态这样操作来初始化链码。 + +shim根据\ ``Init``\ 函数的返回值,响应\ ``RESPONSE``\ 或\ ``ERROR``\ 消息。如果没有错误,那么链码初始化完成,并准备好接收调用和查询交易。 + +3.3.2.2 链码调用 +~~~~~~~~~~~~~~~~ + +当处理调用交易时,验证 peer +发送\ ``TRANSACTION``\ 消息给链码容器的shim,由它来调用链码的\ ``Invoke``\ 函数,并传递从\ ``ChaincodeInput``\ 得到的参数。shim响应\ ``RESPONSE``\ 或\ ``ERROR``\ 消息来表示函数完成。如果接收到\ ``ERROR``\ 函数,\ ``payload``\ 包含链码所产生的错误信息。 + +3.3.2.3 链码查询 +~~~~~~~~~~~~~~~~ + +与调用交易一样,验证 peer +发送\ ``QUERY``\ 消息给链码容器的shim,由它来调用链码的\ ``Query``\ 函数,并传递从\ ``ChaincodeInput``\ 得到的参数。\ ``Query``\ 函数可能会返回状态值或错误,它会把它通过\ ``RESPONSE``\ 或\ ``ERROR``\ 消息来传递给验证 +peer。 + +3.3.2.4 链码状态 +~~~~~~~~~~~~~~~~ + +每个链码可能都定义了它自己的持久化状态变量。例如,一个链码可能创建电视,汽车或股票这样的资产来保存资产属性。当\ ``Invoke``\ 函数处理时,链码可能会更新状态变量,例如改变资产所有者。链码会根据下面这些消息类型类操作状态变量: + +PUT\_STATE +^^^^^^^^^^ + +链码发送一个\ ``payload``\ 包含\ ``PutStateInfo``\ 对象的\ ``PU_STATE``\ 消息来保存键值对。 + +:: + + message PutStateInfo { + string key = 1; + bytes value = 2; + } + +GET\_STATE +^^^^^^^^^^ + +链码发送一个由\ ``payload``\ 指定要获取值的键的\ ``GET_STATE``\ 消息。 + +DEL\_STATE +^^^^^^^^^^ + +链码发送一个由\ ``payload``\ 指定要删除值的键的\ ``DEL_STATE``\ 消息。 + +GET\_STATE\_BY\_RANGE +^^^^^^^^^^^^^^^^^^^^^ + +链码发送一个\ ``payload``\ 包含\ ``GET_STATE_BY_RANGE``\ 对象的\ ``GET_STATE_BY_RANGE``\ 来获取一个范围内的值。 + +:: + + message GetStateByRange { + string startKey = 1; + string endKey = 2; + } + +``startKey``\ 和\ ``endKey``\ 假设是通过字典排序的. 验证 peer +响应一个\ ``payload``\ 是\ ``GetStateByRangeResponse``\ 对象的\ ``RESPONSE``\ 消息 + +:: + + message GetStateByRangeResponse { + repeated GetStateByRangeKeyValue keysAndValues = 1; + bool hasMore = 2; + string ID = 3; + } + message GetStateByRangeKeyValue { + string key = 1; + bytes value = 2; + } + +如果相应中\ ``hasMore=true``\ ,这表示有在请求的返回中还有另外的键。链码可以通过发送包含与响应中ID相同的ID的\ ``GetStateByRangeNext``\ 消息来获取下一集合。 + +:: + + message GetStateByRangeNext { + string ID = 1; + } + +当链码结束读取范围,它会发送带有ID的\ ``GetStateByRangeClose``\ 消息来期望它关闭。 + +:: + + message GetStateByRangeClose { + string ID = 1; + } + +INVOKE\_CHAINCODE +^^^^^^^^^^^^^^^^^ + +链码可以通过发送\ ``payload``\ 包含 +``ChaincodeSpec``\ 对象的\ ``INVOKE_CHAINCODE``\ 消息给验证 peer +来在相同的交易上下文中调用另一个链码 + +QUERY\_CHAINCODE +^^^^^^^^^^^^^^^^ + +链码可以通过发送\ ``payload``\ 包含 +``ChaincodeSpec``\ 对象的\ ``QUERY_CHAINCODE``\ 消息给验证 peer +来在相同的交易上下文中查询另一个链码 + +3.4 插拔式共识框架 +~~~~~~~~~~~~~~~~~~ + +共识框架定义了每个共识插件都需要实现的接口: + +- ``consensus.Consenter``: 允许共识插件从网络上接收消息的接口 +- ``consensus.CPI``: 共识编程接口\_Consensus Programming Interface\_ + (``CPI``) 是共识插件用来与栈交互的,这个接口可以分为两部分: + + - ``consensus.Communicator``: 用来发送(广播或单播)消息到其他的验证 + peer + - ``consensus.LedgerStack``: 这个接口使得执行框架像总账一样方便 + +就像下面描述的细节一样,\ ``consensus.LedgerStack``\ 封装了其他接口,\ ``consensus.Executor``\ 接口是共识框架的核心部分。换句话说,\ ``consensus.Executor``\ 接口允许一个(批量)交易启动,执行,根据需要回滚,预览和提交。每一个共识插件都需要满足以所有验证 +peer +上全序的方式把批量(块)交易(通过\ ``consensus.Executor.CommitTxBatch``\ )被提交到总账中(参看下面的\ ``consensus.Executor``\ 接口获得详细细节)。 + +当前,共识框架由\ ``consensus``, +``controller``\ 和\ ``helper``\ 这三个包组成。使用\ ``controller``\ 和\ ``helper``\ 包的主要原因是防止Go语言的“循环引入”和当插件更新时的最小化代码变化。 + +- ``controller`` 包规范了验证 peer 所使用的共识插件 +- ``helper`` 是围绕公式插件的垫片,它是用来与剩下的栈交互的,如为其他 + peer 维护消息。 + +这里有2个共识插件提供:\ ``pbft``\ 和\ ``noops``\ : + +- ``obcpbft``\ 包包含实现 *PBFT* [1] 和 *Sieve* + 共识协议的共识插件。参看第5节的详细介绍 +- ``noops`` 是一个为开发和测试提供的''假的''共识插件. + 它处理所有共识消息但不提供共识功能,它也是一个好的学习如何开发一个共识插件的简单例子。 + +3.4.1 ``Consenter`` 接口 +~~~~~~~~~~~~~~~~~~~~~~~~ + +定义: + +:: + + type Consenter interface { + RecvMsg(msg *pb.Message) error + } + +``Consenter``\ 接口是插件对(外部的)客户端请求的入口,当处理共识时,共识消息在内部(如从共识模块)产生。NewConsenter\ ``创建``\ Consenter\ ``插件。``\ RecvMsg\`以到达共识的顺序来处理进来的交易。 + +阅读下面的\ ``helper.HandleMessage``\ 来理解 peer +是如何和这个接口来交互的。 + +3.4.2 ``CPI``\ 接口 +~~~~~~~~~~~~~~~~~~~ + +定义: + +:: + + type CPI interface { + Inquirer + Communicator + SecurityUtils + LedgerStack + } + +``CPI`` +允许插件和栈交互。它是由\ ``helper.Helper``\ 对象实现的。回想一下这个对象是: + +1. 在\ ``helper.NewConsensusHandler``\ 被调用时初始化的 +2. 当它们的插件构造了\ ``consensus.Consenter``\ 对象,那么它对插件的作者是可访问的 + +3.4.3 ``Inquirer``\ 接口 +~~~~~~~~~~~~~~~~~~~~~~~~ + +定义: + +:: + + type Inquirer interface { + GetNetworkInfo() (self *pb.PeerEndpoint, network []*pb.PeerEndpoint, err error) + GetNetworkHandles() (self *pb.PeerID, network []*pb.PeerID, err error) + } + +这个接口是\ ``consensus.CPI``\ 接口的一部分。它是用来获取网络中验证 peer +的(\ ``GetNetworkHandles``\ )句柄,以及那些验证 peer +的明细(\ ``GetNetworkInfo``): + +注意peers由\ ``pb.PeerID``\ 对象确定。这是一个protobuf消息,当前定义为(注意这个定义很可能会被修改): + +:: + + message PeerID { + string name = 1; + } + +3.4.4 ``Communicator``\ 接口 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +定义: + +:: + + type Communicator interface { + Broadcast(msg *pb.Message) error + Unicast(msg *pb.Message, receiverHandle *pb.PeerID) error + } + +这个接口是\ ``consensus.CPI``\ 接口的一部分。它是用来与网络上其它 peer +通信的(\ ``helper.Broadcast``, ``helper.Unicast``\ ): + +3.4.5 ``SecurityUtils``\ 接口 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +定义: + +:: + + type SecurityUtils interface { + Sign(msg []byte) ([]byte, error) + Verify(peerID *pb.PeerID, signature []byte, message []byte) error + } + +这个接口是\ ``consensus.CPI``\ 接口的一部分。它用来处理消息签名(\ ``Sign``)的加密操作和验证签名(\ ``Verify``) + +3.4.6 ``LedgerStack`` 接口 +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +定义: + +:: + + type LedgerStack interface { + Executor + Ledger + RemoteLedgers + } + +``CPI``\ 接口的主要成员,\ ``LedgerStack`` +组与fabric的其它部分与共识相互作用,如执行交易,查询和更新总账。这个接口支持对本地区块链和状体的查询,更新本地区块链和状态,查询共识网络上其它节点的区块链和状态。它是由\ ``Executor``, +``Ledger``\ 和\ ``RemoteLedgers``\ 这三个接口组成的。下面会描述它们。 + +3.4.7 ``Executor`` 接口 +~~~~~~~~~~~~~~~~~~~~~~~ + +定义: + +:: + + type Executor interface { + BeginTxBatch(id interface{}) error + ExecTXs(id interface{}, txs []*pb.Transaction) ([]byte, []error) + CommitTxBatch(id interface{}, transactions []*pb.Transaction, transactionsResults []*pb.TransactionResult, metadata []byte) error + RollbackTxBatch(id interface{}) error + PreviewCommitTxBatchBlock(id interface{}, transactions []*pb.Transaction, metadata []byte) (*pb.Block, error) + } + +executor接口是\ ``LedgerStack``\ 接口最常使用的部分,且是共识网络工作的必要部分。接口允许交易启动,执行,根据需要回滚,预览和提交。这个接口由下面这些方法组成。 + +3.4.7.1 开始批量交易 +^^^^^^^^^^^^^^^^^^^^ + +:: + + BeginTxBatch(id interface{}) error + +这个调用接受任意的,故意含糊的\ ``id``\ ,来使得共识插件可以保证与这个具体的批量相关的交易才会被执行。例如:在pbft实现中,这个\ ``id``\ 是被执行交易的编码过的哈希。 + +3.4.7.2 执行交易 +^^^^^^^^^^^^^^^^ + +:: + + ExecTXs(id interface{}, txs []*pb.Transaction) ([]byte, []error) + +这个调用根据总账当前的状态接受一组交易,并返回带有对应着交易组的错误信息组的当前状态的哈希。注意一个交易所产生的错误不影响批量交易的安全提交。当遇到失败所采用的策略取决与共识插件的实现。这个接口调用多次是安全的。 + +3.4.7.3 提交与回滚交易 +^^^^^^^^^^^^^^^^^^^^^^ + +:: + + RollbackTxBatch(id interface{}) error + +这个调用中止了批量执行。这会废弃掉对当前状态的操作,并把总账状态回归到之前的状态。批量是从\ ``BeginBatchTx``\ 开始的,如果需要开始一个新的就需要在执行任意交易之前重新创建一个。 + +:: + + PreviewCommitTxBatchBlock(id interface{}, transactions []*pb.Transaction, metadata []byte) (*pb.Block, error) + +这个调用是共识插件对非确定性交易执行的测试时最有用的方法。区块返回的哈希表部分会保证,当\ ``CommitTxBatch``\ 被立即调用时的区块是同一个。这个保证会被任意新的交易的执行所打破。 + +:: + + CommitTxBatch(id interface{}, transactions []*pb.Transaction, transactionsResults []*pb.TransactionResult, metadata []byte) error + +这个调用提交区块到区块链中。区块必须以全序提交到区块链中,\ ``CommitTxBatch``\ 结束批量交易,在执行或提交任意的交易之前必须先调用\ ``BeginTxBatch``\ 。 + +3.4.8 ``Ledger`` 接口 +~~~~~~~~~~~~~~~~~~~~~ + +定义: + +:: + + type Ledger interface { + ReadOnlyLedger + UtilLedger + WritableLedger + } + +``Ledger`` +接口是为了允许共识插件询问或可能改变区块链当前状态。它是由下面描述的三个接口组成的 + +3.4.8.1 ``ReadOnlyLedger`` 接口 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +定义: + +:: + + type ReadOnlyLedger interface { + GetBlock(id uint64) (block *pb.Block, err error) + GetCurrentStateHash() (stateHash []byte, err error) + GetBlockchainSize() (uint64, error) + } + +``ReadOnlyLedger`` +接口是为了查询总账的本地备份,而不会修改它。它是由下面这些函数组成的。 + +:: + + GetBlockchainSize() (uint64, error) + +这个函数返回区块链总账的长度。一般来说,这个函数永远不会失败,在这种不太可能发生情况下,错误被传递给调用者,由它确定是否需要恢复。具有最大区块值的区块的值为\ ``GetBlockchainSize()-1`` + +注意在区块链总账的本地副本是腐坏或不完整的情况下,这个调用会返回链中最大的区块值+1。这允许节点在旧的块是腐坏或丢失的情况下能继续操作当前状态/块。 + +:: + + GetBlock(id uint64) (block *pb.Block, err error) + +这个调用返回区块链中块的数值\ ``id``\ 。一般来说这个调用是不会失败的,除非请求的区块超出当前区块链的长度,或者底层的区块链被腐坏了。\ ``GetBlock``\ 的失败可能可以通过状态转换机制来取回它。 + +:: + + GetCurrentStateHash() (stateHash []byte, err error) + +这个调用返回总账的当前状态的哈希。一般来说,这个函数永远不会失败,在这种不太可能发生情况下,错误被传递给调用者,由它确定是否需要恢复。 + +3.4.8.2 ``UtilLedger`` 接口 +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +定义: + +:: + + type UtilLedger interface { + HashBlock(block *pb.Block) ([]byte, error) + VerifyBlockchain(start, finish uint64) (uint64, error) + } + +``UtilLedger`` +接口定义了一些由本地总账提供的有用的功能。使用mock接口来重载这些功能在测试时非常有用。这个接口由两个函数构成。 +会会 + +:: + + HashBlock(block *pb.Block) ([]byte, error) + +尽管\ ``*pb.Block``\ 定义了\ ``GetHash``\ 方法,为了mock测试,重载这个方法会非常有用。因此,建议\ ``GetHash``\ 方法不直接调用,而是通过\ ``UtilLedger.HashBlock``\ 接口来调用这个方法。一般来说,这个函数永远不会失败,但是错误还是会传递给调用者,让它决定是否使用适当的恢复。 + +:: + + VerifyBlockchain(start, finish uint64) (uint64, error) + +这个方法是用来校验区块链中的大的区域。它会从高的块\ ``start``\ 到低的块\ ``finish``\ ,返回第一个块的\ ``PreviousBlockHash``\ 与块的前一个块的哈希不相符的块编号以及错误信息。注意,它一般会标识最后一个好的块的编号,而不是第一个坏的块的编号。 + +3.4.8.3 ``WritableLedger`` 接口 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +定义: + +:: + + type WritableLedger interface { + PutBlock(blockNumber uint64, block *pb.Block) error + ApplyStateDelta(id interface{}, delta *statemgmt.StateDelta) error + CommitStateDelta(id interface{}) error + RollbackStateDelta(id interface{}) error + EmptyState() error + } + +``WritableLedger`` 接口允许调用者更新区块链。注意这\_NOT\_ +\_不是\_共识插件的通常用法。当前的状态需要通过\ ``Executor``\ 接口执行交易来修改,新的区块在交易提交时生成。相反的,这个接口主要是用来状态改变和腐化恢复。特别的,这个接口下的函数\_永远\_不能直接暴露给共识消息,这样会导致打破区块链所承诺的不可修改这一概念。这个结构包含下面这些函数。 + +- :: + + PutBlock(blockNumber uint64, block *pb.Block) error + + 这个函数根据给定的区块编号把底层区块插入到区块链中。注意这是一个不安全的接口,所以它不会有错误返回或返回。插入一个比当前区块高度更高的区块是被允许的,同样,重写一个已经提交的区块也是被允许的。记住,由于哈希技术使得创建一个链上的更早的块是不可行的,所以这并不影响链的可审计性和不可变性。任何尝试重写区块链的历史的操作都能很容易的被侦测到。这个函数一般只用于状态转移API。 + +- :: + + ApplyStateDelta(id interface{}, delta *statemgmt.StateDelta) error + + 这个函数接收状态变化,并把它应用到当前的状态。变化量的应用会使得状态向前或向后转变,这取决于状态变化量的构造,与\ ``Executor``\ 方法一样,\ ``ApplyStateDelta``\ 接受一个同样会被传递给\ ``CommitStateDelta`` + or ``RollbackStateDelta``\ 不透明的接口\ ``id`` + +- :: + + CommitStateDelta(id interface{}) error + + 这个方法提交在\ ``ApplyStateDelta``\ 中应用的状态变化。这通常是在调用者调用\ ``ApplyStateDelta``\ 后通过校验由\ ``GetCurrentStateHash()``\ 获得的状态哈希之后调用的。这个函数接受与传递给\ ``ApplyStateDelta``\ 一样的\ ``id``\ 。 + +- :: + + RollbackStateDelta(id interface{}) error + + 这个函数撤销在\ ``ApplyStateDelta``\ 中应用的状态变化量。这通常是在调用者调用\ ``ApplyStateDelta``\ 后与由\ ``GetCurrentStateHash()``\ 获得的状态哈希校验失败后调用的。这个函数接受与传递给\ ``ApplyStateDelta``\ 一样的\ ``id``\ 。 + +- :: + + EmptyState() error + + 这个函数将会删除整个当前状态,得到原始的空状态。这通常是通过变化量加载整个新的状态时调用的。这一般只对状态转移API有用。 + +3.4.9 ``RemoteLedgers`` 接口 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +定义: + +:: + + type RemoteLedgers interface { + GetRemoteBlocks(peerID uint64, start, finish uint64) (<-chan *pb.SyncBlocks, error) + GetRemoteStateSnapshot(peerID uint64) (<-chan *pb.SyncStateSnapshot, error) + GetRemoteStateDeltas(peerID uint64, start, finish uint64) (<-chan *pb.SyncStateDeltas, error) + } + +``RemoteLedgers`` +接口的存在主要是为了启用状态转移,和向其它副本询问区块链的状态。和\ ``WritableLedger``\ 接口一样,这不是给正常的操作使用,而是为追赶,错误恢复等操作而设计的。这个接口中的所有函数调用这都有责任来处理超时。这个接口包含下面这些函数: + +- :: + + GetRemoteBlocks(peerID uint64, start, finish uint64) (<-chan *pb.SyncBlocks, error) + + 这个函数尝试从由\ ``peerID``\ 指定的 peer + 中取出由\ ``start``\ 和\ ``finish``\ 标识的范围中的\ ``*pb.SyncBlocks``\ 流。一般情况下,由于区块链必须是从结束到开始这样的顺序来验证的,所以\ ``start``\ 是比\ ``finish``\ 更高的块编号。由于慢速的结构,其它请求的返回可能出现在这个通道中,所以调用者必须验证返回的是期望的块。第二次以同样的\ ``peerID``\ 来调用这个方法会导致第一次的通道关闭。 + +- :: + + GetRemoteStateSnapshot(peerID uint64) (<-chan *pb.SyncStateSnapshot, error) + + 这个函数尝试从由\ ``peerID``\ 指定的 peer + 中取出\ ``*pb.SyncStateSnapshot``\ 流。为了应用结果,首先需要通过\ ``WritableLedger``\ 的\ ``EmptyState``\ 调用来清空存在在状态,然后顺序应用包含在流中的变化量。 + +- :: + + GetRemoteStateDeltas(peerID uint64, start, finish uint64) (<-chan *pb.SyncStateDeltas, error) + + 这个函数尝试从由\ ``peerID``\ 指定的 peer + 中取出由\ ``start``\ 和\ ``finish``\ 标识的范围中的\ ``*pb.SyncStateDeltas``\ 流。由于慢速的结构,其它请求的返回可能出现在这个通道中,所以调用者必须验证返回的是期望的块变化量。第二次以同样的\ ``peerID``\ 来调用这个方法会导致第一次的通道关闭。 + +3.4.10 ``controller``\ 包 +~~~~~~~~~~~~~~~~~~~~~~~~~ + +3.4.10.1 controller.NewConsenter +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +签名: + +:: + + func NewConsenter(cpi consensus.CPI) (consenter consensus.Consenter) + +这个函数读取为\ ``peer``\ 过程指定的\ ``core.yaml``\ 配置文件中的\ ``peer.validator.consensus``\ 的值。键\ ``peer.validator.consensus``\ 的有效值指定运行\ ``noops``\ 还是\ ``pbft``\ 共识插件。(注意,它最终被改变为\ ``noops``\ 或\ ``custom``\ 。在\ ``custom``\ 情况下,验证 +peer 将会运行由\ ``consensus/config.yaml``\ 中定义的共识插件) + +插件的作者需要编辑函数体,来保证路由到它们包中正确的构造函数。例如,对于\ ``pbft`` +我们指向\ ``pbft.GetPlugin``\ 构造器。 + +这个函数是当设置返回信息处理器的\ ``consenter``\ 域时,被\ ``helper.NewConsensusHandler``\ 调用的。输入参数\ ``cpi``\ 是由\ ``helper.NewHelper``\ 构造器输出的,并实现了\ ``consensus.CPI``\ 接口 + +3.4.11 ``helper``\ 包 +~~~~~~~~~~~~~~~~~~~~~ + +3.4.11.1 高层次概述 +^^^^^^^^^^^^^^^^^^^ + +验证 peer +通过\ ``helper.NewConsesusHandler``\ 函数(一个处理器工厂),为每个连接的 +peer +建立消息处理器(\ ``helper.ConsensusHandler``)。每个进来的消息都会检查它的类型(\ ``helper.HandleMessage``);如果这是为了共识必须到达的消息,它会传递到 +peer +的共识对象(\ ``consensus.Consenter``)。其它的信息会传递到栈中的下一个信息处理器。 + +3.4.11.2 helper.ConsensusHandler +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +定义: + +:: + + type ConsensusHandler struct { + chatStream peer.ChatStream + consenter consensus.Consenter + coordinator peer.MessageHandlerCoordinator + done chan struct{} + peerHandler peer.MessageHandler + } + +共识中的上下文,我们只关注域\ ``coordinator``\ 和\ ``consenter``\ 。\ ``coordinator``\ 就像名字隐含的那样,它被用来在 +peer 的信息处理器之间做协调。例如,当 peer +希望\ ``Broadcast``\ 时,对象被访问。共识需要到达的共识者会接收到消息并处理它们。 + +注意,\ ``fabric/peer/peer.go``\ 定义了\ ``peer.MessageHandler`` +(接口),和``peer.MessageHandlerCoordinator``\ (接口)类型。 + +3.4.11.3 helper.NewConsensusHandler +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +签名: + +:: + + func NewConsensusHandler(coord peer.MessageHandlerCoordinator, stream peer.ChatStream, initiatedStream bool, next peer.MessageHandler) (peer.MessageHandler, error) + +创建一个\ ``helper.ConsensusHandler``\ 对象。为每个\ ``coordinator``\ 设置同样的消息处理器。同时把\ ``consenter``\ 设置为\ ``controller.NewConsenter(NewHelper(coord))`` + +3.4.11.4 helper.Helper +~~~~~~~~~~~~~~~~~~~~~~ + +定义: + +:: + + type Helper struct { + coordinator peer.MessageHandlerCoordinator + } + +包含验证peer的\ ``coordinator``\ 的引用。对象是否为peer实现了\ ``consensus.CPI``\ 接口。 + +3.4.11.5 helper.NewHelper +^^^^^^^^^^^^^^^^^^^^^^^^^ + +签名: + +:: + + func NewHelper(mhc peer.MessageHandlerCoordinator) consensus.CPI + +返回\ ``coordinator``\ 被设置为输入参数\ ``mhc``\ (\ ``helper.ConsensusHandler``\ 消息处理器的\ ``coordinator``\ 域)的\ ``helper.Helper``\ 对象。这个对象实现了\ ``consensus.CPI``\ 接口,从而允许插件与栈进行交互。 + +3.4.11.6 helper.HandleMessage +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +回忆一下,\ ``helper.NewConsensusHandler``\ 返回的\ ``helper.ConsesusHandler``\ 对象实现了 +``peer.MessageHandler`` 接口: + +:: + + type MessageHandler interface { + RemoteLedger + HandleMessage(msg *pb.Message) error + SendMessage(msg *pb.Message) error + To() (pb.PeerEndpoint, error) + Stop() error + } + +在共识的上下文中,我们只关心\ ``HandleMessage``\ 方法。签名: + +:: + + func (handler *ConsensusHandler) HandleMessage(msg *pb.Message) error + +这个函数检查进来的\ ``Message``\ 的\ ``Type``\ 。有四种情况: + +1. 等于\ ``pb.Message_CONSENSUS``\ :传递给处理器的\ ``consenter.RecvMsg``\ 函数。 +2. 等于\ ``pb.Message_CHAIN_TRANSACTION`` (如:一个外部部署的请求): + 一个响应请求首先被发送给用户,然后把消息传递给\ ``consenter.RecvMsg``\ 函数 +3. 等于\ ``pb.Message_CHAIN_QUERY`` (如:查询): + 传递给\ ``helper.doChainQuery``\ 方法来在本地执行 +4. 其它: 传递给栈中下一个处理器的\ ``HandleMessage``\ 方法 + +3.5 事件 +~~~~~~~~ + +事件框架提供了生产和消费预定义或自定义的事件的能力。它有3个基础组件: - +事件流 - 事件适配器 - 事件结构 + +3.5.1 事件流 +^^^^^^^^^^^^ + +事件流是用来发送和接收事件的gRPC通道。每个消费者会与事件框架建立事件流,并快速传递它感兴趣的事件。事件生成者通过事件流只发送合适的事件给连接到生产者的消费者。 + +事件流初始化缓冲和超时参数。缓冲保存着几个等待投递的事件,超时参数在缓冲满时有三个选项: + +- 如果超时小于0,丢弃新到来的事件 +- 如果超时等于0,阻塞事件知道缓冲再次可用 +- 如果超时大于0,等待指定的超时时间,如果缓冲还是满的话就丢弃事件 + +3.5.1.1 事件生产者 +^^^^^^^^^^^^^^^^^^ + +事件生产者暴露函数\ ``Send(e *pb.Event)``\ 来发送事件,其中\ ``Event``\ 可以是预定义的\ ``Block``\ 或\ ``Generic``\ 事件。将来会定义更多的事件来包括其它的fabric元素。 + +:: + + message Generic { + string eventType = 1; + bytes payload = 2; + } + +``eventType``\ 和\ ``payload``\ 是由事件生产者任意定义的。例如,JSON数据可能被用在\ ``payload``\ 中。链码或插件发出\ ``Generic``\ 事件来与消费者通讯。 + +3.5.1.2 事件消费者 +^^^^^^^^^^^^^^^^^^ + +事件消费者允许外部应用监听事件。每个事件消费者通过时间流注册事件适配器。消费者框架可以看成是事件流与适配器之间的桥梁。一种典型的事件消费者使用方式: + +:: + + adapter = + consumerClient = NewEventsClient(, adapter) + consumerClient.Start() + ... + ... + consumerClient.Stop() + +3.5.2 事件适配器 +^^^^^^^^^^^^^^^^ + +事件适配器封装了三种流交互的切面: - 返回所有感兴趣的事件列表的接口 - +当事件消费者框架接受到事件后调用的接口 - +当事件总线终止时,事件消费者框架会调用的接口 + +引用的实现提供了Golang指定语言绑定 + +:: + + EventAdapter interface { + GetInterestedEvents() ([]*ehpb.Interest, error) + Recv(msg *ehpb.Event) (bool,error) + Disconnected(err error) + } + +把gRPC当成事件总线协议来使用,允许事件消费者框架对于不同的语言的绑定可移植而不影响事件生成者框架。 + +3.5.3 事件框架 +^^^^^^^^^^^^^^ + +这节详细描述了事件系统的消息结构。为了简单起见,消息直接使用Golang描述。 + +事件消费者和生产者之间通信的核心消息是事件。 + +:: + + message Event { + oneof Event { + //consumer events + Register register = 1; + + //producer events + Block block = 2; + Generic generic = 3; + } + } + +每一个上面的定义必须是\ ``Register``, +``Block``\ 或\ ``Generic``\ 中的一种。 + +就像之前提到过的一样,消费者通过与生产者建立连接来创建事件总线,并发送\ ``Register``\ 事件。\ ``Register``\ 事件实质上是一组声明消费者感兴趣的事件的\ ``Interest``\ 消息。 + +:: + + message Interest { + enum ResponseType { + //don't send events (used to cancel interest) + DONTSEND = 0; + //send protobuf objects + PROTOBUF = 1; + //marshall into JSON structure + JSON = 2; + } + string eventType = 1; + ResponseType responseType = 2; + } + +事件可以通过protobuf结构直接发送,也可以通过指定适当的\ ``responseType``\ 来发送JSON结构。 + +当前,生产者框架可以生成\ ``Block``\ 和\ ``Generic``\ 事件。\ ``Block``\ 是用来封装区块链中区块属性的消息。 + +4. 安全 +------- + +这一节将讨论下面的图所展示的设置描述。特别的,系统是由下面这些实体构成的:成员管理基础架构,如从一个实体集合中区分出不同用户身份的职责(使用系统中任意形式的标识,如:信用卡,身份证),为这个用户注册开户,并生成必要的证书以便通过fabric成功的创建交易,部署或调用链码。 + +.. figure:: ./images/sec-sec-arch.png + :alt: figure-architecture + + figure-architecture + +- Peers,它们被分为验证 peer 和非验证 peer。验证 + peer(也被称为验证器)是为了规范并处理(有效性检查,执行并添加到区块链中)用户消息(交易)提交到网络上。非验证 + peer(也被称为 + peer)代表用户接受用户交易,并通过一些基本的有效性检查,然后把交易发送到它们附近的验证 + peer。peer + 维护一个最新的区块链副本,只是为了做验证,而不会执行交易(处理过程也被称为\ *交易验证*)。 +- 注册到我们的成员服务管理系统的终端用户是在获取被系统认定的\ *身份*\ 的所有权之后,并将获取到的证书安装到客户端软件后,提交交易到系统。 +- 客户端软件,为了之后能完成注册到我们成员服务和提交交易到系统所需要安装在客户端的软件。 +- 在线钱包,用户信任的用来维护他们证书的实体,并独自根据用户的请求向网络提交交易。在线钱包配置在他们自己的客户端软件中。这个软件通常是轻量级的,它只需有对自己和自己的钱包的请求做授权。也有 + peer + 为一些用户扮演\ *在线钱包*\ 的角色,在接下来的会话中,对在线钱包做了详细区分。 + +希望使用fabric的用户,通过提供之前所讨论的身份所有权,在成员管理系统中开立一个账户,新的链码被链码创建者(开发)以开发者的形式通过客户端软件部署交易的手段,公布到区块链网络中。这样的交易是第一次被 +peer +或验证器接收到,并流传到整个验证器网络中,这个交易被区块链网络执行并找到自己的位置。用户同样可以通过调用交易调用一个已经部署了的链码 + +下一节提供了由商业目标所驱动的安全性需求的摘要。然后我们游览一下安全组件和它们的操作,以及如何设计来满足安全需求。 + +4.1 商业安全需求 +~~~~~~~~~~~~~~~~ + +这一节表述与fabric相关的商业安全需求。 + +**身份和角色管理相结合** + +为了充分的支持实际业务的需求,有必要超越确保加密连续性来进行演进。一个可工作的B2B系统必须致力于证明/展示身份或其他属性来开展业务。商业交易和金融机构的消费交互需要明确的映射到账户的所有者。商务合同通常需要与特定的机构和/或拥有交易的其他特定性质的各方保证有从属关系。问责制和不可陷害性是身份管理作为此类系统关键组成部分的两个原因。 + +问责制意味着系统的用户,个人或公司,谁的胡作非为都可以追溯到并为自己的行为负责。在很多情况下,B2B系统需要它们的会员使用他们的身份(在某些形式)加入到系统中,以确保问责制的实行。问责制和不可陷害性都是B2B系统的核心安全需求,并且他们非常相关。B2B系统需要保证系统的诚实用户不会因为其他用户的交易而被指控。 + +此外,一个B2B系统需要具有可再生性和灵活性,以满足参与者角色和/或从属关系的改变。 + +**交易隐私.** + +B2B系统对交易的隐私有着强烈的需求,如:允许系统的终端用户控制他与环境交互和共享的信息。例如:一家企业在交易型B2B系统上开展业务,要求它的交易得其他企业不可见,而他的行业合作伙伴无权分享机密信息。 + +在fabric中交易隐私是通过下面非授权用户的两个属性来实现的: + +- 交易匿名,交易的所有者隐藏在一个被称为\ *匿名集*\ 的组建中,在fabric中,它是用户的一个集合。 + +- 交易不可关联,同一用户的两个或多个交易不能被关联起来。 + +根据上下文,非授权用户可以是系统以外的任何人,或用户的子集。 + +交易隐私与B2B系统的两个或多个成员之间的保密协议的内容强烈相关。任何授权机制的匿名性和不可关联性需要在交易时考虑。 + +**通过身份管理协调交易隐私.** + +就像文档之后描述的那样,这里所采用的方法用来协调身份管理与用户隐私,并使有竞争力的机构可以像下面一样在公共的区块链(用于内部和机构间交易)上快速的交易: + +1. 为交易添加证书来实现“有权限的”区块链 + +2. 使用两层系统: + +3. 向登记的证颁发机构(CA)注册来获得(相对的) 静态登记证书 (ECerts) + +4. 通过交易CA获取能如实但伪匿名的代表登记用户的交易证书(TCerts). + +5. 提供对系统中未授权会员隐藏交易内用的机制 + +**审计支持.** + +商业系统偶尔会受到审核。在这种情况下,将给予审计员检查某些交易,某组交易,系统中某些特定用户或系统自己的一些操作的手段。因此,任意与商业伙伴通过合同协议进行交易的系统都应该提供这样的能力。 + +4.2 使用成员管理的用户隐私 +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +成员管理服务是由网络上管理用户身份和隐私的几个基础架构来组成的。这些服务验证用户的身份,在系统中注册用户,并为他/她提供所有作为可用、兼容的参数者来创建和/或调用交易所需要的证书。公开密钥体系(Public +Key Infrastructure +,PKI)是一个基于不仅对公共网络上交换的数据的加密而且能确认对方身份的公共密钥加密的。PKI管理密钥和数字证书的生成,发布和废止。数字证书是用来建立用户证书,并对消息签名的。使用证书签名的消息保证信息不被篡改。典型的PKI有一个证书颁发机构(CA),一个登记机构(RA),一个证书数据库,一个证书的存储。RA是对用户进行身份验证,校验数据的合法性,提交凭据或其他证据来支持用户请求一个或多个人反映用户身份或其他属性的可信任机构。CA根据RA的建议为特定的用户发放根CA能直接或分级的认证的数字证书。另外,RA的面向用户的通信和尽职调查的责任可以看作CA的一部分。成员服务由下图展示的实体组成。整套PKI体系的引入加强了B2B系统的强度(如:超过比特币)。 + +.. figure:: ./images/sec-memserv-components.png + :alt: Figure 1 + + Figure 1 + +*根证书颁发机构(根CA):* +它代表PKI体系中的信任锚。数字证书的验证遵循信任链。根CA是PKI层次结构中最上层的CA。 + +*登记机构(RA):* +它是一个可以确定想要加入到带权限区块链的用户的有效性和身份的可信实体。它是负责与用户外的带外通信来验证他/她的身份和作用。它是负责与用户进行频外通信来验证他/她的身份和角色。它创建登记时所需要的注册证书和根信任上的信息。 + +*注册证书颁发机构(ECA):* +负责给通过提供的注册凭证验证的用户颁发注册证书(ECerts) + +*交易认证中心(TCA):* 负责给提供了有效注册证书的用户颁发交易证书(TCerts) + +*TLS证书颁发机构(TLS-CA):* +负责签发允许用户访问其网络的TLS证书和凭证。它验证用户提供的包含该用户的特定信息的,用来签发TLS证书的,证书或证据。 + +*注册证书(ECerts)* +ECerts是长期证书。它们是颁发给所有角色的,如用户,非验证 peer,验证 +peer。在给用户颁发的情况下,谁向区块链提交候选人申请谁就拥有TCerts(在下面讨论),ECerts有两种可能的结构和使用模式: + +- Model A: ECerts + 包含所有者的身份/注册ID,并可以在交易中为TCert请求提供只用来对名义实体身份做验证。它们包含两个密钥对的公共部分:签名密钥对和加密/密钥协商密钥对。 + ECerts是每个人都可以访问。 + +- Model B: ECerts + 包含所有者的身份/注册ID,并只为TCert请求提供名义实体的身份验证。它们包含一个签名密钥对的公共部分,即,签名验证公钥的公共部分。作为依赖方,ECerts最好只由TCA和审计人员访问。他们对交易是不可见的,因此(不像TCerts)签名密钥对不在这一层级发挥不可抵赖的作用。 + +*交易证书(TCerts)* +TCerts是每个交易的短期证书。它们是由TCA根据授权的用户请求颁发的。它们安全的给一个交易授权,并可以被配置为隐藏谁参与了交易或选择性地暴露这样身份注册ID这样的信息。他们包含签名密钥对的公共部分,并可以被配置为包含一个密钥协议的密钥对的公共部分。他们仅颁发给用户。它们唯一的关联到所有者,它们可以被配置为这个关联只有TCA知道知道(和授权审核员)。TCert可以配置成不携带用户的身份信息。它们使得用户不仅以匿名方式参与到系统中,而且阻止了交易之间的关联性。 + +然而,审计能力和问责制的要求TCA能够获取给定身份的TCert,或者获取指定TCert的所有者。有关TCerts如何在部署和调用交易中使用的详细信息参见4.3节,交易安全是在基础设施层面提供的。 + +TCerts可容纳的加密或密钥协议的公共密钥(以及数字签名的验证公钥)。 +如果配备好TCert,那么就需要注册证书不能包含加密或密钥协议的公钥。 + +这样的密钥协议的公钥,Key\_Agreement\_TCertPub\_Key,可以由交易认证机构(TCA)使用与生成Signature\_Verification\_TCertPub\_Key同样的方法,使用TCertIndex ++ 1 +而不是TCertIndex来作为索引个值来生成,其中TCertIndex是由TCA为了恢复而隐藏在TCert中的。 + +交易证书(TCert)的结构如下所述: \* TCertID – +交易证书ID(为了避免通过隐藏的注册ID发生的意外可关联性,最好由TCA随机生成). +\* Hidden Enrollment ID: AES\_EncryptK(enrollmentID), 其中密钥K = +[HMAC(Pre-K, +TCertID)]256位截断其中为每个K定义三个不同的密钥分配方案:(a), (b) and +(c)。 \* Hidden Private Keys Extraction: +AES\_EncryptTCertOwner\_EncryptKey(TCertIndex \|\| +已知的填充/校验检查向量) +其中\|\|表示连接,其中各个批次具有被加到计数器的唯一(每个批次)的时间戳/随机偏移量(这个实现中初始化为1)来生成TCertIndex。该计数器可以通过每次增加2来适应TCA生成公钥,并由这两种类型的私钥的TCert所有者来恢复,如签名密钥对和密钥协商密钥对。 +\* Sign Verification Public Key – TCert签名验证的公共密钥。 \* Key +Agreement Public Key – TCert密钥协商的公钥。 \* Validity period – +该交易证书可用于交易的外/外部签名的时间窗口。 + +这里至少有三种方式来配置考虑了隐藏注册ID域密钥的分配方案: + +*(a)* Pre-K在注册期间发给用户,peer +和审计员,并对TCA和授权的审计员可用。它可能,例如由Kchain派生(会在这个规范的后面描述)或为了链码的保密性使用独立的key(s)。 + +*(b)* +Pre-K对验证器,TCA和授权的审计员可用。K是在验证器成功响应用户的查询交易(通过TLS)后可用给的。查询交易可以使用与调用交易相同的格式。对应下面的例1,如果查询用户又有部署交易的ACL中的一张TCert,那么就可以得到创建这个部署交易的用户的注册ID(enrollmentID)。对应下面的例2,如果查询所使用TCert的注册ID(enrollmentID)与部署交易中访问控制域的其中一个隶属关系/角色匹配,那么就可以得到创建这个部署交易的用户的注册ID(enrollmentID)。 + +*Example 1:* + +.. figure:: ./images/sec-example-1.png + :alt: Example 1 + + Example 1 + +*Example 2:* + +.. figure:: ./images/sec-example-2.png + :alt: Example 2 + + Example 2 + +*(c)* +Pre-K对TCA和授权的审计员可用。对于批量中的所有TCert,TCert特有的K可以和TCert一起分发给TCert的所有者(通过TLS)。这样就通过K的TCert所有者启用目标释放(TCert所有者的注册ID的可信通知)。这样的目标释放可以使用预定收件人的密钥协商公钥和/或PKchain其中SKchain就像规范的后面描述的那样对验证器可用。这样目标释放给其它合同的参与者也可以被纳入到这个交易或在频外完成。 + +如果TCert与上述的ECert模型A的结合使用,那么使用K不发送给TCert的所有者的方案(c)就足够了。 +如果TCert与上述的ECert模型A的结合使用,那么TCert中的密钥协商的公钥域可能就不需要了。 + +交易认证中心(TCA)以批量的方式返回TCert,每个批量包含不是每个TCert都有的,但是和TCert的批量一起传递到客户端的KeyDF\_Key(Key-Derivation-Function +Key) +(通用TLS)。KeyDF\_Key允许TCert的拥有者派生出真正用于从AES\_EncryptTCertOwner\_EncryptKey(TCertIndex +\|\| 已知的填充/校验检查向量)的TCertIndex恢复的TCertOwner\_EncryptKey。 + +*TLS证书(TLS-Certs)* TLS-Certs +是用于系统/组件到系统/组件间通讯所使用的证书。他们包含所有者的身份信息,使用是为了保证网络基本的安全。 + +成员管理的这个实现提供下面描述的基础功能:ECerts是没有到期/废止的;TCert的过期是由验证周期的时间窗口提供的。TCerts是没有废止的。ECA,TCA和TLS +CA证书是自签名的,其中TLS CA提供信任锚点。 + +4.2.1 用户/客户端注册过程 +^^^^^^^^^^^^^^^^^^^^^^^^^ + +下面这个图高度概括了用户注册过程,它具有离线和在线阶段。 + +.. figure:: ./images/sec-registration-high-level.png + :alt: Registration + + Registration + +*离线处理:* 在第一步中,每个用户/非验证 peer /验证 peer +有权在线下将较强的识别凭证(身份证明)到导入到注册机构(RA)。这需要在频外给RA提供为用户创建(存储)账号的证据凭证。第二步,RA返回对应的用户名/密码和信任锚点(这个实现中是TLS-CA +Cert)给用户。如果用户访问了本地客户端,那么这是客户端可以以TLS-CA证书作为信任锚点来提供安全保障的一种方法。 + +*在线阶段:* +第三步,用户连接客户端来请求注册到系统中。用户发送它的用户名和密码给客户端。客户端代表用户发送请求给PKI框架。第四步,接受包,第五步,包含其中一些对应于由客户端私有/秘密密钥的若干证书。一旦客户端验证包中所有加密材料是正确/有效的,他就把证书存储在本地并通知用户。这时候用户注册就完成了。 + +.. figure:: ./images/sec-registration-detailed.png + :alt: Figure 4 + + Figure 4 + +图4展示了注册的详细过程。PKI框架具有RA, ECA, +TCA和TLS-CA这些实体。第一步只收,RA调用“AddEntry”函数为它的数据库输入(用户名/密码)。这时候用户已正式注册到系统数据库中。客户端需要TLS-CA证书(当作信任锚点)来验证与服务器之间的TLS握手是正确的。第四步,客户端发送包含注册公钥和像用户名,密码这样的附加身份信息的注册请求到ECA(通过TLS备案层协议)。ECA验证这个用户是否真实存在于数据库。一旦它确认用户有权限提交他/她的注册公钥,那么ECA就会验证它。这个注册信息是一次性的。ECA会更新它的数据库来标识这条注册信息(用户名,密码)不能再被使用。ECA构造,签名并送回一张包含用户注册公钥的(步骤5)注册证书(ECert)。它同样会发送将来会用到(客户端需要向TCA证明他/她的ECert使用争取的ECA创建的)的ECA证书(ECA-Cert))。(尽管ECA-Cert在最初的实现中是自签名的,TCA,TLS-CA和ECA是共址)第六步,客户端验证ECert中的公钥是最初由客户端提交的(即ECA没有作弊)。它同样验证ECert中的所有期望的信息存在且形式正确。 + +同样的,在第七步,客户端发送包含它的公钥和身份的注册信息到TLS-CA。TLS-CA验证该用户在数据库中真实存在。TLS-CA生成,签名包含用户TLS公钥的一张TLS-Cert(步骤8)。TLS-CA发送TLS-Cert和它的证书(TLS-CA +Cert)。第九步类似于第六步,客户端验证TLS +Cert中的公钥是最初由客户端提交的,TLS +Cert中的信息是完整且形式正确。在第十步,客户端在本地存储中保存这两张证书的所有证书。这时候用户就注册完成了。 + +在这个版本的实现中验证器的注册过程和 peer +的是一样的。尽管,不同的实现可能使得验证器直接通过在线过程来注册。 + +|Figure 5| |Figure 6| + +*客户端:* +请求TCert批量需要包含(另外计数),ECert和使用ECert私钥签名的请求(其中ECert的私钥使用本地存储获取的) + +*TCA为批量生成TCerts:* 生成密钥派生函数的密钥,KeyDF\_Key, +当作HMAC(TCA\_KDF\_Key, EnrollPub\_Key). +为每张TCert生成公钥(使用TCertPub\_Key = EnrollPub\_Key + ExpansionValue +G, 其中384位的ExpansionValue = HMAC(Expansion\_Key, TCertIndex) +和384位的Expansion\_Key = HMAC(KeyDF\_Key, “2”)). +生成每个AES\_EncryptTCertOwner\_EncryptKey(TCertIndex \|\| +已知的填充/校验检查向量), 其中\|\| +表示连接,且TCertOwner\_EncryptKey被当作[HMAC(KeyDF\_Key, +“1”)]派生256位截断. + +*客户端:* +为部署,调用和查询,根据TCert来生成TCert的私钥:KeyDF\_Key和ECert的私钥需要从本地存储中获取。KeyDF\_Key是用来派生被当作[HMAC(KeyDF\_Key, +“1”)]256位截断的TCertOwner\_EncryptKey;TCertOwner\_EncryptKey是用来对TCert中的 +AES\_EncryptTCertOwner\_EncryptKey(TCertIndex \|\| +已知的填充/校验检查向量)域解密的;TCertIndex是用来派生TCert的私钥的: +TCertPriv\_Key = (EnrollPriv\_Key + +ExpansionValue)模n,其中384位的ExpansionValue = HMAC(Expansion\_Key, +TCertIndex),384位的Expansion\_Key = HMAC(KeyDF\_Key, “2”)。 + +4.2.2 过期和废止证书 +^^^^^^^^^^^^^^^^^^^^ + +实际是支持交易证书过期的。一张交易证书能使用的时间窗是由‘validity +period’标识的。实现过期支持的挑战在于系统的分布式特性。也就是说,所有验证实体必须共享相同的信息;即,与交易相关的有效期验证需要保证一致性。为了保证有效期的验证在所有的验证器间保持一致,有效期标识这一概念被引入。这个标识扮演着逻辑时钟,使得系统可以唯一识别有效期。在创世纪时,链的“当前有效期”由TCA初始化。至关重要的是,此有效期标识符给出随时间单调增加的值,这使得它规定了有效期间总次序。 + +对于指定类型的交易,系统交易有效周期标识是用来一起向区块链公布有效期满的。系统交易涉及已经在创世纪块被定义和作为基础设施的一部分的合同。有效周期标识是由TCA周期性的调用链码来更新的。注意,只有TCA允许更新有效期。TCA通过给定义了有效期区间的‘not-before’和‘not-after’这两个域设置合适的整数值来为每个交易证书设置有效期。 + +TCert过期: 在处理TCert时,验证器从状态表中读取与总账中的‘current +validity +period’相关的值来验证与交易相关的外部证书目前是否有效。状态表中的当前值需要落在TCert的‘not-before’和‘not-after’这两个子域所定义的区间中。如果满足,那么验证器就继续处理交易。如果当前值没有在这个区间中,那么TCert已经过期或还没生效,那么验证器就停止处理交易。 + +ECert过期: 注册证书与交易证书具有不同的有效期长度。 + +废止是由证书废止列表(CRLs)来支持的,CRLs鉴定废止的证书。CRLs的改变,增量的差异通过区块链来公布 + +4.3 基础设施层面提供的交易安全 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +fabric中的交易是通过提交用户-消息来引入到总账中的。就像之前章节讨论的那样,这些信息具有指定的结构,且允许用户部署新的链码,调用已经存在的链码,或查询已经存在的链码的状态。因此交易的方式被规范,公布和处理在整个系统提供的隐私和安全中起着重要的作用。 + +一方面我们的成员服务通过检查交易是由系统的有效用户创建的来提供验证交易的手段,为了把用户身份和交易撇清,但是在特定条件下又需要追踪特定个体的交易(执法,审计)。也就是说,成员服务提供结合用户隐私与问责制和不可抵赖性来提供交易认证机制。 + +另一方面,fabric的成员服务不能单独提供完整的用户活动隐私。首先fabric提供完整的隐私保护条款,隐私保护认证机制需要通过交易保密协同。很明显,如果认为链码的内容可能会泄漏创建者的信息,那么这就打破了链码创建者的隐私要求。第一小节讨论交易的保密性。 + +.. raw:: html + + + +.. raw:: html + + + +为链码的调用强制访问控制是一个重要的安全要求。fabric暴露给应用程序(例如,链码创建者)这意味着当应用利用fabric的成员服务是,需要应用自己调用访问控制。4.4节详细阐述了这一点。 + +.. raw:: html + + + +重放攻击是链码安全的另一个重要方面,作为恶意用户可能复制一个之前的,已经加入到区块链中的交易,并向网络重放它来篡改它的操作。这是第4.3.3节的话题。 + +本节的其余部分介绍了基础设施中的安全机制是如何纳入到交易的生命周期中,并分别详细介绍每一个安全机制。 + +4.3.1 交易安全的生命周期 +^^^^^^^^^^^^^^^^^^^^^^^^ + +交易在客户端创建。客户端可以是普通的客户端,或更专用的应用,即,通过区块链处理(服务器)或调用(客户端)具体链码的软件部分。这样的应用是建立在平台(客户端)上的,并在4.4节中详细介绍。 + +新链码的开发者可以通过这些fabric的基础设施来新部署交易: \* +希望交易符合保密/安全的版本和类型 \* +希望访问部分链码的用户有适当的(读)访问权限 \* 链码规范 \* +代码元数据,包含的信息需要在链码执行时传递给它(即,配置参数),和 \* +附加在交易结构上的并只在应用部署链码时使用的交易元数据 + +具有保密限制的链码的调用和查询交易都是用类似的方式创建。交易者提供需要执行的链码的标识,要调用的函数的名称及其参数。可选的,调用者可以传递在链码执行的时候所需要提供的代码调用元数据给交易创建函数。交易元数据是调用者的应用程序或调用者本身为了它自己的目的所使用的另外一个域。 + +最后,交易在客户端,通过它们的创建者的证书签名,并发送给验证器网络。 +验证器接受私密交易,并通过下列阶段传递它们: \* +*预验证*\ 阶段,验证器根据根证书颁发机构来验证交易证书,验证交易(静态的)中包含交易证书签名,并验证交易是否为重放(参见,下面关于重放攻击的详细信息)。 +\* *共识*\ 阶段, +验证器把这笔交易加入到交易的全序列表中(最终包含在总账中) \* +*预执行*\ 阶段, 验证交易/注册证书是否在当前的有效期中 +解密交易(如果交易是加密的),并验证交易明文的形式正确(即,符合调用访问控制,包含TCert形式正确) +在当前处理块的事务中,也执行了简单的重放攻击检查。 \* *执行*\ 阶段, +(解密的) 链码和相关的代码元数据被传递给容器,并执行。 \* *提交* 阶段, +(解密的)更新的链码的状态和交易本身被提交到总账中。 + +4.3.2 交易保密性 +^^^^^^^^^^^^^^^^ + +在开发人员的要求下,交易机密性要求链码的原文,即代码,描述,是不能被未授权的实体(即,未被开发人员授权的用户或 +peer)访问或推导(assuming a computational +attacker)出来。对于后者,\ *部署*\ 和\ *调用*\ 交易的内容始终被隐藏对链码的保密需求是至关重要的。本着同样的精神,未授权方,不应该能联系链码(调用交易)与链码本身(部署交易)之间的调用关系或他们之间的调用。 + +任何候选的解决方案的附加要求是,满足并支持底层的成员服务的隐私和安全规定。此外,在fabric中他不应该阻止任何链码函数的调用访问控制,或在应用上实现强制的访问控制机制(参看4.4小结)。 + +下面提供了以用户的粒度来设置的交易机密性机制的规范。最后小结提供了一些如何在验证器的层次来扩展这个功能的方针。当前版本所支持的特性和他的安全条款可以在4.7节中找到。 + +目标是达到允许任意的子集实体被允许或限制访问链码的下面所展示的部分: 1. +链码函数头,即,包含在链码中函数的原型 2. 链码[调用&] 状态,即, +当一个或多个函数被调用时,连续更新的特定链码的状态。 3. 所有上面所说的 + +注意,这样的设计为应用提供利用fabric的成员管理基础设施和公钥基础设施来建立自己的访问控制策略和执法机制的能力。 + +4.3.2.1 针对用户的保密 +'''''''''''''''''''''' + +为了支持细粒度的保密控制,即,为链码创建者定义的用户的子集,限制链码的明文读权限,一条绑定到单个长周期的加密密钥对的链(PKchain, +SKchain)。 + +尽管这个密钥对的初始化是通过每条链的PKI来存储和维护的,在之后的版本中,这个限制将会去除。链(和相关的密钥对)可以由任意带有\ *特定*\ (管理)权限的用户通过区块链来触发(参看4.3.2.2小节) + +**搭建**. 在注册阶段, +用户获取(像之前一样)一张注册证书,为用户ui标记为Certui,其中每个验证器vj获取的注册证书标记为Certvj。注册会给用户或验证器发放下面这些证书: + +1. 用户: + +a. 声明并授予自己签名密钥对(spku, ssku) + +b. 申明并授予他们加密密钥对(epku, esku), + +c. 获取链PKchain的加密(公共)密钥 + +2. 验证器: + +a. 声明并授予他们签名密钥对(spkv, sskv) + +b. 申明并授予他们加密密钥对 (epkv, eskv), + +c. 获取链SKchain的解密(秘密)密钥 + +因此,注册证书包含两个密钥对的公共部分: \* +一个签名密钥对[为验证器标记为(spkvj,sskvj),为用户标记为(spkui, sskui)] +和 \* 一个加密密钥对[为验证器标记为(epkvj,eskvj),为用户标记为(epkui, +eskui)] + +链,验证器和用户注册公钥是所有人都可以访问的。 + +除了注册证书,用户希望通过交易证书的方式匿名的参与到交易中。用户的简单交易证书ui被标记为TCertui。交易证书包含的签名密钥对的公共部分标记为(tpkui,tskui)。 + +下面的章节概括性的描述了如何以用户粒度的方式提供访问控制。 + +**部署交易的结构.** 下图描绘了典型的启用了保密性的部署交易的结构。 + +.. figure:: ./images/sec-usrconf-deploy.png + :alt: FirstRelease-deploy + + FirstRelease-deploy + +注意,部署交易由几部分组成: \* *基本信息*\ 部分: +包含交易管理员的详细信息,即这个交易对应于哪个链(链接的),交易的类型(设置''deplTrans''),实现的保密协议的版本号,创建者的身份(由注册证书的交易证书来表达),和主要为了防止重放攻击的Nonce。 +\* *代码信息*\ 部分: +包含链码的源码,函数头信息。就像下图所展示的那样,有一个对称密钥(KC)用于链码的源代码,另一个对称密钥(KH)用于函数原型。链码的创建者会对明文代码做签名,使得信函不能脱离交易,也不能被其他东西替代。 +\* *链验证器*\ 部分: +为了(i)解密链码的源码(KC),(ii)解密函数头,和(iii)当链码根据(KS)调用时加密状态。尤其是链码的创建者为他部署的链码生产加密密钥对(PKC, +SKC)。它然后使用PKC加密所有与链码相关的密钥: + +.. raw:: html + +
+ +[(''code'',KC) ,(''headr'',KH),(''code-state'',KS), SigTCertuc(\*)]PKc, + +.. raw:: html + +
+ +并把 where appropriate key material is passed to the In particular, the +chain-code creator generates an encryption key-pair for the chain-code +it deploys (PKC, SKC). It then uses PKC to encrypt all the keys +associated to the chain-code: + +.. raw:: html + +
+ +[(''code'',KC) ,(''headr'',KH),(''code-state'',KS), SigTCertuc(\*)]PKc, + +.. raw:: html + +
+ +私钥SKC通过链指定的公钥: + +.. raw:: html + +
+ +[(''chaincode'',SKC), SigTCertuc(\*)]PKchain. + +.. raw:: html + +
+ +传递给验证器。 \* *合同用户*\ 部分: +合同用户的公共密钥,即具有部分链码读权限的用户,根据他们的访问权限加密密钥: + +1. SKc使得用户能读取与这段链码相关的任意信息(调用,状态,等) + +2. KC使用户只能读取合同代码 + +3. KH 使用户只能读取头信息 + +4. KS使用户只能读取与合同相关的状态 + +最后给用户发放一个合同的公钥PKc,使得他们可以根据合同加密信息,从而验证器(or +any in possession of +SKc)可以读取它。每个合同用户的交易证书被添加到交易中,并跟随在用户信息之后。这可以使得用户可以很容易的搜索到有他们参与的交易。注意,为了信函可以在本地不保存任何状态的情况下也能通过分析总账来获取这笔交易,部署交易也会添加信息到链码创建者uc。 + +整个交易由链码的创建者的证书签名,即:由后者决定使用注册还是交易证书。 +两个值得注意的要点: \* +交易中的信息是以加密的方式存储的,即,code-functions, \* +code-hdrs在使用TCert加密整个交易之前会用想用的TCert签名,或使用不同的TCert或ECert(如果交易的部署需要带上用户的身份。一个绑定到底层交易的载体需要包含在签名信息中,即,交易的TCert的哈希是签名的,因此mix&match攻击是不可能的。我们在4.4节中详细讨论这样的攻击,在这种情况下,攻击者不能从他看到的交易中分离出对应的密文,即,代码信息,并在另一个交易中使用它。很明显,这样会打乱整个系统的操作,链码首先有用户A创建,现在还属于恶意用户B(可能没有权限读取它) +\* +为了给用户提供交叉验证的能力,会给他们访问正确密钥的权限,即给其他用户相同的密钥,使用密钥K对交易加密成密文,伴随着对K的承诺,而这一承诺值开放给所有在合同中有权访问K的用户,和链验证器。 +在这种情况下,谁有权访问该密钥,谁就可以验证密钥是否正确传递给它。为了避免混乱,这部分在上图中省略了。 + +**调用交易的结构.** +下图结构化描述了,交易调用链码会触发使用用户指定的参数来执行链码中的函数 + +.. figure:: ./images/sec-usrconf-invoke.png + :alt: FirstRelease-deploy + + FirstRelease-deploy + +调用交易和部署交易一样由一个\ *基本信息*\ , +*代码信息*\ ,\ *链验证器*\ 和一个\ *合同用户*\ ,并使用一张调用者的交易证书对所有进行签名。 + +- 基本信息 + 与部署交易中对应部分遵循相同的结构。唯一的不同是交易类型被设置为''InvocTx'',链码的标识符或名字是通过链指定的加密(公共)密钥来加密的。 + +- 代码信息 + 部署交易中的对应结构具有相同展现。在部署交易中作为代码有效载荷,现在由函数调用明细(调用函数的名字,对应的参数),由应用提供的代码元数据和交易创建者(调用者 + u)的证书,TCertu。在部署交易的情况下,代码有效载荷和是通过调用者u的交易证书TCertu签名的。在部署交易的情况下,代码元数据,交易数据是由应用提供来使得信函可以实现他自己的访问控制机制和角色(详见4.4节)。 + +- 最后,合同用户和链验证器部分提供密钥和有效荷载是使用调用者的密钥加密的,并分别链加密密钥。在收到此类交易,验证器解密 + [code-name]PKchain使用链指定的密钥SKchain + ,并获取被调用的链码身份。给定的信封,验证器从本地的获取链码的解密密钥SKc,并使用他来解密链验证器的信息,使用对称密钥 + KI对调用交易的有效荷载加密。给定信函,验证器解密代码信息,并使用指定的参数和附加的代码元数据(参看4.4节的代码元数据详细信息)执行链码。当链码执行后,链码的状态可能就更新了。 + 加密所使用的状态特定的密钥Ks在链码部署的时候就定义了。尤其是,在当前版本中Ks + 和KiTx被设计成一样的(参看4.7节)。 + +**查询交易的结构.** +查询交易和调用交易具有同样的格式。唯一的区别是查询交易对链码的状态没有影响,且不需要在执行完成之后获取(解密的)并/或更新(加密的)状态。 + +4.3.2.2 针对验证器的保密 +'''''''''''''''''''''''' + +这节阐述了如何处理当前链中的不同(或子集)集合的验证器下的一些交易的执行。本节中抑制IP限制,将在接下的几个星期中进行扩展。 + +4.3.3 防重放攻击 +^^^^^^^^^^^^^^^^ + +在重放攻击中,攻击者“重放”他在网络上“窃听”或在区块链''看到''的消息 +由于这样会导致整个验证实体重做计算密集型的动作(链码调用)和/或影响对应的链码的状态,同时它在攻击侧又只需要很少或没有资源,所以重放攻击在这里是一个比较大的问题。如果交易是一个支付交易,那么问题就更大了,重放可能会导致在不需要付款人的参与下,多于一次的支付。 +当前系统使用以下方式来防止重放攻击: \* +在系统中记录交易的哈希。这个方法要求验证器为每个交易维护一个哈希日志,发布到网络上,并把每个新来的交易与本地存储的交易记录做对比。很明显这样的方法是不能扩展到大网络的,也很容易导致验证器花了比真正做交易还多的时间在检查交易是不是重放上。 +\* +利用每个用户身份维护的状态(Ethereum).Ethereum保存一些状态,即,对每个身份/伪匿名维护他们自己的计数器(初始化为1)。每次用户使用他的身份/伪匿名发送交易是,他都把他的本地计数器加一,并把结果加入到交易中。交易随后使用用户的身份签名,并发送到网络上。当收到交易时,验证器检查计数器并与本地存储的做比较;如果值是一样的,那就增加这个身份在本地的计数器,并接受交易。否则把交易当作无效或重放的而拒绝掉。尽管这样的方法在有限个用户身份/伪匿名(即,不太多)下工作良好。它最终在用户每次交易都使用不同的标识(交易证书),用户的伪匿名与交易数量成正比时无法扩展。 + +其他资产管理系统,即比特币,虽然没有直接处理重放攻击,但它防止了重放。在管理(数字)资产的系统中,状态是基于每个资产来维护的,即,验证器只保存谁拥有什么的记录。因为交易的重放根据协议(因为只能由资产/硬币旧的所有者衍生出来)可以直接认为无效的,所以防重放攻击是这种方式的直接结果。尽管这合适资产管理系统,但是这并不表示在更一般的资产管理中需要比特币系统。 + +在fabric中,防重放攻击使用混合方法。 +这就是,用户在交易中添加一个依赖于交易是匿名(通过交易证书签名)或不匿名(通过长期的注册证书签名)来生成的nonce。更具体的: +\* +用户通过注册证书来提交的交易需要包含nonce。其中nonce是在之前使用同一证书的交易中的nonce函数(即计数器或哈希)。包含在每张注册证书的第一次交易中的nonce可以是系统预定义的(即,包含在创始块中)或由用户指定。在第一种情况中,创世区块需要包含nonceall,即,一个固定的数字和nonce被用户与身份IDA一起用来为他的第一笔注册证书签名的交易将会 + +.. raw:: html + +
+ +nonceround0IDA <- hash(IDA, nonceall), + +.. raw:: html + +
+ +其中IDA出现在注册证书中。从该点之后的这个用户关于注册证书的连续交易需要包含下面这样的nonce + +.. raw:: html + +
+ +nonceroundiIDA <- hash(nonceround{i-1}IDA), + +.. raw:: html + +
+ +这表示第i次交易的nonce需要使用这样证书第{i-1}次交易的nonce的哈希。验证器持续处理他们收到的只要其满足上述条件的交易。一旦交易格式验证成功,验证器就使用nonce更新他们的数据库。 + +**存储开销**: + +1. 在用户侧:只有最近使用的nonce + +2. 在验证器侧: O(n), 其中n是用户的数量 + +- 用户使用交易证书提交的交易需要包含一个随机的nonce,这样就保证两个交易不会产生同样的哈希。如果交易证书没有过期的话,验证器就向本地数据库存储这笔交易的哈希。为了防止存储大量的哈希,交易证书的有效期被利用。特别是验证器为当前或未来有效周期来维护一个接受交易哈希的更新记录。 + +**存储开销** (这里只影响验证器): O(m), +其中m近似于有效期内的交易和对应的有效标识的数量(见下方) + +4.4 应用的访问控制功能 +~~~~~~~~~~~~~~~~~~~~~~ + +应用是运行在区块链客户端软件上的一个具有特定功能的软件。如餐桌预订。应用软件有一个开发版本,使后者可以生成和管理一些这个应用所服务的行业所需要的链码,而且,客户端版本可以允许应用的终端用户调用这些链码。应用可以选择是否对终端用户屏蔽区块链。 + +本节介绍应用中如何使用链码来实现自己的访问控制策略,并提供如何使用成员服务来达到相同的目的。 + +这个报告可以根据应用分为调用访问控制,和读取访问控制。 + +4.4.1 调用访问控制 +^^^^^^^^^^^^^^^^^^ + +为了允许应用在应用层安全的实现自己的访问问控制,fabric需要提供特定的支持。在下面的章节中,我们详细的说明的fabric为了达到这个目的而给应用提供的工具,并为应用如何来使用它们使得后者能安全的执行访问控制提供方针。 + +**来自基础设施的支持.** 把链码的创建者标记为 +*uc*\ ,为了安全的实现应用层自己的调用访问控制,fabric必须需要提供特定的支持。 +更具体的,fabric层提供下面的访问能力: + +1. 客户端-应用可以请求fabric使用指定的客户端拥有的交易证书或注册证书来签名和验证任何消息; + 这是由Certificate Handler interface来处理的。 + +2. 客户端-应用可以请求fabric一个\ *绑定*\ 将身份验证数据绑定到底层的交易传输的应用程序;这是由Certificate + Handler interface来处理的。 + +3. 为了支持交易格式,允许指定被传递给链码在部署和调用时间的应用的元数据;后者被标记为代码元数据。 + +**Certificate +Handler**\ 接口允许使用底层证书的密钥对来对任意消息进行签名和验证。证书可以是TCert或ECert。 + +:: + + // CertificateHandler exposes methods to deal with an ECert/TCert + type CertificateHandler interface { + + // GetCertificate returns the certificate's DER + GetCertificate() []byte + + // Sign signs msg using the signing key corresponding to the certificate + Sign(msg []byte) ([]byte, error) + + // Verify verifies msg using the verifying key corresponding to the certificate + Verify(signature []byte, msg []byte) error + + // GetTransactionHandler returns a new transaction handler relative to this certificate + GetTransactionHandler() (TransactionHandler, error) + } + +**Transaction +Handler**\ 借口允许创建交易和访问可利用的底层\ *绑定*\ 来链接应用数据到底层交易。绑定是在网络传输协议引入的概念(参见,https://tools.ietf.org/html/rfc5056)记作\ *通道绑定*\ ,\ *允许应用在网络层两端的建立安全通道,与在高层的认证绑定和在低层是一样的。 +这允许应用代理保护低层会话,这具有很多性能优势。* +交易绑定提供识别fabric层次交易的身份,这就是应用数据要加入到总账的容器。 + +:: + + // TransactionHandler represents a single transaction that can be uniquely determined or identified by the output of the GetBinding method. + // This transaction is linked to a single Certificate (TCert or ECert). + type TransactionHandler interface { + + // GetCertificateHandler returns the certificate handler relative to the certificate mapped to this transaction + GetCertificateHandler() (CertificateHandler, error) + + // GetBinding returns a binding to the underlying transaction (container) + GetBinding() ([]byte, error) + + // NewChaincodeDeployTransaction is used to deploy chaincode + NewChaincodeDeployTransaction(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string) (*obc.Transaction, error) + + // NewChaincodeExecute is used to execute chaincode's functions + NewChaincodeExecute(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) + + // NewChaincodeQuery is used to query chaincode's functions + NewChaincodeQuery(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) + } + +对于版本1,\ *绑定*\ 由\ *hash*\ (TCert, +Nonce)组成,其中TCert是给整个交易签名的交易证书,Nonce是交易所使用的nonce。 + +**Client**\ 接口更通用,提供之前接口实例的手段。 + +:: + + type Client interface { + + ... + + // GetEnrollmentCertHandler returns a CertificateHandler whose certificate is the enrollment certificate + GetEnrollmentCertificateHandler() (CertificateHandler, error) + + // GetTCertHandlerNext returns a CertificateHandler whose certificate is the next available TCert + GetTCertificateHandlerNext() (CertificateHandler, error) + + // GetTCertHandlerFromDER returns a CertificateHandler whose certificate is the one passed + GetTCertificateHandlerFromDER(der []byte) (CertificateHandler, error) + + } + +为了向链码调用控制提供应用级别的的访问控制列表,fabric的交易和链码指定的格式需要存储在应用特定元数据的额外的域。 +这个域在图1中通过元数据展示出来。这个域的内容是由应用在交易创建的时候决定的。fabric成把它当作非结构化的字节流。 + +:: + + + message ChaincodeSpec { + + ... + + ConfidentialityLevel confidentialityLevel; + bytes metadata; + + ... + } + + + message Transaction { + ... + + bytes payload; + bytes metadata; + + ... + } + +为了帮助链码执行,在链码调用的时候,验证器为链码提供额外信息,如元数据和绑定。 + +**应用调用访问控制.** +这一节描述应用如何使用fabric提供的手段在它的链码函数上实现它自己的访问控制。 +这里考虑的情况包括: + +1. **C**: 是只包含一个函数的链码,如,被成为\ *hello* + +2. **uc**: 是\ **C**\ 的部署; + +3. **ui**: + 是被授权调用\ **C**\ 的用户。用户uc希望只有ui可以调用函数\ *hello* + +*链码部署:* +在部署的时候,uc具有被部署交易元数据的完全控制权,可硬存储一个ACL的列表(每个函数一个),或一个应用所需要的角色的列表。存储在ACL中的格式取决于部署的交易,链码需要在执行时解析元数据。 +为了定义每个列表/角色,uc可以使用ui的任意TCerts/Certs(或,如果可接受,其他分配了权限或角色的用户)。把它记作TCertui。 +开发者和授权用户之间的TCerts和 Certs交换实在频外渠道进行的。 + +假设应用的uc需要调用 +*hello*\ 函数,某个消息\ *M*\ 就被授权给授权的调用者(在我们的例子中是ui)。 +可以区分为以下两种情况: + +1. *M*\ 是链码的其中一个函数参数; + +2. *M*\ 是调用信息本事,如函数名,函数参数。 + +*链码调用:* 为了调用C, +ui的应用需要使用TCert/ECert对\ *M*\ 签名,用来识别ui在相关的部署交易的元数据中的参与身份。即,TCertui。更具体的,ui的客户端应用做一下步骤: + +1. Certui, *cHandler*\ 获取CertificateHandler + +2. 获取新的TransactionHandler来执行交易, + *txHandler*\ 相对与他的下一个有效的TCert或他的ECert + +3. 通过调用\ *txHandler.getBinding()*\ 来得到\ *txHandler*\ 的绑定 + +4. 通过调用\ *cHandler.Sign('*\ M\* \|\| txBinding')\ *来对*'*M* \|\| + txBinding'\ *签名, *\ sigma\*是签名函数的输出。 + +5. 通过调用来发布一个新的执行交易,\ *txHandler.NewChaincodeExecute(...)*. + 现在, + *sigma*\ 可以以一个传递给函数(情形1)参数或payload的元数据段的一部分(情形2)的身份包含在交易中。 + +*链码处理:* 验证器, 从ui处接受到的执行交易将提供以下信息: + +1. 执行交易的\ *绑定*\ ,他可以在验证端独立的执行; + +2. 执行交易的\ *元数据*\ (交易中的代码元数据); + +3. 部署交易的\ *元数据*\ (对应部署交易的代码元数据组建). + +注意\ *sigma*\ 是被调用函数参数的一部分,或者是存储在调用交易的代码元数据内部的(被客户端应用合理的格式化)。 +应用ACL包含在代码元数据段中,在执行时同样被传递给链码。 +函数\ *hello*\ 负责检查\ *sigma*\ 的确是通过TCertui在'\ *M* \|\| +*txBinding'*\ 上的有效签名。 + +4.4.2 读访问控制 +^^^^^^^^^^^^^^^^ + +这节描述fabric基础设施如何支持应用在用户层面执行它自己的读访问控制策略。和调用访问控制的情况一样,第一部分描述了可以被应用程序为实现此目的利用的基础设施的功能,接下来介绍应用使用这些工具的方法。 + +为了说明这个问题,我们使用和指点一样的例子,即: + +1. **C**: 是只包含一个函数的链码,如,被成为\ *hello* + +2. **uA**: 是\ **C**\ 的部署者,也被成为应用; + +3. **ur**: + 是被授权调用\ **C**\ 的用户。用户uA希望只有ur可以读取函数\ *hello* + +**来自基础设施的支持.** +为了让\ **uA**\ 在应用层安全的实现自己的读取访问控制我们的基础设施需要像下面描述的那样来支持代码的部署和调用交易格式。 + +.. figure:: ./images/sec-usrconf-deploy-interm.png + :alt: SecRelease-RACappDepl title="Deployment transaction format + supporting application-level read access control." + + SecRelease-RACappDepl title="Deployment transaction format supporting + application-level read access control." + +.. figure:: ./images/sec-usrconf-invoke-interm.png + :alt: SecRelease-RACappInv title="Invocation transaction format + supporting application-level read access control." + + SecRelease-RACappInv title="Invocation transaction format supporting + application-level read access control." + +更具体的fabric层需要提供下面这些功能: + +1. 为数据只能通过验证(基础设施)侧解密,提供最低限度的加密功能;这意味着基础设施在我们的未来版本中应该更倾向于使用非对称加密方案来加密交易。更具体的,在链中使用在上图中标记为 + Kchain 的非对称密钥对。具体参看交易保密小节 + +2. 客户端-引用可以请求基础设施,基于客户端侧使用特定的公共加密密钥或客户端的长期解密密钥来加密/解密信息。 + +3. 交易格式提供应用存储额外的交易元数据的能力,这些元数据可以在后者请求后传递给客户端应用。交易元数据相对于代码元数据,在执行时是没有加密或传递给链码的。因为验证器是不负责检查他们的有效性的,所以把它们当作字节列表。 + +**应用读访问控制.** +应用可以请求并获取访问用户\ **ur**\ 的公共加密密钥,我们把它标记为\ **PKur**\ 。可选的,\ **ur** +可能提供 +**uA**\ 的一张证书给应用,使应用可以利用,标记为TCertur。如:为了跟踪用户关于应用的链码的交易。TCertur和PKur实在频外渠道交换的。 + +部署时,应用 **uA**\ 执行下面步骤: + +1. 使用底层基础设施来加密\ **C**\ 的信息,应用使用PKur来访问\ **ur**\ 。标记Cur为得到的密文。 + +2. (可选) Cur可以和TCertur连接 + +3. 保密交易被构造为''Tx-metadata''来传递 + +在调用的时候,在 +ur节点上的客户端-应用可以获取部署交易来得到\ **C**\ 的内容。 +这只需要得到相关联的部署交易的 +**tx-metadata**\ 域,并触发区块链基础设施客户端为Cur提供的解密函数。注意,为ur正确加密\ **C**\ 是应用的责任。 +此外,使用\ **tx-metadata**\ 域可以一般性的满足应用需求。即,调用者可以利用调用交易的同一域来传递信息给应用的开发者。 + +\ **Important Note:** +要注意的是验证器在整个执行链码过程中\ **不提供**\ 任何解密预测。 +对payload解密由基础设施自己负责(以及它附近的代码元数据域)。并提供他们给部署/执行的容器。 + +4.5 在线钱包服务 +~~~~~~~~~~~~~~~~ + +这一节描述了钱包服务的安全设计,这是一个用户可以注册,移动他们的秘密材料到,办理交易的节点。 +由于钱包服务是一个用户秘密材料所有权的服务,所以要杜绝没有安全授权机制的恶意钱包服务可以成功模拟客户。 +因此,我们强调的是,设计一种\ **值得信赖**\ 的,只有在代表用户的客户端同意的情况下,钱包服务才能执行交易。 +这里有两种终端用户注册到在线钱包服务的情况: + +1. 当用户注册到注册机构并获得他/她的 + ````\ ,但是没有安装客户端来触发完整的注册过程。 + +2. 用户已经安装客户端并完成注册阶段 + +首先,用户与在线钱包服务交互,允许他们进行身份验证的钱包服务发布证书。即用户给定用户名和密码,其中用户名在成员服务中识别用户,标记为AccPub,密码是关联的秘密,标记为AccSec,这是由用户和服务分享的。 + +为了通过在线钱包服务注册,用户必须提供下面请求对象到钱包服务: + +:: + + AccountRequest /* account request of u \*/ + { + OBCSecCtx , /* credentials associated to network \*/ + AccPubu, /* account identifier of u \*/ + AccSecProofu /* proof of AccSecu\*/ + } + +OBCSecCtx指向用户证书,它依赖于注册过程中的阶段。可以是用户的注册ID和密码,\ ```` +或他的注册证书和关联的密钥(ECertu, sku), 其中 +sku是用户签名和解密密钥的简化标记。 +OBCSecCtx需要给在线钱包服务必要的信息来注册用户和发布需要的TCerts。 + +对于后续的请求,用户u需要提供给钱包服务的请求与下面这个格式类似。 + +:: + + TransactionRequest /* account request of u \*/ + { + TxDetails, /* specifications for the new transaction \*/ + AccPubu, /* account identifier of u \*/ + AccSecProofu /* proof of AccSecu \*/ + } + +这里,TxDetails指向在线服务代表用户构造交易所需要的信息,如类型,和用户指定的交易的内容。 + +AccSecProofu是对应请求中剩下的域的使用共享密钥的HMAC。 +Nonce-based方法与我们在fabric中一样可以防止重放攻击。 + +TLS连接可以用在每种服务器端认证的情况,在网络层对请求加密(保密,防止重放攻击,等) + +4.6 网络安全(TLS) +~~~~~~~~~~~~~~~~~ + +TLS +CA需要给(非验证)peer,验证器,和单独的客户端(或具有存储私钥的游览器)发放TLS证书的能力。最好,这些证书可以使用之前的类型来区分。 +各个类型的CA(如TLS CA, ECA, +TCA)的TLS证书有可以通过中间CA(如,一个根CA的下属CA)发放。这里没有特定流量分析的问题,任意给定的TLS连接都可以相互验证,除了请求TLS +CA的TLS证书的时候。 + +在当前的实现中,唯一的信任锚点是TLS +CA的自签名证书来适应与所有三个(共址)服务器(即TLS +CA,TCA和ECA)进行通信的单个端口限制。因此,与TLS CA的TLS握手来与TLS +CA建立连接,所得到的会话密钥会传递给共址的TCA和ECA。因此,TCA和ECA的自签名证书的有效性的信任继承自对TLS +CA的信任。在不提高TLS CA在其他CA之上的实现中,信任锚点需要由TLS +CA和其他CA都认证的根CA替代。 + +4.7 当前版本的限制 +~~~~~~~~~~~~~~~~~~ + +这一小节列出了当前版本的fabric的限制。 +具体的关注点是客户端操作和交易保密性设计,如4.7.1和4.7.2所述。 + +- 客户端注册和交易的创建是由受信任不会模拟用户的非验证 peer + 来完全执行。参看4.7.1节得到更多j信息。 +- 链码只能被系统的成员实体访问是保密性的最低要求,即,注册到我们成员服务的验证器和用户,其它的都不能访问。后者包含可以访问到存储区域维护的总账,或者可以看到在验证器网络上公布的交易。第一个发布版本在4.7.2小节中详细介绍。 +- 代码为注册CA(ECA)和交易CA(TCA)使用自签名的证书 +- 防重放攻击机制还不可用 +- 调用访问控制可以在应用层强制执行: + 安全性的保证取决于应用对基础设施工具的正确使用。这说明如果应用忽略了fabric提供的交易绑定\ *绑定*\ 安全交易的处理可能在存在风险。 + +4.7.1 简化客户端 +^^^^^^^^^^^^^^^^ + +客户端的注册和交易的创建是由非验证 peer +以在线钱包的角色全部执行的。特别地,终端用户利用他们的注册证书向非验证 +peer 开立账户,并且使用这些证书来进一步授权 peer 建立代表用户的交易。 +需要注意的是,这样的设计不会为 peer +代表用户提交的交易提供安全\ **授权**\ ,如恶意 peer 可以模拟用户。 +网上钱包的涉及安全问题设计规范的详细信息,可以在4.5节找到。 +目前用户可以注册和执行交易的 peer 数量是一。 + +4.7.2 简化交易保密 +^^^^^^^^^^^^^^^^^^ + +**免责声明:** +当前版本的交易保密是最小的,这被用来作为中间步骤来达到允许在未来版本中的细粒度(调用)的访问控制的执行设计。 + +在当前的格式,交易的保密仅仅在链层面提供,即,保存在总账中的交易内容对链的所有成员,如,验证器和用户,都是可读的。于此同时,不是系统的成员的应用审计人员,可以给予被动的观察区块链数据的手段。同时保证给予他们只是为了与被审计应用程序相关的交易。状态通过一种加密,同时不破坏底层共识网络的正常运行的方式来满足这样的审计要求 + +更具体的,当前使用对称密钥加密来提供交易保密性。 +在这种背景下,一个最主要的挑战是特定于区块链的设置,验证器需要在区块链的状态上打成共识,即,除了交易本身,还包括个人合同或链码的状态更新。 +虽然对于非机密链码这是微不足道的,对于机密链码,需要设计状态的加密机制,使得所得的密文语义安全,然而,如果明文状态是相同的那么他们就相等。 + +为了克服这一难题,fabric利用了密钥的层级,使用相同的密钥进行加密来降低密文数。同时,由于部分这些密钥被用于IV的生成,这使得验证方执行相同的事务时产生完全相同的密文(这是必要的,以保持不可知到底层共识算法),并通过只披露给审计实体最相关的密钥来提供控制审计的可能性。 + +**方法描述:** 成员服务为总账生成对称密钥 +(Kchain),这是在注册到区块链系统所有实体时发布的,如,客户端和验证实体已通过链的成员服务发放证书。 +在注册阶段,用户获取(像之前一样)一张注册证书,为用户ui记作Certui,每个验证器vj获取它的被记作Certvj的证书。 + +实体注册将得到提高,如下所示。除了注册证书,用户希望以匿名方式参与交易发放交易证书。 +为了简化我们把用户 ui 的交易证书记作 TCertui。 +交易证书包含签名密钥对的公共部分记作 (tpkui,tskui)。 + +为了防止密码分析和执行保密,下面的密钥层级被用来生成和验证保密的交易: +为了提交保密交易(Tx)到总账,客户端首先选择一个nonce(N),这是需要提交区块链的所有交易中是唯一的,并通过以Kchain作为密钥,nonce作为输入的HMAC函数生成一个交易对称密钥(KTx))KTx= +HMAC(Kchain, N)。 对于KTx,客户端生成两个AES密钥: KTxCID当作HMAC(KTx, +c1), KTxP 当作 HMAC(KTx, c2)) +分别加密链码名称或标识CID和代码(或payload)P. c1, c2 +是公共常量。nonce,加密的链码ID(ECID)和加密的Payload(EP)被添加到交易Tx结构中,即最终签名和认证的。 +下面的图显示了如何产生用于客户端的事务的加密密钥。这张图中的剪头表示HMAC的应用,源由密钥锁定和使用在箭头中的数量作为参数。部署/调用交易的密钥键分别用d/I表示。 + +.. figure:: ./images/sec-firstrel-1.png + :alt: FirstRelease-clientSide + + FirstRelease-clientSide + +为了验证客户端提交到区块链的保密交易Tx,验证实体首先通过和之前一样的Kchain和Tx.Nonce再生成KTxCID和KTxP来解密ECID和EP。一旦链码和Payload被恢复就可以处理交易了。 + +.. figure:: ./images/sec-firstrel-2.png + :alt: FirstRelease-validatorSide + + FirstRelease-validatorSide + +当V验证一个机密事务,相应的链码可以访问和修改链码的状态。V保持链码的状态加密。为了做到这一点,V生成如上图所示的对称密钥 +。让iTX是一个之前由保密交易dTx部署的保密的交易调用一个函数(注意iTx可以是dTx本身)在这种情况下,例如,dTx具有初始化链码状态的设置函数。然后V像下面一样生成两个对称密钥KIV和Kstate: + +1. 计算KdTx如,对应部署交易的交易密钥和Nstate = HMAC(Kdtx + ,hash(Ni))其中Ni是在调用交易中出现的nonce, *hash*\ 是哈希函数 +2. 它设Kstate = HMAC(KdTx, c3 \|\| Nstate),截断用来加密底层密码; c3 + 是一个常数 +3. 它设KIV = HMAC(KdTx, c4 \|\| Nstate); c4 是一个常数 + +为了加密状态变量S,验证器首先生成IV像 HMAC(KIV, crtstate)正确截断,其中 +crtstate是计数器值,并在每次同样链码调用时请求状态更新时增加。当链码执行终止是计数器丢弃。IV产生之后,V认证加密(即,GSM模式)S的值连接Nstate(实际上,Nstate只需要认证而不需要加密)。在所得的密文(CT), +Nstate和IV被追加。为了解密加密状态CT\|\| +Nstate',验证器首次生成对称密钥KdTX' ,Kstate',然后解密CT。 + +IV的生成: +任何底层共识算法是不可知的,所有的验证各方需要一种方法以产生相同的确切密文。为了做到这一点,需要验证使用相同的IV。重用具有相同的对称密钥相同的IV完全打破了底层密码的安全性。因此,前面所描述的方法制备。特别是,V首先通过计算HMAC(KdTX, +c4 \|\| Nstate )派生的IV生成密钥KIV,其中c4是一个常数,并为(dTx, +iTx)保存计数器crtstate初始设置为0。然后,每次必须生成一个新的密文,验证器通过计算HMAC(KIV, +crtstate)作为输出生成新的IV,然后为crtstate增加1。 + +上述密钥层次结构的另一个好处是控制了审计的能力。 +例如,当发布Kchain会提供对整个供应链的读取权限,当只为交易的(dTx,iTx)发布Kstate访问只授予由iTx更新的状态,等等 + +下图展示一个部署和调用交易在目前在代码中的形式。 + +.. figure:: ./images/sec-firstrel-depl.png + :alt: FirstRelease-deploy + + FirstRelease-deploy + +.. figure:: ./images/sec-firstrel-inv.png + :alt: FirstRelease-deploy + + FirstRelease-deploy + +可以注意到,部署和调用交易由两部分组成: + +- *基本信息*\ 部分: + 包含交易管理细节,如,把这个交易链接到的(被链接到的),交易的类型(被设置为''deploymTx''或''invocTx''),保密策略实现的版本号,它的创建者标识(由TCert,Cert表达)和一个nonce(主要为了防止重放攻击) + +- *代码信息*\ 部分: + 包含在链码的源代码的信息。本质上是链码标识符/名称和源代码的部署交易,而对调用链码是是被调用函数名称和它的参数。就像在两张图中展示的代码信息那样他们最终是使用链指定的对称密钥Kchain加密的。 + +5. 拜占庭共识 +------------- + +``obcpbft``\ 包是\ `PBFT `__\ 共识协议[1]的实现,其中提供了验证器之间的共识,虽然验证器的阈作为\_Byzantine\_,即,恶意的或不可预测的方式失败。在默认的配置中,PBFT容忍t + +fabric API 设计涵盖的类别如下,虽然当前版本的其中一些实现不完整。[REST +API(#62-REST的API)节将说明API当前支持。 + +- 身份 - 注册来获得或吊销一张证书 +- Address - 交易的源或目的 +- Transaction - 总账上的执行单元 +- Chaincode - 总账上运行的程序 +- Blockchain - 总账的内容 +- Network - 区块链 peer 网络的信息 +- Storage - 文件或文档的外部存储 +- Event Stream - 区块链上订阅/发布事件 + +6.1 REST Service +---------------- + +REST服务可以(通过配置)在验证和非验证 peer +被启用,但是建议在生产环境中只启用非验证 peer 的REST服务。 + +:: + + func StartOpenchainRESTServer(server *oc.ServerOpenchain, devops *oc.Devops) + +这个函数读取\ ``core.yaml``peer``\ 处理的配置文件中的\ ``rest.address``\ 。\ ``rest.address``\ 键定义了 +peer 的HTTP REST服务默认监听的地址和端口。 + +假定REST服务接收来已经认证的终端用户的应用请求。 + +6.2 REST API +------------ + +您可以通过您所选择的任何工具与REST +API的工作。例如,curl命令行实用程序或一个基于浏览器的客户端,如Firefox的REST客户端或Chrome +Postman。同样,可以通过 `Swagger `__ +直接触发REST请求。为了获得REST API Swagger描述,点击 +`这里 `__\ 。目前可用的API总结于以下部分。 + +6.2.1 REST Endpoints +~~~~~~~~~~~~~~~~~~~~ + +- `Block <#6211-block-api>`__ +- GET /chain/blocks/{block-id} +- `Blockchain <#6212-blockchain-api>`__ +- GET /chain +- `Chaincode <#6213-chaincode-api>`__ +- POST /chaincode +- `Network <#6214-network-api>`__ +- GET /network/peers +- `Registrar <#6215-registrar-api-member-services>`__ +- POST /registrar +- GET /registrar/{enrollmentID} +- DELETE /registrar/{enrollmentID} +- GET /registrar/{enrollmentID}/ecert +- GET /registrar/{enrollmentID}/tcert +- `Transactions <#6216-transactions-api>`__ +- GET /transactions/{UUID} + +6.2.1.1 块API +^^^^^^^^^^^^^ + +- **GET /chain/blocks/{block-id}** + +使用块API来从区块链中检索各个块的内容。返回的块信息结构是在\ `3.2.1.1 <#3211-block>`__\ 节中定义 + +块检索请求: + +:: + + GET host:port/chain/blocks/173 + +块检索响应: + +:: + + { + "transactions": [ + { + "type": 3, + "chaincodeID": "EgRteWNj", + "payload": "Ch4IARIGEgRteWNjGhIKBmludm9rZRIBYRIBYhICMTA=", + "uuid": "f5978e82-6d8c-47d1-adec-f18b794f570e", + "timestamp": { + "seconds": 1453758316, + "nanos": 206716775 + }, + "cert": "MIIB/zCCAYWgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMTI1MjE0MTE3WhcNMTYwNDI0MjE0MTE3WjArMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQ4wDAYDVQQDEwVsdWthczB2MBAGByqGSM49AgEGBSuBBAAiA2IABC/BBkt8izf6Ew8UDd62EdWFikJhyCPY5VO9Wxq9JVzt3D6nubx2jO5JdfWt49q8V1Aythia50MZEDpmKhtM6z7LHOU1RxuxdjcYDOvkNJo6pX144U4N1J8/D3A+97qZpKN/MH0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDA9BgYqAwQFBgcBAf8EMABNbPHZ0e/2EToi0H8mkouuUDwurgBYuUB+vZfeMewBre3wXG0irzMtfwHlfECRDDAKBggqhkjOPQQDAwNoADBlAjAoote5zYFv91lHzpbEwTfJL/+r+CG7oMVFUFuoSlvBSCObK2bDIbNkW4VQ+ZC9GTsCMQC5GCgy2oZdHw/x7XYzG2BiqmRkLRTiCS7vYCVJXLivU65P984HopxW0cEqeFM9co0=", + "signature": "MGUCMCIJaCT3YRsjXt4TzwfmD9hg9pxYnV13kWgf7e1hAW5Nar//05kFtpVlq83X+YtcmAIxAK0IQlCgS6nqQzZEGCLd9r7cg1AkQOT/RgoWB8zcaVjh3bCmgYHsoPAPgMsi3TJktg==" + } + ], + "stateHash": "7ftCvPeHIpsvSavxUoZM0u7o67MPU81ImOJIO7ZdMoH2mjnAaAAafYy9MIH3HjrWM1/Zla/Q6LsLzIjuYdYdlQ==", + "previousBlockHash": "lT0InRg4Cvk4cKykWpCRKWDZ9YNYMzuHdUzsaeTeAcH3HdfriLEcTuxrFJ76W4jrWVvTBdI1etxuIV9AO6UF4Q==", + "nonHashData": { + "localLedgerCommitTimestamp": { + "seconds": 1453758316, + "nanos": 250834782 + } + } + } + +6.2.1.2 区块链API +^^^^^^^^^^^^^^^^^ + +- **GET /chain** + +使用链API来检索区块链的当前状态。返回区块链信息消息被定义如下。 + +:: + + message BlockchainInfo { + uint64 height = 1; + bytes currentBlockHash = 2; + bytes previousBlockHash = 3; + } + +- ``height`` - 区块链中块的数量,包括创始区块 + +- ``currentBlockHash`` - 当前或最后区块的哈希 + +- ``previousBlockHash`` - 前一区块的哈希 + +区块链检索请求: + +:: + + GET host:port/chain + +区块链检索响应: + +:: + + { + "height": 174, + "currentBlockHash": "lIfbDax2NZMU3rG3cDR11OGicPLp1yebIkia33Zte9AnfqvffK6tsHRyKwsw0hZFZkCGIa9wHVkOGyFTcFxM5w==", + "previousBlockHash": "Vlz6Dv5OSy0OZpJvijrU1cmY2cNS5Ar3xX5DxAi/seaHHRPdssrljDeppDLzGx6ZVyayt8Ru6jO+E68IwMrXLQ==" + } + +6.2.1.3 链码API +^^^^^^^^^^^^^^^ + +- **POST /chaincode** + +使用链码API来部署,调用和查询链码 +部署请求需要客户端提供\ ``path``\ 参数,执行文件系统中链码的目录。部署请求的响应要么是包含成功的链码部署确认消息要么是包含失败的原因的错误。 +它还含有所生成的链码的\ ``name``\ 域在消息中,这是在随后的调用和查询交易中使用的已部署链码的唯一标识。 + +要部署链码,需要提供ChaincodeSpec的payload,在\ `3.1.2.2 <#3122-transaction-specification>`__\ 节中定义。 + +部署请求: + +:: + + POST host:port/chaincode + + { + "jsonrpc": "2.0", + "method": "deploy", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "path":"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" + }, + "ctorMsg": { + "function":"init", + "args":["a", "1000", "b", "2000"] + } + }, + "id": "1" + } + +部署响应: + +:: + + { + "jsonrpc": "2.0", + "result": { + "status": "OK", + "message": "52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" + }, + "id": 1 + } + +当启用安全时,修改所需的payload包括传递的登录用户注册ID的\ ``secureContext``\ 元素如下: + +启用安全的部署请求: + +:: + + POST host:port/chaincode + + { + "jsonrpc": "2.0", + "method": "deploy", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "path":"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" + }, + "ctorMsg": { + "function":"init", + "args":["a", "1000", "b", "2000"] + }, + "secureContext": "lukas" + }, + "id": "1" + } + +该调用请求要求客户端提供一个\ ``name``\ 参数,这是之前从部署交易响应得到的。调用请求的响应要么是包含成功执行的确认消息,要么是包含失败的原因的错误。 + +要调用链码,需要提供ChaincodeSpec的payload,在\ `3.1.2.2 <#3122-transaction-specification>`__\ 节中定义 + +调用请求: + +:: + + POST host:port/chaincode + + { + "jsonrpc": "2.0", + "method": "invoke", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" + }, + "ctorMsg": { + "function":"invoke", + "args":["a", "b", "100"] + } + }, + "id": "3" + } + +调用响应: + +:: + + { + "jsonrpc": "2.0", + "result": { + "status": "OK", + "message": "5a4540e5-902b-422d-a6ab-e70ab36a2e6d" + }, + "id": 3 + } + +当启用安全时,修改所需的payload包括传递的登录用户注册ID的\ ``secureContext``\ 元素如下: + +启用安全的调用请求: + +:: + + { + "jsonrpc": "2.0", + "method": "invoke", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" + }, + "ctorMsg": { + "function":"invoke", + "args":["a", "b", "100"] + }, + "secureContext": "lukas" + }, + "id": "3" + } + +查询请求需要在客户端提供一个\ ``name``\ 参数,这是之前在部署交易响应中得到了。查询请求的响应取决于链码的实现。响应要么是包含成功执行的确认消息,要么是包含失败的原因的错误。在成功执行的情况下,响应将包含链码请求的状态变量的值 + +要查询链码,需要提供ChaincodeSpec的payload,在\ `3.1.2.2 <#3122-transaction-specification>`__\ 节中定义。 + +查询请求: + +:: + + POST host:port/chaincode/ + + { + "jsonrpc": "2.0", + "method": "query", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" + }, + "ctorMsg": { + "function":"query", + "args":["a"] + } + }, + "id": "5" + } + +查询响应: + +:: + + { + "jsonrpc": "2.0", + "result": { + "status": "OK", + "message": "-400" + }, + "id": 5 + } + +当启用安全时,修改所需的payload包括传递的登录用户注册ID的\ ``secureContext``\ 元素如下: + +启用安全的查询请求: + +:: + + { + "jsonrpc": "2.0", + "method": "query", + "params": { + "type": "GOLANG", + "chaincodeID":{ + "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586" + }, + "ctorMsg": { + "function":"query", + "args":["a"] + }, + "secureContext": "lukas" + }, + "id": "5" + } + +6.2.1.4 网络API +^^^^^^^^^^^^^^^ + +使用网络API来获取组成区块链 fabric 的 peer 节点的网络信息 + +/network/peers 端点返回的目标 peer +节点的所有现有的网络连接的列表。该列表包括验证和非验证 peer。peer +的列表被返回类型\ ``PeersMessage``\ 是包含\ ``PeerEndpoint``\ 的数组,在第[3.1.1](#311-discovery-messages发现的消息)定义。 + +:: + + message PeersMessage { + repeated PeerEndpoint peers = 1; + } + +网络请求: + +:: + + GET host:port/network/peers + +网络响应: + +:: + + { + "peers": [ + { + "ID": { + "name": "vp1" + }, + "address": "172.17.0.4:7051", + "type": 1, + "pkiID": "rUA+vX2jVCXev6JsXDNgNBMX03IV9mHRPWo6h6SI0KLMypBJLd+JoGGlqFgi+eq/" + }, + { + "ID": { + "name": "vp3" + }, + "address": "172.17.0.5:7051", + "type": 1, + "pkiID": "OBduaZJ72gmM+B9wp3aErQlofE0ulQfXfTHh377ruJjOpsUn0MyvsJELUTHpAbHI" + }, + { + "ID": { + "name": "vp2" + }, + "address": "172.17.0.6:7051", + "type": 1, + "pkiID": "GhtP0Y+o/XVmRNXGF6pcm9KLNTfCZp+XahTBqVRmaIumJZnBpom4ACayVbg4Q/Eb" + } + ] + } + +6.2.1.5 注册API (成员服务) +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- **POST /registrar** +- **GET /registrar/{enrollmentID}** +- **DELETE /registrar/{enrollmentID}** +- **GET /registrar/{enrollmentID}/ecert** +- **GET /registrar/{enrollmentID}/tcert** + +使用注册API来管理的证书颁发机构(CA)的最终用户注册。这些API端点用于注册与CA用户,确定指定用户是否已注册,并从本地存储中删除任何目标用户的登录令牌,防止他们执行任何进一步的交易。注册API也用于从系统中检索用户注册和交易证书。 + +``/registrar``\ 端点使用与CA注册用户所需的秘密payload定义如下。注册请求的响应可以是一个成功的注册的确认或包含失败的原因的错误。 + +:: + + message Secret { + string enrollId = 1; + string enrollSecret = 2; + } + +- ``enrollId`` - 在证书颁发机构的注册ID +- ``enrollSecret`` - 在证书颁发机构的密码 + +注册请求: + +:: + + POST host:port/registrar + + { + "enrollId": "lukas", + "enrollSecret": "NPKYL39uKbkj" + } + +注册响应: + +:: + + { + "OK": "Login successful for user 'lukas'." + } + +``GET /registrar/{enrollmentID}``\ 端点用于确认一个给定的用户是否与CA注册如果是,确认将被反悔。否则,将导致授权错误。 + +注册验证请求: + +:: + + GET host:port/registrar/jim + +注册验证返回: + +:: + + { + "OK": "User jim is already logged in." + } + +注册验证请求: + +:: + + GET host:port/registrar/alex + +注册验证返回: + +:: + + { + "Error": "User alex must log in." + } + +``DELETE /registrar/{enrollmentID}`` +端点用于删除一个目标用户的登录令牌。如果登录令牌成功删除,确认将被反悔。否则,将导致授权错误。此端点不需要payload。 + +删除注册请求: + +:: + + DELETE host:port/registrar/lukas + +删除注册返回: + +:: + + { + "OK": "Deleted login token and directory for user lukas." + } + +``GET /registrar/{enrollmentID}/ecert`` +端点用于检索从本地存储给定用户的登记证书。如果目标用户已与CA注册,响应将包括注册证书的URL-encoded版本。如果目标用户尚未注册,将返回一个错误。如果客户希望使用检索后返回的注册证书,请记住,它必须是URL-decoded。 + +注册证书检索请求: + +:: + + GET host:port/registrar/jim/ecert + +注册证书检索响应: + +:: + + { + "OK": "-----BEGIN+CERTIFICATE-----%0AMIIBzTCCAVSgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwNPQkMwHhcNMTYwMTIxMDYzNjEwWhcNMTYwNDIw%0AMDYzNjEwWjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNP%0AQkMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARSLgjGD0omuJKYrJF5ClyYb3sGEGTU%0AH1mombSAOJ6GAOKEULt4L919sbSSChs0AEvTX7UDf4KNaKTrKrqo4khCoboMg1VS%0AXVTTPrJ%2BOxSJTXFZCohVgbhWh6ZZX2tfb7%2BjUDBOMA4GA1UdDwEB%2FwQEAwIHgDAM%0ABgNVHRMBAf8EAjAAMA0GA1UdDgQGBAQBAgMEMA8GA1UdIwQIMAaABAECAwQwDgYG%0AUQMEBQYHAQH%2FBAE0MAoGCCqGSM49BAMDA2cAMGQCMGz2RR0NsJOhxbo0CeVts2C5%0A%2BsAkKQ7v1Llbg78A1pyC5uBmoBvSnv5Dd0w2yOmj7QIwY%2Bn5pkLiwisxWurkHfiD%0AxizmN6vWQ8uhTd3PTdJiEEckjHKiq9pwD%2FGMt%2BWjP7zF%0A-----END+CERTIFICATE-----%0A" + } + +``/registrar/{enrollmentID}/tcert``\ 端点检索已与证书机关登记给定用户的交易证书。如果用户已注册,确认消息将包含URL-encoded交易证书的列表被返回。否则,将会导致一个错误。交易证书的所需数量由可选的'count'查询参数指定。返回交易证书的默认数量为1;500是可以与单个请求中检索证书的最大数量。如果客户端希望使用取回后的交易证书,请记住,他们必须是URL-decoded。 + +交易证书检索请求: + +:: + + GET host:port/registrar/jim/tcert + +交易证书检索响应: + +:: + + { + "OK": [ + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQfwJORRED9RAsmSl%2FEowq1STBb%0A%2FoFteymZ96RUr%2BsKmF9PNrrUNvFZFhvukxZZjqhEcGiQqFyRf%2FBnVN%2BbtRzMo38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwSRWQFmErr0SmQO9AFP4GJYzQ%0APQMmcsCjKiJf%2Bw1df%2FLnXunCsCUlf%2FalIUaeSrT7MAoGCCqGSM49BAMDA0gAMEUC%0AIQC%2FnE71FBJd0hwNTLXWmlCJff4Yi0J%2BnDi%2BYnujp%2Fn9nQIgYWg0m0QFzddyJ0%2FF%0AKzIZEJlKgZTt8ZTlGg3BBrgl7qY%3D%0A-----END+CERTIFICATE-----%0A" + ] + } + +交易证书检索请求: + +:: + + GET host:port/registrar/jim/tcert?count=5 + +交易证书检索响应: + +:: + + { + "OK": [ + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A", + "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A" + ] + } + +6.2.1.6 交易API +^^^^^^^^^^^^^^^ + +- **GET /transactions/{UUID}** + +使用交易API来从区块链中检索匹配UUID的单个交易。返回的交易消息在\ `3.1.2.1 <#3121-transaction-data-structure>`__\ 小节定义 + +交易检索请求: + +:: + + GET host:port/transactions/f5978e82-6d8c-47d1-adec-f18b794f570e + +交易检索响应: + +:: + + { + "type": 3, + "chaincodeID": "EgRteWNj", + "payload": "Ch4IARIGEgRteWNjGhIKBmludm9rZRIBYRIBYhICMTA=", + "uuid": "f5978e82-6d8c-47d1-adec-f18b794f570e", + "timestamp": { + "seconds": 1453758316, + "nanos": 206716775 + }, + "cert": "MIIB/zCCAYWgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMTI1MjE0MTE3WhcNMTYwNDI0MjE0MTE3WjArMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQ4wDAYDVQQDEwVsdWthczB2MBAGByqGSM49AgEGBSuBBAAiA2IABC/BBkt8izf6Ew8UDd62EdWFikJhyCPY5VO9Wxq9JVzt3D6nubx2jO5JdfWt49q8V1Aythia50MZEDpmKhtM6z7LHOU1RxuxdjcYDOvkNJo6pX144U4N1J8/D3A+97qZpKN/MH0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDA9BgYqAwQFBgcBAf8EMABNbPHZ0e/2EToi0H8mkouuUDwurgBYuUB+vZfeMewBre3wXG0irzMtfwHlfECRDDAKBggqhkjOPQQDAwNoADBlAjAoote5zYFv91lHzpbEwTfJL/+r+CG7oMVFUFuoSlvBSCObK2bDIbNkW4VQ+ZC9GTsCMQC5GCgy2oZdHw/x7XYzG2BiqmRkLRTiCS7vYCVJXLivU65P984HopxW0cEqeFM9co0=", + "signature": "MGUCMCIJaCT3YRsjXt4TzwfmD9hg9pxYnV13kWgf7e1hAW5Nar//05kFtpVlq83X+YtcmAIxAK0IQlCgS6nqQzZEGCLd9r7cg1AkQOT/RgoWB8zcaVjh3bCmgYHsoPAPgMsi3TJktg==" + } + +6.3 CLI +------- + +CLI包括可用的API的一个子集,使开发人员能够快速测试和调试链码或查询交易状态。CLI由Golang实现和可在多个操作系统上操作。当前可用的CLI命令归纳在下面的部分: + +6.3.1 CLI命令 +~~~~~~~~~~~~~ + +To see what CLI commands are currently available in the implementation, +execute the following: + +要查看当前可用的CLI命令,执行如下命令 + +:: + + cd $GOPATH/src/github.com/hyperledger/fabric/peer + ./peer + +你可以获得和下面类似的响应: + +:: + + Usage: + peer [command] + + Available Commands: + peer Run the peer. + status Status of the peer. + stop Stop the peer. + login Login user on CLI. + vm VM functionality on the fabric. + chaincode chaincode specific commands. + help Help about any command + + Flags: + -h, --help[=false]: help + + + Use "peer [command] --help" for more information about a command. + +Some of the available command line arguments for the ``peer`` command +are listed below: + +- ``-c`` - 构造函数: 用来为部署触发初始化链码状态的函数 + +- ``-l`` - 语言: 指定链码的实现语言,目前只支持Golang + +- ``-n`` - 名字: + 部署交易返回的链码的标识。在后续的调用和查询交易中必须使用 + +- ``-p`` - 路径: 链码在本地文件系统中的标识。在部署交易时必须提供。 + +- ``-u`` - 用户名: 调用交易的登入的用户的注册ID + +上述所有命令并非完全在当前版本中实现。如下所述全面支持的命令是有助于链码的开发和调试的。 + +所有 peer +节点的设置都被列在\ ``core.yaml``\ 这个\ ``peer``\ 处理的配置文件中,可能通过命令行的环境变量而被修改。如,设置\ ``peer.id``\ 或 +``peer.ddressAutoDetect``\ ,只需要传递\ ``CORE_PEER_ID=vp1``\ 和\ ``CORE_PEER_ADDRESSAUTODETECT=true``\ 给命令行。 + +6.3.1.1 peer +^^^^^^^^^^^^ + +``peer``\ CLI命令在开发和生产环境中都会执行 peer +处理。开发模式会在本地运行单个 peer +节点和本地的链码部署。这使得在链码开修改和调试代码,不需要启动一个完整的网络。在开发模式启动 +peer 的一个例子: + +:: + + ./peer peer --peer-chaincodedev + +在生产环境中启动peer进程,像下面一样修改上面的命令: + +:: + + ./peer peer + +6.3.1.2 登录 +^^^^^^^^^^^^ + +登录的CLI命令会登入一个已经在CA注册的用户。要通过CLI登录,发出以下命令,其中\ ``username``\ 是注册用户的注册ID。 + +:: + + ./peer login + +下面的例子演示了用户\ ``jim``\ 登录过程。 + +:: + + ./peer login jim + +该命令会提示输入密码,密码必须为此用户使用证书颁发机构注册登记的密码相匹配。如果输入的密码不正确的密码匹配,将导致一个错误。 + +:: + + 22:21:31.246 [main] login -> INFO 001 CLI client login... + 22:21:31.247 [main] login -> INFO 002 Local data store for client loginToken: /var/hyperledger/production/client/ + Enter password for user 'jim': ************ + 22:21:40.183 [main] login -> INFO 003 Logging in user 'jim' on CLI interface... + 22:21:40.623 [main] login -> INFO 004 Storing login token for user 'jim'. + 22:21:40.624 [main] login -> INFO 005 Login successful for user 'jim'. + +您也可以与\ ``-p``\ 参数来提供用户的密码。下面是一个例子。 + +:: + + ./peer login jim -p 123456 + +6.3.1.3 链码部署 +^^^^^^^^^^^^^^^^ + +``deploy``\ CLI命令为链码和接下来的部署包到验证 peer 创建 docker +镜像。如下面的例子。 + +:: + + ./peer chaincode deploy -p github.com/hyperledger/fabric/example/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' + +启用安全性时,命令必须修改来通过\ ``-u``\ 参数传递用户登录的注册ID。下面是一个例子 + +:: + + ./peer chaincode deploy -u jim -p github.com/hyperledger/fabric/example/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' + +6.3.1.4 链码调用 +^^^^^^^^^^^^^^^^ + +``invoke``\ CLI命令执行目标来代码中的指定函数。如下: + +:: + + ./peer chaincode invoke -n -c '{"Function": "invoke", "Args": ["a", "b", "10"]}' + +启用安全性时,命令必须修改来通过\ ``-u``\ 参数传递用户登录的注册ID。下面是一个例子 + +:: + + ./peer chaincode invoke -u jim -n -c '{"Function": "invoke", "Args": ["a", "b", "10"]}' + +6.3.1.5 链码查询 +^^^^^^^^^^^^^^^^ + +``query``\ CLI命令在目标链码上触发指定的查询。返回的响应取决于链码实现。下面是一个例子。 + +:: + + ./peer chaincode query -l golang -n -c '{"Function": "query", "Args": ["a"]}' + +启用安全性时,命令必须修改来通过\ ``-u``\ 参数传递用户登录的注册ID。下面是一个例子 + +:: + + ./peer chaincode query -u jim -l golang -n -c '{"Function": "query", "Args": ["a"]}' + +7. 应用模型 +----------- + +7.1 应用的组成 +~~~~~~~~~~~~~~ + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + + + +.. raw:: html + +
+ +.. raw:: html + + + +一个遵循MVC-B架构的应用– Model, View, Control, BlockChain. + +.. raw:: html + +

+ +.. raw:: html + +

+ +.. raw:: html + +

    + +.. raw:: html + +
  • + +VIEW LOGIC – 与控制逻辑集成的移动或WEB 用户界面。 + +.. raw:: html + +
  • + +.. raw:: html + +
  • + +CONTROL LOGIC – 协调用户界面、数据模型和交易与链码的API + +.. raw:: html + +
  • + +.. raw:: html + +
  • + +DATA MODEL – 应用数据模型– +管理包括文档和大文件这样的非链(off-chain)数据 + +.. raw:: html + +
  • + +.. raw:: html + +
  • + +BLOCKCHAIN LOGIC – +区块链逻辑是控制逻辑和数据模型在区块链领域的扩展,链码(chaincode)加强了控制逻辑,区块链上的交易加强了数据模型。 + +.. raw:: html + +
  • + +.. raw:: html + +
+ +.. raw:: html + +

+ +例如,使用 Node.js 的一个 Bluemix PaaS 的应用程序可能有一个 Web +前端用户界面或与 Cloudant +数据服务后端模型中的原生移动应用。控制逻辑可以被 1 +或多个链码交互以处理对区块链交易。 + +.. raw:: html + +

+ +7.2 应用样例 +~~~~~~~~~~~~ + +8. 未来发展方向 +--------------- + +8.1 企业集成 +~~~~~~~~~~~~ + +8.2 性能与可扩展性 +~~~~~~~~~~~~~~~~~~ + +8.3 附加的共识插件 +~~~~~~~~~~~~~~~~~~ + +8.4 附加的语言 +~~~~~~~~~~~~~~ + +9. References +------------- + +- [1] Miguel Castro, Barbara Liskov: Practical Byzantine fault + tolerance and proactive recovery. ACM Trans. Comput. Syst. 20(4): + 398-461 (2002) + +- [2] Christian Cachin, Rachid Guerraoui, Luís E. T. Rodrigues: + Introduction to Reliable and Secure Distributed Programming (2. ed.). + Springer 2011, ISBN 978-3-642-15259-7, pp. I-XIX, 1-367 + +- [3] Tushar Deepak Chandra, Vassos Hadzilacos, Sam Toueg: The Weakest + Failure Detector for Solving Consensus. J. ACM 43(4): 685-722 (1996) + +- [4] Cynthia Dwork, Nancy A. Lynch, Larry J. Stockmeyer: Consensus in + the presence of partial synchrony. J. ACM 35(2): 288-323 (1988) + +- [5] Manos Kapritsos, Yang Wang, Vivien Quéma, Allen Clement, Lorenzo + Alvisi, Mike Dahlin: All about Eve: Execute-Verify Replication for + Multi-Core Servers. OSDI 2012: 237-250 + +- [6] Pierre-Louis Aublin, Rachid Guerraoui, Nikola Knezevic, Vivien + Quéma, Marko Vukolic: The Next 700 BFT Protocols. ACM Trans. Comput. + Syst. 32(4): 12:1-12:45 (2015) + +- [7] Christian Cachin, Simon Schubert, Marko Vukolić: `Non-determinism + in Byzantine Fault-Tolerant + Replication `__ + +.. |Figure 5| image:: ./images/sec-request-tcerts-deployment.png +.. |Figure 6| image:: ./images/sec-request-tcerts-invocation.png +.. |Reference architecture| image:: images/refarch-api.png + diff --git a/docs/source/pythonsdk.rst b/docs/source/pythonsdk.rst new file mode 100644 index 00000000000..d20e6699ee1 --- /dev/null +++ b/docs/source/pythonsdk.rst @@ -0,0 +1,14 @@ +Python SDK +========== + +[WIP] ...coming soon + +In the meantime, refer to the `Hyperledger Fabric SDK design +doc `__ +for more details on the APIs and specifications. + +OR + +Refer to the +`fabric-sdk-py `__ +repository in the Hyperledger community. diff --git a/docs/source/quality.rst b/docs/source/quality.rst new file mode 100644 index 00000000000..590a3d0a97b --- /dev/null +++ b/docs/source/quality.rst @@ -0,0 +1,4 @@ +Quality +======= + +[WIP] ...coming soon diff --git a/docs/source/questions.rst b/docs/source/questions.rst new file mode 100644 index 00000000000..038e6c31027 --- /dev/null +++ b/docs/source/questions.rst @@ -0,0 +1,14 @@ +Still Have Questions? +===================== + +We try to maintain a comprehensive set of documentation for various +audiences. However, we realize that often there are questions that +remain unanswered. For any technical questions relating to the +Hyperledger Fabric project not answered in this documentation, please +use +`StackOverflow `__. +If you need help finding things, please don't hesitate to send a note to +the `mailing +list `__, +or ask on `RocketChat <(https://chat.hyperledger.org/)>`__ (an +alternative to Slack). diff --git a/docs/source/readwrite.rst b/docs/source/readwrite.rst new file mode 100644 index 00000000000..8635b84f781 --- /dev/null +++ b/docs/source/readwrite.rst @@ -0,0 +1,149 @@ +Read-Write set semantics +~~~~~~~~~~~~~~~~~~~~~~~~ + +This documents discusses the details of the current implementation about +the semantics of read-write sets. + +Transaction simulation and read-write set +''''''''''''''''''''''''''''''''''''''''' + +During simulation of a transaction at an ``endorser``, a read-write set +is prepared for the transaction. The ``read set`` contains a list of +unique keys and their committed versions that the transaction reads +during simulation. The ``write set`` contains a list of unique keys +(though there can be overlap with the keys present in the read set) and +their new values that the transaction writes. A delete marker is set (in +the place of new value) for the key if the update performed by the +transaction is to delete the key. + +Further, if the transaction writes a value multiple times for a key, +only the last written value is retained. Also, if a transaction reads a +value for a key, the value in the committed state is returned even if +the transaction has updated the value for the key before issuing the +read. In another words, Read-your-writes semantics are not supported. + +As noted earlier, the versions of the keys are recorded only in the read +set; the write set just contains the list of unique keys and their +latest values set by the transaction. + +There could be various schemes for implementing versions. The minimal +requirement for a versioning scheme is to produce non-repeating +identifiers for a given key. For instance, using monotonically +increasing numbers for versions can be one such scheme. In the current +implementation, we use a blockchain height based versioning scheme in +which the height of the committing transaction is used as the latest +version for all the keys modified by the transaction. In this scheme, +the height of a transaction is represented by a tuple (txNumber is the +height of the transaction within the block). This scheme has many +advantages over the incremental number scheme - primarily, it enables +other components such as statedb, transaction simulation and validation +for making efficient design choices. + +Following is an illustration of an example read-write set prepared by +simulation of a hypothetical transaction. For the sake of simplicity, in +the illustrations, we use the incremental numbers for representing the +versions. + +:: + + + + + + + + + + + + +Additionally, if the transaction performs a range query during +simulation, the range query as well as its results will be added to the +read-write set as ``query-info``. + +Transaction validation and updating world state using read-write set +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +A ``committer`` uses the read set portion of the read-write set for +checking the validity of a transaction and the write set portion of the +read-write set for updating the versions and the values of the affected +keys. + +In the validation phase, a transaction is considered ``valid`` if the +version of each key present in the read set of the transaction matches +the version for the same key in the world state - assuming all the +preceding ``valid`` transactions (including the preceding transactions +in the same block) are committed (*committed-state*). An additional +validation is performed if the read-write set also contains one or more +query-info. + +This additional validation should ensure that no key has been +inserted/deleted/updated in the super range (i.e., union of the ranges) +of the results captured in the query-info(s). In other words, if we +re-execute any of the range queries (that the transaction performed +during simulation) during validation on the committed-state, it should +yield the same results that were observed by the transaction at the time +of simulation. This check ensures that if a transaction observes phantom +items during commit, the transaction should be marked as invalid. Note +that the this phantom protection is limited to range queries (i.e., +``GetStateByRange`` function in the chaincode) and not yet implemented +for other queries (i.e., ``GetQueryResult`` function in the chaincode). +Other queries are at risk of phantoms, and should therefore only be used +in read-only transactions that are not submitted to ordering, unless the +application can guarantee the stability of the result set between +simulation and validation/commit time. + +If a transaction passes the validity check, the committer uses the write +set for updating the world state. In the update phase, for each key +present in the write set, the value in the world state for the same key +is set to the value as specified in the write set. Further, the version +of the key in the world state is changed to reflect the latest version. + +Example simulation and validation +''''''''''''''''''''''''''''''''' + +This section helps with understanding the semantics through an example +scenario. For the purpose of this example, the presence of a key, ``k``, +in the world state is represented by a tuple ``(k,ver,val)`` where +``ver`` is the latest version of the key ``k`` having ``val`` as its +value. + +Now, consider a set of five transactions ``T1, T2, T3, T4, and T5``, all +simulated on the same snapshot of the world state. The following snippet +shows the snapshot of the world state against which the transactions are +simulated and the sequence of read and write activities performed by +each of these transactions. + +:: + + World state: (k1,1,v1), (k2,1,v2), (k3,1,v3), (k4,1,v4), (k5,1,v5) + T1 -> Write(k1, v1'), Write(k2, v2') + T2 -> Read(k1), Write(k3, v3') + T3 -> Write(k2, v2'') + T4 -> Write(k2, v2'''), read(k2) + T5 -> Write(k6, v6'), read(k5) + +Now, assume that these transactions are ordered in the sequence of +T1,..,T5 (could be contained in a single block or different blocks) + +1. ``T1`` passes validation because it does not perform any read. + Further, the tuple of keys ``k1`` and ``k2`` in the world state are + updated to ``(k1,2,v1'), (k2,2,v2')`` + +2. ``T2`` fails validation because it reads a key, ``k1``, which was + modified by a preceding transaction - ``T1`` + +3. ``T3`` passes the validation because it does not perform a read. + Further the tuple of the key, ``k2``, in the world state is updated + to ``(k2,3,v2'')`` + +4. ``T4`` fails the validation because it reads a key, ``k2``, which was + modified by a preceding transaction ``T1`` + +5. ``T5`` passes validation because it reads a key, ``k5,`` which was + not modified by any of the preceding transactions + +**Note**: Transactions with multiple read-write sets are not yet supported. diff --git a/docs/source/releases.rst b/docs/source/releases.rst new file mode 100644 index 00000000000..1db3ce00a31 --- /dev/null +++ b/docs/source/releases.rst @@ -0,0 +1,63 @@ +`v0.6-preview `__ +September 16, 2016 + +A developer preview release of the Hyperledger Fabric intended to +exercise the release logistics and stabilize a set of capabilities for +developers to try out. This will be the last release under the original +architecture. All subsequent releases will deliver on the `v1.0 +architecture `__. + +Key enhancements: + +- 8de58ed - NodeSDK doc changes -- FAB-146 +- 62d866d - Add flow control to SYNC\_STATE\_SNAPSHOT +- 4d97069 - Adding TLS changes to SDK +- e9d3ac2 - Node-SDK: add support for fabric events(block, chaincode, + transactional) +- 7ed9533 - Allow deploying Java chaincode from remote git repositories +- 4bf9b93 - Move Docker-Compose files into their own folder +- ce9fcdc - Print ChaincodeName when deploy with CLI +- 4fa1360 - Upgrade go protobuf from 3-beta to 3 +- 4b13232 - Table implementation in java shim with example +- df741bc - Add support for dynamically registering a user with + attributes +- 4203ea8 - Check for duplicates when adding peers to the chain +- 518f3c9 - Update docker openjdk image +- 47053cd - Add GetTxID function to Stub interface (FAB-306) +- ac182fa - Remove deprecated devops REST API +- ad4645d - Support hyperledger fabric build on ppc64le platform +- 21a4a8a - SDK now properly adding a peer with an invalid URL +- 1d8114f - Fix setting of watermark on restore from crash +- a98c59a - Upgrade go protobuff from 3-beta to 3 +- 937039c - DEVENV: Provide strong feedback when provisioning fails +- d74b1c5 - Make pbft broadcast timeout configurable +- 97ed71f - Java shim/chaincode project reorg, separate java docker env +- a76dd3d - Start container with HostConfig was deprecated since v1.10 + and removed since v1.12 +- 8b63a26 - Add ability to unregister for events +- 3f5b2fa - Add automatic peer command detection +- 6daedfd - Re-enable sending of chaincode events +- b39c93a - Update Cobra and pflag vendor libraries +- dad7a9d - Reassign port numbers to 7050-7060 range + +`v0.5-developer-preview `__ +June 17, 2016 + +A developer preview release of the Hyperledger Fabric intended to +exercise the release logistics and stabilize a set of capabilities for +developers to try out. + +Key features: + +Permissioned blockchain with immediate finality Chaincode (aka smart +contract) execution environments Docker container (user chaincode) +In-process with peer (system chaincode) Pluggable consensus with PBFT, +NOOPS (development mode), SIEVE (prototype) Event framework supports +pre-defined and custom events Client SDK (Node.js), basic REST APIs and +CLIs Known Key Bugs and work in progress + +- 1895 - Client SDK interfaces may crash if wrong parameter specified +- 1901 - Slow response after a few hours of stress testing +- 1911 - Missing peer event listener on the client SDK +- 889 - The attributes in the TCert are not encrypted. This work is + still on-going diff --git a/docs/source/requirements.txt b/docs/source/requirements.txt new file mode 100644 index 00000000000..da829ff4f2d --- /dev/null +++ b/docs/source/requirements.txt @@ -0,0 +1 @@ +python-markdown-math==0.2 diff --git a/docs/source/sampleapp.rst b/docs/source/sampleapp.rst new file mode 100644 index 00000000000..89b097dc67d --- /dev/null +++ b/docs/source/sampleapp.rst @@ -0,0 +1,7 @@ +Sample Application +================== + +[WIP] ...coming soon + +In the meantime, refer to the `Asset transfer through +SDK `__ topic. diff --git a/docs/source/security_model.rst b/docs/source/security_model.rst new file mode 100644 index 00000000000..abd0ded1a77 --- /dev/null +++ b/docs/source/security_model.rst @@ -0,0 +1,16 @@ +Security Model +============== + +[WIP] + +Hyperledger Fabric allows for different organizations and participants +in a common network to utilize their own certificate authority, and as a +byproduct, implement varying cryptographic algorithms for +signing/verifying/identity attestation. This is done through an MSP +process running on both the ordering service and channel levels. + +Membership service provider (MSP): A set of cryptographic mechanisms and +protocols for issuing and validating certificates and identities +throughout the blockchain network. Identities issued in the scope of a +membership service provider can be evaluated within that membership +service provider’s rules validation policies. diff --git a/docs/source/smartcontract.rst b/docs/source/smartcontract.rst new file mode 100644 index 00000000000..4a7c20f7a8e --- /dev/null +++ b/docs/source/smartcontract.rst @@ -0,0 +1,15 @@ +Chaincode +========= + +[WIP] + +The widely-used term, smart contract, is referred to as "chaincode" in +Hyperledger Fabric. + +Self-executing logic that encodes the rules for specific types of +network transactions. Chaincode (currently written in Go or Java) is +installed and instantiated onto a channel's peers by an appropriately +authorized member. End users then invoke chaincode through a client-side +application that interfaces with a network peer. Chaincode runs network +transactions, which if validated, are appended to the shared ledger and +modify world state. diff --git a/docs/source/starter/fabric-starter-kit.rst b/docs/source/starter/fabric-starter-kit.rst new file mode 100644 index 00000000000..244a3ef1d00 --- /dev/null +++ b/docs/source/starter/fabric-starter-kit.rst @@ -0,0 +1,7 @@ +Fabric Starter Kit +================== + +**Coming soon for v1.0** + +If you are looking for the v0.6 Starter Kit, you can find it +`here `__. diff --git a/docs/source/tech/application-ACL.rst b/docs/source/tech/application-ACL.rst new file mode 100644 index 00000000000..1a0c1c2e52e --- /dev/null +++ b/docs/source/tech/application-ACL.rst @@ -0,0 +1,201 @@ +Hyperledger Fabric - Application Access Control Lists +===================================================== + +Overview +-------- + +We consider the following entities: + +1. *HelloWorld*: is a chaincode that contains a single function called + *hello*; +2. *Alice*: is the *HelloWorld* deployer; +3. *Bob*: is the *HelloWorld*'s functions invoker. + +Alice wants to ensure that only Bob can invoke the function *hello*. + +Fabric Support +-------------- + +To allow Alice to specify her own access control lists and Bob to gain +access, the fabric layer gives access to following capabilities: + +1. Alice and Bob can sign and verify any message with specific + transaction certificates or enrollment certificate they own; +2. The fabric allows to *name* each transaction by means of a unique + *binding* to be used to bind application data to the underlying + transaction transporting it; +3. Extended transaction format. + +The fabric layer exposes the following interfaces and functions to allow +the application layer to define its own ACLS. + +Certificate Handler +~~~~~~~~~~~~~~~~~~~ + +The following interface allows to sign and verify any message using +signing key-pair underlying the associated certificate. The certificate +can be a TCert or an ECert. + +:: + + // CertificateHandler exposes methods to deal with an ECert/TCert + type CertificateHandler interface { + + // GetCertificate returns the certificate's DER + GetCertificate() []byte + + // Sign signs msg using the signing key corresponding to the certificate + Sign(msg []byte) ([]byte, error) + + // Verify verifies msg using the verifying key corresponding to the certificate + Verify(signature []byte, msg []byte) error + + // GetTransactionHandler returns a new transaction handler relative to this certificate + GetTransactionHandler() (TransactionHandler, error) + } + +Transaction Handler +~~~~~~~~~~~~~~~~~~~ + +The following interface allows to create transactions and give access to +the underlying *binding* that can be leveraged to link application data +to the underlying transaction. + +:: + + // TransactionHandler represents a single transaction that can be named by the output of the GetBinding method. + // This transaction is linked to a single Certificate (TCert or ECert). + type TransactionHandler interface { + + // GetCertificateHandler returns the certificate handler relative to the certificate mapped to this transaction + GetCertificateHandler() (CertificateHandler, error) + + // GetBinding returns a binding to the underlying transaction + GetBinding() ([]byte, error) + + // NewChaincodeDeployTransaction is used to deploy chaincode + NewChaincodeDeployTransaction(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string) (*obc.Transaction, error) + + // NewChaincodeExecute is used to execute chaincode's functions + NewChaincodeExecute(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) + + // NewChaincodeQuery is used to query chaincode's functions + NewChaincodeQuery(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) + } + +Client +~~~~~~ + +The following interface offers a mean to get instances of the previous +interfaces. + +:: + + type Client interface { + + ... + + // GetEnrollmentCertHandler returns a CertificateHandler whose certificate is the enrollment certificate + GetEnrollmentCertificateHandler() (CertificateHandler, error) + + // GetTCertHandlerNext returns a CertificateHandler whose certificate is the next available TCert + GetTCertificateHandlerNext() (CertificateHandler, error) + + // GetTCertHandlerFromDER returns a CertificateHandler whose certificate is the one passed + GetTCertificateHandlerFromDER(der []byte) (CertificateHandler, error) + + } + +Transaction Format +~~~~~~~~~~~~~~~~~~ + +To support application-level ACLs, the fabric's transaction and +chaincode specification format have an additional field to store +application-specific metadata. The content of this field is decided by +the application. The fabric layer treats it as an unstructured stream of +bytes. + +:: + + + message ChaincodeSpec { + + ... + + ConfidentialityLevel confidentialityLevel; + bytes metadata; + + ... + } + + + message Transaction { + ... + + bytes payload; + bytes metadata; + + ... + } + +Another way to achieve this is to have the payload contain the metadata +itself. + +Validators +~~~~~~~~~~ + +To assist chaincode execution, the validators provide the chaincode +additional information, such as the metadata and the binding. + +Application-level access control +-------------------------------- + +Deploy Transaction +~~~~~~~~~~~~~~~~~~ + +Alice has full control over the deployment transaction's metadata. In +particular, the metadata can be used to store a list of ACLs (one per +function), or a list of roles. To define each of these lists/roles, +Alice can use any TCerts/ECerts of the users who have been granted that +(access control) privilege or have been assigned that role. The latter +is done offline. + +Now, Alice requires that in order to invoke the *hello* function, a +certain message *M* has to be authenticated by an authorized invoker +(Bob, in our case). We distinguish the following two cases: + +1. *M* is one of the chaincode's function arguments; +2. *M* is the invocation message itself, i.e., function-name, arguments. + +Execute Transaction +~~~~~~~~~~~~~~~~~~~ + +To invoke *hello*, Bob needs to sign *M* using the TCert/ECert Alice has +used to name him in the deployment transaction's metadata. Let's call +this certificate CertBob. At this point Bob does the following: + +1. Bob obtains a *CertificateHandler* for CertBob, *cHandlerBob*; +2. Bob obtains a new *TransactionHandler* to issue the execute + transaction, *txHandler* relative to his next available TCert or his + ECert; +3. Bob obtains *txHandler*'s *binding* by invoking + *txHandler.getBinding()*; +4. Bob signs *'M \|\| txBinding'* by invoking *cHandlerBob.Sign('M \|\| + txBinding')*, let *signature* be the output of the signing function; +5. Bob issues a new execute transaction by invoking, + *txHandler.NewChaincodeExecute(...)*. Now, *signature* can be + included in the transaction as one of the argument to be passed to + the function or as transaction metadata. + +Chaincode Execution +~~~~~~~~~~~~~~~~~~~ + +The validators, who receive the execute transaction issued by Bob, will +provide to *hello* the following information: + +1. The *binding* of the execute transaction; +2. The *metadata* of the execute transaction; +3. The *metadata* of the deploy transaction. + +Then, *hello* is responsible for checking that *signature* is indeed a +valid signature issued by Bob. diff --git a/docs/source/tech/attributes.rst b/docs/source/tech/attributes.rst new file mode 100644 index 00000000000..f8fa01922dc --- /dev/null +++ b/docs/source/tech/attributes.rst @@ -0,0 +1,228 @@ +Attributes support +================== + +To support attributes the user has to pass them during TCert creation, +these attributes can be used during transaction deployment, execution or +query for Attribute Based Access Control (ABAC) to determine whether the +user can or cannot execute a specific chaincode or used attributes' +values for other purposes. A mechanism to validate the ownership of +attributes is required in order to prove if the attributes passed by the +user are correct. The Attribute Certificate Authority (ACA) has the +responsibility of validate attributes and to return an Attribute +Certificate (ACert) with the valid attribute values. Attributes values +are encrypted using the keys defined below (section Attributes keys). + +Attribute Keys +-------------- + +The attributes are encrypted using a key derived from a hierarchy called +PreKey tree. This approach consists in deriving keys from a parent key, +allowing the parent key owner, get access to derived keys. This way keys +used to encrypt attributes are different among attributes and TCerts +avoiding linkability while allowing an authorized auditor who owns a +parent key to derive the keys in the lower levels. + +Example of prekey tree +~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Pre3K_BI + |_Pre2K_B = HMAC(Pre3K_BI, “banks”) + | |_Pre1K_BankA = HMAC(Pre2K_B, “Bank A”) + | | |_Pre0K_BankA = HMAC(Pre1K_BankA, TCertID) + | | |_PositionKey_BankA_TIdx = HMAC(Pre0K_BankA, "position") + | | |_CompanyKey_BankA_TIdx = HMAC(Pre0K_BankA, "company") + | | + | |_Pre1K_BankB = HMAC(Pre2K_B, “BanKB”) + | |_Pre0K_BankB = HMAC(Pre1K_BankB, TCertID) + | |_PositionKey_BankB_TIdx = HMAC(Pre0K_BankB, "position") + | |_CompanyKey_BankB_TIdx = HMAC(Pre0K_BankB, "company") + | + |_Pre2K_I = HMAC(Pre3K_BI, "institutions") + |_Pre1K_InstitutionA= HMAC(Pre2K_I, "Institution A”) + |_Pre0K_InstitutionA = HMAC(_Pre1K_InstitutionA, TCertID) + |_PositionKey_InstA_TIdx = HMAC(Pre0K_InstitutionA, "position") + |_CompanyKey_InstA_TIdx = HMAC(Pre0K_InstitutionA, "company") + +- Pre3K\_BI: is available to TCA and auditors for banks and + institutions. +- Pre2K\_B: is available to auditors for banks +- Pre1K\_BankA: is available to auditors for Bank A. +- Pre1K\_BankB: is available to auditors for Bank B. +- Pre2K\_I: is available to auditors for institutions. +- Pre1K\_InstitutionA: is available to auditors for Institution A. + +Each TCert has a different PreK0 (for example Pre0K\_BankA) and each +TCert attribute has a different attribute key (for example +PositionKey\_BankA\_TIdx). + +Attribute Certificate Authority +------------------------------- + +Attribute Certificate Authority (ACA) has the responsibility of certify +the ownership of the attributes. ACA has a database to hold attributes +for each user and affiliation. + +1. id: The id passed by the user during enrollment +2. affiliation: The entity which the user is affiliated to +3. attributeName: The name used to look for the attribute, e.g. + 'position' +4. attributeValue: The value of the attribute, e.g. 'software engineer' +5. validFrom: The start of the attribute's validity period +6. validTo: The end of the attribute's validity period + +gRPC ACA API +~~~~~~~~~~~~ + +1. FetchAttributes + +:: + + rpc FetchAttributes(ACAFetchAttrReq) returns (ACAFetchAttrResp); + + message ACAFetchAttrReq { + google.protobuf.Timestamp ts = 1; + Cert eCert = 2; // ECert of involved user. + Signature signature = 3; // Signed using the ECA private key. + } + + message ACAFetchAttrResp { + enum StatusCode { + SUCCESS = 000; + FAILURE = 100; + } + StatusCode status = 1; + } + +2. RequestAttributes + +:: + + rpc RequestAttributes(ACAAttrReq) returns (ACAAttrResp); + + message ACAAttrReq { + google.protobuf.Timestamp ts = 1; + Identity id = 2; + Cert eCert = 3; // ECert of involved user. + repeated TCertAttributeHash attributes = 4; // Pairs attribute-key, attribute-value-hash + Signature signature = 5; // Signed using the TCA private key. + } + + message ACAAttrResp { + enum StatusCode { + FULL_SUCCESSFUL = 000; + PARTIAL_SUCCESSFUL = 001; + NO_ATTRIBUTES_FOUND = 010; + FAILURE = 100; + } + StatusCode status = 1; + Cert cert = 2; // ACert with the owned attributes. + Signature signature = 3; // Signed using the ACA private key. + } + +3. RefreshAttributes + +:: + + rpc RefreshAttributes(ACARefreshReq) returns (ACARefreshResp); + + message ACARefreshAttrReq { + google.protobuf.Timestamp ts = 1; + Cert eCert = 2; // ECert of the involved user. + Signature signature = 3; // Signed using enrollPrivKey + } + + message ACARefreshAttrResp { + enum StatusCode { + SUCCESS = 000; + FAILURE = 100; + } + StatusCode status = 1; + } + +FLOW +---- + +.. figure:: ../images/attributes_flow.png + :alt: ACA flow + + ACA flow + +During enrollment +~~~~~~~~~~~~~~~~~ + +1. The user requests an Enrollment Certificate (ECert) to ECA +2. ECA creates the ECert and responds to the user with it. +3. ECA issues a fetch request under TLS to the ACA passing the newly + generated ECert as a parameter. This request is signed with the ECA's + private key. +4. The request triggers ACA asynchronous mechanism that fetches + attributes' values from external sources and populates the attributes + database (in the current implementation attributes are loaded from an + internal configuration file). + +During TCert generation +~~~~~~~~~~~~~~~~~~~~~~~ + +1. When the user needs TCerts to create a new transaction it requests a + batch of TCerts to the TCA, and provides the following: + +- The batch size (i.e. how many TCerts the user is expecting) +- Its ECert +- A list of attributes (e.g. Company, Position) + +2. Under TLS TCA sends a RequestAttributes() to ACA to verify if the + user is in possession of those attributes. This request is signed + with TCA's private key and it contains: + +- User's ECert +- A list of attribute names "company, position, ..." + +3. The ACA performs a query to the internal attributes database and + there are three possible scenarios\*\*\*: + + a. The user does not have any of the specified attributes – An error + is returned. + b. The user has all the specified attributes – An X.509 certificate + (ACert) with all the specified attributes and the ECert public key + is returned. + c. The user has a subset of the requested attributes – An X.509 + certificate (ACert) with just the subset of the specified + attributes and the ECert public key is returned. + +4. The TCA checks the validity period of the ACert's attributes and + updates the list by eliminating those that are expired. Then for + scenarios b and c from the previous item it checks how many (and + which ones) of the attributes the user will actually receive inside + each TCert. This information needs to be returned to the user in + order to decide whether the TCerts are useful or if further actions + needs to be performed (i.e. issue a RefreshAttributes command and + request a new batch, throw an error or make use of the TCerts as they + are). +5. The TCA could have other criteria to update the valid list of + attributes. +6. The TCA creates the batch of TCerts. Each TCert contains the valid + attributes encrypted with keys derived from the Prekey tree (each key + is unique per attribute, per TCert and per user). +7. The TCA returns the batch of TCerts to the user along with a root key + (Prek0) from which each attribute encryption key was derived. There + is a Prek0 per TCert. All the TCerts in the batch have the same + attributes and the validity period of the TCerts is the same for the + entire batch. + +\*\*\* *In the current implementation an attributes refresh is executed +automatically before this step, but once the refresh service is +implemented the user will have the responsibility of keeping his/her +attributes updated by invoking this method.* + +Assumptions +~~~~~~~~~~~ + +1. An Attribute Certificate Authority (ACA) has been incorporated to the + Membership Services internally to provide a trusted source for + attribute values. +2. In the current implementation attributes are loaded from a + configuration file (membersrvc.yml). +3. Refresh attributes service is not implemented yet, instead, + attributes are refreshed in each RequestAttribute invocation. diff --git a/docs/source/tech/best-practices.rst b/docs/source/tech/best-practices.rst new file mode 100644 index 00000000000..be05368acaa --- /dev/null +++ b/docs/source/tech/best-practices.rst @@ -0,0 +1,4 @@ +Hyperledger Fabric Development Best Practices +--------------------------------------------- + +(This page is under construction.) diff --git a/docs/source/testing.rst b/docs/source/testing.rst new file mode 100644 index 00000000000..9b7b95b3382 --- /dev/null +++ b/docs/source/testing.rst @@ -0,0 +1,7 @@ +Testing +======= + +[WIP] ...coming soon + +This topic is intended to contain recommended test scenarios, as well as +current performance numbers against a variety of configurations. diff --git a/docs/source/troubleshooting.rst b/docs/source/troubleshooting.rst new file mode 100644 index 00000000000..c3b2f00b5a4 --- /dev/null +++ b/docs/source/troubleshooting.rst @@ -0,0 +1,7 @@ +Troubleshooting +=============== + +[WIP] ...coming soon + +This topic is intended to solve high level bugs and then direct users to +more granular FAQ topics based on their errors. diff --git a/docs/source/txflow.rst b/docs/source/txflow.rst new file mode 100644 index 00000000000..f68278aa5d7 --- /dev/null +++ b/docs/source/txflow.rst @@ -0,0 +1,106 @@ +Transaction Flow +================ + +This document outlines the transactional mechanics that take place during a standard asset +exchange. The scenario includes two clients, A and B, who are buying and selling +radishes. They each have a peer on the network through which they send their +transactions and interact with the ledger. + +.. image:: images/step0.png + +**Assumptions** + +This flow assumes that a channel is set up and running. The application user +has registered and enrolled with the organization’s certificate authority (CA) +and received back necessary cryptographic material, which is used to authenticate +to the network. + +The chaincode (containing a set of key value pairs representing the initial +state of the radish market) is installed on the peers and instantiated on the +channel. The chaincode contains logic defining a set of transaction +instructions and the agreed upon price for a radish. An endorsement policy has +also been set for this chaincode, stating that both ``peerA`` and ``peerB`` must endorse +any transaction. + +.. image:: images/step1.png + +1. **Client A initiates a transaction** + +What's happening? - Client A is sending a request to purchase radishes. The +request targets ``peerA`` and ``peerB``, who are respectively representative of +Client A and Client B. The endorsement policy states that both peers must endorse +any transaction, therefore the request goes to ``peerA`` and ``peerB``. + +Next, the transaction proposal is constructed. An application leveraging a supported +SDK (node, java, python) utilizes one of the available API's which generates a +transaction proposal. The proposal is a request to invoke a chaincode function +so that data can be read and/or written to the ledger (i.e. write new key value +pairs for the assets). The SDK serves as a shim to package the transaction proposal +into the properly architected format (protocol buffer over gRPC) and takes the user’s +cryptographic credentials to produce a unique signature for this transaction proposal. + +.. image:: images/step2.png + +2. **Endorsing peers verify signature & execute the transaction** + +The endorsing peers verify the signature (using MSP) and determine if the +submitter is properly authorized to perform the proposed operation (using the +channel's ACL). The endorsing peers take the transaction proposal arguments as +inputs and execute them against the current state database to produce transaction +results including a response value, read set, and write set. No updates are +made to the ledger at this point. The set of these values, along with the +endorsing peer’s signature and a YES/NO endorsement statement is passed back as +a “proposal response” to the SDK which parses the payload for the application to +consume. + +*{The MSP is a local process running on the peers which allows them to verify +transaction requests arriving from clients and to sign transaction results(endorsements). +The ACL (Access Control List) is defined at channel creation time, and determines +which peers and end users are permitted to perform certain actions.}* + + +.. image:: images/step3.png + +3. **Proposal responses are inspected** + +The application verifies the endorsing peer signatures and compares the proposal +responses (link to glossary term which will contain a representation of the payload) +to determine if the proposal responses are the same and if the specified endorsement +policy has been fulfilled (i.e. did peerA and peerB both endorse). The architecture +is such that even if an application chooses not to inspect responses or otherwise +forwards an unendorsed transaction, the policy will still be enforced by peers +and upheld at the commit validation phase. + +.. image:: images/step4.png + +4. **Client assembles endorsements into a transaction** + +The application “broadcasts” the transaction proposal and response within a +“transaction message” to the Ordering Service. The transaction will contain the +read/write sets, the endorsing peers signatures and the Channel ID. The +Ordering Service does not read the transaction details, it simply receives +transactions from all channels in the network, orders them chronologically by +channel, and creates blocks of transactions per channel. + +.. image:: images/step5.png + +5. **Transaction is validated and committed** + +The blocks of transactions are “delivered” to all peers on the channel. The +transactions within the block are validated to ensure endorsement policy is +fulfilled and to ensure that there have been no changes to ledger state for read +set variables since the read set was generated by the transaction execution. +Transactions in the block are tagged as being valid or invalid. + +.. image:: images/step6.png + +6. **Ledger updated** + +Each peer appends the block to the channel’s chain, and for each valid transaction +the write sets are committed to current state database. An event is emitted, to +notify the client application that the transaction (invocation) has been +immutably appended to the chain, as well as notification of whether the +transaction was validated or invalidated. + +**Note**: See the :ref:`swimlane` diagram to better understand the server side flow and the +protobuffers. diff --git a/docs/source/videos.rst b/docs/source/videos.rst new file mode 100644 index 00000000000..d81168a85df --- /dev/null +++ b/docs/source/videos.rst @@ -0,0 +1,8 @@ +Videos +====== + +Refer to the Hyperledger Fabric libary on +`youtube `__. +The collection contains developers demonstrating various v1 features and +components such as: ledger, channels, gossip, SDK, chaincode, MSP, and +more... diff --git a/docs/source/whyfabric.rst b/docs/source/whyfabric.rst new file mode 100644 index 00000000000..877303ff43d --- /dev/null +++ b/docs/source/whyfabric.rst @@ -0,0 +1,52 @@ +Why Hyperledger Fabric? +======================= + +The Hyperledger Fabric project is delivering a blockchain platform +designed to allow the exchange of an asset or the state of an asset to +be consented upon, maintained, and viewed by all parties in a +permissioned group. A key characteristic of Hyperledger Fabric is that +the asset is defined digitally, with all participants simply agreeing on +its representation/characterization. As such, Hyperledger Fabric can +support a broad range of asset types; ranging from the tangible (real +estate and hardware) to the intangible (contracts and intellectual +property). + +The technology is based on a standard blockchain concept - a shared, +replicated ledger. However, Hyperledger Fabric is based on a +`permissioned network `__, meaning all +participants are required to be authenticated in order to participate +and transact on the blockchain. Moreover, these identities can be used +to govern certain levels of access control (e.g. this user can read the +ledger, but cannot exchange or transfer assets). This dependence on +identity is a great advantage in that varying consensus algorithms (e.g. +byzantine or crash fault tolerant) can be implemented in place of the +more compute-intensive Proof-of-Work and Proof-of-Stake varieties. As a +result, permissioned networks tend to provide higher transaction +throughput rates and performance. + +Once an organization is granted access to the `blockchain +network `__, it then has the ability to +create and maintain a private `channel `__ with +other specified members. For example, let's assume there are four +organizations trading jewels. They may decide to use Hyperledger Fabric +because they trust each other, but not to an unconditional extent. They +can all agree on the business logic for trading the jewels, and can all +maintain a global ledger to view the current state of their jewel market +(call this the consortium channel). Additionally, two or more of these +organizations might decide to form an alternate private blockchain for a +certain exchange that they want to keep confidential (e.g. price X for +quantity Y of asset Z). They can perform this trade without affecting +their broader consortium channel, or, if desired, this private channel +can broadcast some level of reference data to their consortium channel. + +This is powerful! This provides for great flexibility and potent +capabilities, along with the interoperability of multiple blockchain +ledgers within one consortium. This is the first of its kind and allows +organizations to curate Hyperledger Fabric to support the myriad use +cases for different businesses and industries. Hyperledger Fabric has +already been successfully implemented in the banking, finance, and +retail industries. + +We welcome you to the Hyperledger Fabric community and are keen to learn +of your architectural and business requirements, and help determine how +Hyperledger Fabric can be leveraged to support your use cases. diff --git a/docs/wiki-images/sdk-current.png b/docs/source/wiki-images/sdk-current.png similarity index 100% rename from docs/wiki-images/sdk-current.png rename to docs/source/wiki-images/sdk-current.png diff --git a/docs/wiki-images/sdk-future.png b/docs/source/wiki-images/sdk-future.png similarity index 100% rename from docs/wiki-images/sdk-future.png rename to docs/source/wiki-images/sdk-future.png diff --git a/docs/starter/fabric-starter-kit.md b/docs/starter/fabric-starter-kit.md deleted file mode 100755 index 573eedd8769..00000000000 --- a/docs/starter/fabric-starter-kit.md +++ /dev/null @@ -1,6 +0,0 @@ -# Fabric Starter Kit - -**Coming soon for v1.0** - -If you are looking for the v0.6 Starter Kit, you can find it -[here](http://hyperledger-fabric.readthedocs.io/en/v0.6/starter/fabric-starter-kit/). diff --git a/docs/tech/application-ACL.md b/docs/tech/application-ACL.md deleted file mode 100644 index 3ef059e8d13..00000000000 --- a/docs/tech/application-ACL.md +++ /dev/null @@ -1,167 +0,0 @@ -# Hyperledger Fabric - Application Access Control Lists - -## Overview - -We consider the following entities: - -1. *HelloWorld*: is a chaincode that contains a single function called *hello*; -2. *Alice*: is the *HelloWorld* deployer; -3. *Bob*: is the *HelloWorld*'s functions invoker. - -Alice wants to ensure that only Bob can invoke the function *hello*. - -## Fabric Support - -To allow Alice to specify her own access control lists and Bob to gain access, the fabric layer gives access to following capabilities: - -1. Alice and Bob can sign and verify any message with specific transaction certificates or enrollment certificate they own; -2. The fabric allows to *name* each transaction by means of a unique *binding* to be used to bind application data -to the underlying transaction transporting it; -3. Extended transaction format. - -The fabric layer exposes the following interfaces and functions to allow the application layer to define its own ACLS. - -### Certificate Handler - -The following interface allows to sign and verify any message using signing key-pair underlying the associated certificate. -The certificate can be a TCert or an ECert. - -``` -// CertificateHandler exposes methods to deal with an ECert/TCert -type CertificateHandler interface { - - // GetCertificate returns the certificate's DER - GetCertificate() []byte - - // Sign signs msg using the signing key corresponding to the certificate - Sign(msg []byte) ([]byte, error) - - // Verify verifies msg using the verifying key corresponding to the certificate - Verify(signature []byte, msg []byte) error - - // GetTransactionHandler returns a new transaction handler relative to this certificate - GetTransactionHandler() (TransactionHandler, error) -} -``` - - -### Transaction Handler - -The following interface allows to create transactions and give access to the underlying *binding* that can be leveraged to link -application data to the underlying transaction. - - -``` -// TransactionHandler represents a single transaction that can be named by the output of the GetBinding method. -// This transaction is linked to a single Certificate (TCert or ECert). -type TransactionHandler interface { - - // GetCertificateHandler returns the certificate handler relative to the certificate mapped to this transaction - GetCertificateHandler() (CertificateHandler, error) - - // GetBinding returns a binding to the underlying transaction - GetBinding() ([]byte, error) - - // NewChaincodeDeployTransaction is used to deploy chaincode - NewChaincodeDeployTransaction(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string) (*obc.Transaction, error) - - // NewChaincodeExecute is used to execute chaincode's functions - NewChaincodeExecute(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) - - // NewChaincodeQuery is used to query chaincode's functions - NewChaincodeQuery(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error) -} -``` - -### Client - -The following interface offers a mean to get instances of the previous interfaces. - -``` -type Client interface { - - ... - - // GetEnrollmentCertHandler returns a CertificateHandler whose certificate is the enrollment certificate - GetEnrollmentCertificateHandler() (CertificateHandler, error) - - // GetTCertHandlerNext returns a CertificateHandler whose certificate is the next available TCert - GetTCertificateHandlerNext() (CertificateHandler, error) - - // GetTCertHandlerFromDER returns a CertificateHandler whose certificate is the one passed - GetTCertificateHandlerFromDER(der []byte) (CertificateHandler, error) - -} -``` - -### Transaction Format - -To support application-level ACLs, the fabric's transaction and chaincode specification format have an additional field to store application-specific metadata. -The content of this field is decided by the application. The fabric layer treats it as an unstructured stream of bytes. - - -``` - -message ChaincodeSpec { - - ... - - ConfidentialityLevel confidentialityLevel; - bytes metadata; - - ... -} - - -message Transaction { - ... - - bytes payload; - bytes metadata; - - ... -} -``` - -Another way to achieve this is to have the payload contain the metadata itself. - -### Validators - -To assist chaincode execution, the validators provide the chaincode additional information, such as the metadata and the binding. - -## Application-level access control - -### Deploy Transaction - -Alice has full control over the deployment transaction's metadata. -In particular, the metadata can be used to store a list of ACLs (one per function), or a list of roles. -To define each of these lists/roles, Alice can use any TCerts/ECerts of the users who have been -granted that (access control) privilege or have been assigned that role. The latter is done offline. - -Now, Alice requires that in order to invoke the *hello* function, a certain message *M* has to be authenticated by an authorized invoker (Bob, in our case). -We distinguish the following two cases: - -1. *M* is one of the chaincode's function arguments; -2. *M* is the invocation message itself, i.e., function-name, arguments. - -### Execute Transaction - -To invoke *hello*, Bob needs to sign *M* using the TCert/ECert Alice has used to name him in the deployment transaction's metadata. -Let's call this certificate CertBob. At this point Bob does the following: - -1. Bob obtains a *CertificateHandler* for CertBob, *cHandlerBob*; -2. Bob obtains a new *TransactionHandler* to issue the execute transaction, *txHandler* relative to his next available TCert or his ECert; -3. Bob obtains *txHandler*'s *binding* by invoking *txHandler.getBinding()*; -4. Bob signs *'M || txBinding'* by invoking *cHandlerBob.Sign('M || txBinding')*, let *signature* be the output of the signing function; -5. Bob issues a new execute transaction by invoking, *txHandler.NewChaincodeExecute(...)*. Now, *signature* can be included - in the transaction as one of the argument to be passed to the function or as transaction metadata. - -### Chaincode Execution - -The validators, who receive the execute transaction issued by Bob, will provide to *hello* the following information: - -1. The *binding* of the execute transaction; -2. The *metadata* of the execute transaction; -3. The *metadata* of the deploy transaction. - -Then, *hello* is responsible for checking that *signature* is indeed a valid signature issued by Bob. diff --git a/docs/tech/attributes.md b/docs/tech/attributes.md deleted file mode 100644 index 3ac95b96741..00000000000 --- a/docs/tech/attributes.md +++ /dev/null @@ -1,154 +0,0 @@ -# Attributes support - -To support attributes the user has to pass them during TCert creation, these attributes can be used during transaction deployment, execution or query for Attribute Based Access Control (ABAC) to determine whether the user can or cannot execute a specific chaincode or used attributes' values for other purposes. A mechanism to validate the ownership of attributes is required in order to prove if the attributes passed by the user are correct. The Attribute Certificate Authority (ACA) has the responsibility of validate attributes and to return an Attribute Certificate (ACert) with the valid attribute values. -Attributes values are encrypted using the keys defined below (section Attributes keys). - -## Attribute Keys - -The attributes are encrypted using a key derived from a hierarchy called PreKey tree. This approach consists in deriving keys from a parent key, allowing the parent key owner, get access to derived keys. This way keys used to encrypt attributes are different among attributes and TCerts avoiding linkability while allowing an authorized auditor who owns a parent key to derive the keys in the lower levels. - - -### Example of prekey tree - - Pre3K_BI - |_Pre2K_B = HMAC(Pre3K_BI, “banks”) - | |_Pre1K_BankA = HMAC(Pre2K_B, “Bank A”) - | | |_Pre0K_BankA = HMAC(Pre1K_BankA, TCertID) - | | |_PositionKey_BankA_TIdx = HMAC(Pre0K_BankA, "position") - | | |_CompanyKey_BankA_TIdx = HMAC(Pre0K_BankA, "company") - | | - | |_Pre1K_BankB = HMAC(Pre2K_B, “BanKB”) - | |_Pre0K_BankB = HMAC(Pre1K_BankB, TCertID) - | |_PositionKey_BankB_TIdx = HMAC(Pre0K_BankB, "position") - | |_CompanyKey_BankB_TIdx = HMAC(Pre0K_BankB, "company") - | - |_Pre2K_I = HMAC(Pre3K_BI, "institutions") - |_Pre1K_InstitutionA= HMAC(Pre2K_I, "Institution A”) - |_Pre0K_InstitutionA = HMAC(_Pre1K_InstitutionA, TCertID) - |_PositionKey_InstA_TIdx = HMAC(Pre0K_InstitutionA, "position") - |_CompanyKey_InstA_TIdx = HMAC(Pre0K_InstitutionA, "company") - -- Pre3K_BI: is available to TCA and auditors for banks and institutions. -- Pre2K_B: is available to auditors for banks -- Pre1K_BankA: is available to auditors for Bank A. -- Pre1K_BankB: is available to auditors for Bank B. -- Pre2K_I: is available to auditors for institutions. -- Pre1K_InstitutionA: is available to auditors for Institution A. - -Each TCert has a different PreK0 (for example Pre0K_BankA) and each TCert attribute has a different attribute key (for example PositionKey_BankA_TIdx). - -## Attribute Certificate Authority - -Attribute Certificate Authority (ACA) has the responsibility of certify the ownership of the attributes. ACA has a database to hold attributes for each user and affiliation. - -1. id: The id passed by the user during enrollment -2. affiliation: The entity which the user is affiliated to -3. attributeName: The name used to look for the attribute, e.g. 'position' -4. attributeValue: The value of the attribute, e.g. 'software engineer' -5. validFrom: The start of the attribute's validity period -6. validTo: The end of the attribute's validity period - -### gRPC ACA API - -1. FetchAttributes - -``` - rpc FetchAttributes(ACAFetchAttrReq) returns (ACAFetchAttrResp); - - message ACAFetchAttrReq { - google.protobuf.Timestamp ts = 1; - Cert eCert = 2; // ECert of involved user. - Signature signature = 3; // Signed using the ECA private key. - } - - message ACAFetchAttrResp { - enum StatusCode { - SUCCESS = 000; - FAILURE = 100; - } - StatusCode status = 1; - } -``` - -2. RequestAttributes - -``` - rpc RequestAttributes(ACAAttrReq) returns (ACAAttrResp); - - message ACAAttrReq { - google.protobuf.Timestamp ts = 1; - Identity id = 2; - Cert eCert = 3; // ECert of involved user. - repeated TCertAttributeHash attributes = 4; // Pairs attribute-key, attribute-value-hash - Signature signature = 5; // Signed using the TCA private key. - } - - message ACAAttrResp { - enum StatusCode { - FULL_SUCCESSFUL = 000; - PARTIAL_SUCCESSFUL = 001; - NO_ATTRIBUTES_FOUND = 010; - FAILURE = 100; - } - StatusCode status = 1; - Cert cert = 2; // ACert with the owned attributes. - Signature signature = 3; // Signed using the ACA private key. - } -``` - -3. RefreshAttributes - -``` - rpc RefreshAttributes(ACARefreshReq) returns (ACARefreshResp); - - message ACARefreshAttrReq { - google.protobuf.Timestamp ts = 1; - Cert eCert = 2; // ECert of the involved user. - Signature signature = 3; // Signed using enrollPrivKey - } - - message ACARefreshAttrResp { - enum StatusCode { - SUCCESS = 000; - FAILURE = 100; - } - StatusCode status = 1; - } -``` - -## FLOW - -![ACA flow](../images/attributes_flow.png) - -### During enrollment - -1. The user requests an Enrollment Certificate (ECert) to ECA -2. ECA creates the ECert and responds to the user with it. -3. ECA issues a fetch request under TLS to the ACA passing the newly generated ECert as a parameter. This request is signed with the ECA's private key. -4. The request triggers ACA asynchronous mechanism that fetches attributes' values from external sources and populates the attributes database (in the current implementation attributes are loaded from an internal configuration file). - -### During TCert generation - -1. When the user needs TCerts to create a new transaction it requests a batch of TCerts to the TCA, and provides the following: - * The batch size (i.e. how many TCerts the user is expecting) - * Its ECert - * A list of attributes (e.g. Company, Position) -2. Under TLS TCA sends a RequestAttributes() to ACA to verify if the user is in possession of those attributes. This request is signed with TCA's private key and it contains: - * User's ECert - * A list of attribute names "company, position, ..." -3. The ACA performs a query to the internal attributes database and there are three possible scenarios***: - a. The user does not have any of the specified attributes – An error is returned. - b. The user has all the specified attributes – An X.509 certificate (ACert) with all the specified attributes and the ECert public key is returned. - c. The user has a subset of the requested attributes – An X.509 certificate (ACert) with just the subset of the specified attributes and the ECert public key is returned. -3. The TCA checks the validity period of the ACert's attributes and updates the list by eliminating those that are expired. Then for scenarios b and c from the previous item it checks how many (and which ones) of the attributes the user will actually receive inside each TCert. This information needs to be returned to the user in order to decide whether the TCerts are useful or if further actions needs to be performed (i.e. issue a RefreshAttributes command and request a new batch, throw an error or make use of the TCerts as they are). -4. The TCA could have other criteria to update the valid list of attributes. -5. The TCA creates the batch of TCerts. Each TCert contains the valid attributes encrypted with keys derived from the Prekey tree (each key is unique per attribute, per TCert and per user). -6. The TCA returns the batch of TCerts to the user along with a root key (Prek0) from which each attribute encryption key was derived. There is a Prek0 per TCert. All the TCerts in the batch have the same attributes and the validity period of the TCerts is the same for the entire batch. - -*** _In the current implementation an attributes refresh is executed automatically before this step, but once the refresh service is implemented the user will have the responsibility of keeping his/her attributes updated by invoking this method._ - -### Assumptions - -1. An Attribute Certificate Authority (ACA) has been incorporated to the Membership Services internally to provide a trusted source for attribute values. -2. In the current implementation attributes are loaded from a configuration file (membersrvc.yml). -3. Refresh attributes service is not implemented yet, instead, attributes are refreshed in each RequestAttribute invocation. diff --git a/docs/tech/best-practices.md b/docs/tech/best-practices.md deleted file mode 100644 index 0b286c2c3f0..00000000000 --- a/docs/tech/best-practices.md +++ /dev/null @@ -1,3 +0,0 @@ -## Hyperledger Fabric Development Best Practices - -(This page is under construction.) diff --git a/docs/tech/error-handling.md b/docs/tech/error-handling.md deleted file mode 100644 index 49e6500cc40..00000000000 --- a/docs/tech/error-handling.md +++ /dev/null @@ -1,44 +0,0 @@ -# Hyperledger Fabric - Error handling - -## Usage instructions - -The new error handling framework should be used in place of all calls to fmt.Errorf() or Errors.new(). Using this framework will provide error codes to check against as well as the option to generate a callstack that will be appended to the error message when logging.error is set to debug in peer/core.yaml. - -Using the framework is simple and will only require an easy tweak to your code. First, you'll need to import “github.com/hyperledger/fabric/core/errors” in any code that uses this framework. - -Let's take the following as an example: fmt.Errorf(“Error trying to connect to local peer: %s”, err.Error()) - -For this error, we will simply call the constructor for Error and pass a component name, error message name, followed by the error message and any arguments to format into the message (note the component and message names are case insensitive and will be converted to uppercase): - -err = errors.Error(“Peer”, “ConnectionError”, “Error trying to connect to local peer: %s”, err.Error()) - -For more critical errors for which a callstack would be beneficial, the error can be created as follows: -err = errors.ErrorWithCallstack(“Peer”, “ConnectionError”, “Error trying to connect to local peer: %s”, err.Error()) - -Note: Make sure to use a consistent component name across code in related files/packages. - -Examples of components of the Peer are: Peer, Orderer, Gossip, Ledger, MSP, Chaincode, Comm -Examples of components of the Orderer are: Orderer, SBFT, Kafka, Solo - -We may, in the future, add constants to allow searching for currently defined components for those using an editor with code completion capabilities; we are avoiding this for now to avoid merge conflict issues. - -## Displaying error messages - -Once the error has been created using the framework, displaying the error message is as simple as - -logger.Warningf("%s", err) or fmt.Printf("%s\n", err) - -which, for the example above, would display the error message: - -PEER_CONNECTIONERROR - Error trying to connect to local peer: grpc: timed out when dialing - -## Setting stack trace to display for any CallStackError - -The display of the stack trace with an error is tied to the logging level for the “error” module, which is initialized using logging.error in core.yaml. It can also be set dynamically for code running on the peer via CLI using “peer logging setlevel error ”. The default level of “warning” will not display the stack trace; setting it to “debug” will display the stack trace for all errors that use this error handling framework. - -## General guidelines for error handling in Fabric - -- If it is some sort of best effort thing you are doing, you should log the error and ignore it. -- If you are servicing a user request, you should log the error and return it. -- If the error comes from elsewhere in the Fabric, do not stack the error (errors.Error(“I am stacking errors: %s”, original_error)), simply return the original error. -- A panic should be handled within the same layer by throwing an internal error code/start a recovery process and should not be allowed to propagate to other packages. diff --git a/docs/testing.md b/docs/testing.md deleted file mode 100644 index 875d4d57b61..00000000000 --- a/docs/testing.md +++ /dev/null @@ -1,7 +0,0 @@ -# Testing - -[WIP] -...coming soon - -This topic is intended to contain recommended test scenarios, as well as current -performance numbers against a variety of configurations. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md deleted file mode 100644 index 1814cc0e63b..00000000000 --- a/docs/troubleshooting.md +++ /dev/null @@ -1,7 +0,0 @@ -# Troubleshooting - -[WIP] -...coming soon - -This topic is intended to solve high level bugs and then direct users to more -granular FAQ topics based on their errors. diff --git a/docs/txflow.md b/docs/txflow.md deleted file mode 100644 index 0802a1a5482..00000000000 --- a/docs/txflow.md +++ /dev/null @@ -1,12 +0,0 @@ -# Transaction Flow - -[WIP] -...coming soon - -This topic will contain a diagram (currently in progress) outlining at a high level the -basic flow of a transaction(s) from Application/SDK -> Endorsing Peers -> Back to SDK -with proposal responses -> "Broadcast" to ordering service -> "Delivered" as a block -to a channel's peers for validation and commitment (i.e. written to the shared ledger). - -In the meantime, view the [high level data flows](https://jira.hyperledger.org/browse/FAB-37) -and familiarize yourself with the concepts, components, and roles of system chaincodes. diff --git a/docs/videos.md b/docs/videos.md deleted file mode 100644 index e97baeb7d04..00000000000 --- a/docs/videos.md +++ /dev/null @@ -1,5 +0,0 @@ -# Videos - -Refer to the Hyperledger Fabric libary on [youtube](https://www.youtube.com/channel/UCCFdgCWH_1vCndMPVqQlwZw). -The collection contains developers demonstrating various v1 features and components such as: -ledger, channels, gossip, SDK, chaincode, MSP, and more... diff --git a/docs/whyfabric.md b/docs/whyfabric.md deleted file mode 100644 index ee9be1c9be1..00000000000 --- a/docs/whyfabric.md +++ /dev/null @@ -1,48 +0,0 @@ -# Why Hyperledger Fabric? - -The Hyperledger Fabric project is delivering a blockchain platform -designed to allow the exchange of an asset or the state of an asset to be -consented upon, maintained, and viewed by all parties in a permissioned group. A -key characteristic of Hyperledger Fabric is that the asset is defined -digitally, with all participants simply agreeing on its -representation/characterization. As such, Hyperledger Fabric can support a -broad range of asset types; ranging from the tangible (real estate and hardware) -to the intangible (contracts and intellectual property). - -The technology is based on a standard blockchain concept - a shared, replicated -ledger. However, Hyperledger Fabric is based on a -[permissioned network](glossary.md#permissioned-network), meaning all -participants are required to be authenticated in order to participate and -transact on the blockchain. Moreover, these identities can be used to govern -certain levels of access control (e.g. this user can read the ledger, but cannot -exchange or transfer assets). This dependence on identity is a great advantage -in that varying consensus algorithms (e.g. byzantine or crash fault tolerant) -can be implemented in place of the more compute-intensive Proof-of-Work and -Proof-of-Stake varieties. As a result, permissioned networks tend to provide -higher transaction throughput rates and performance. - -Once an organization is granted access to the -[blockchain network](glossary.md#blockchain-network), it then has the ability -to create and maintain a private [channel](glossary.md#channel) with other -specified members. For example, let's assume there are four organizations -trading jewels. They may decide to use Hyperledger Fabric because they trust -each other, but not to an unconditional extent. They can all agree on the -business logic for trading the jewels, and can all maintain a global ledger to -view the current state of their jewel market (call this the consortium channel). -Additionally, two or more of these organizations might decide to form an -alternate private blockchain for a certain exchange that they want to keep -confidential (e.g. price X for quantity Y of asset Z). They can perform this -trade without affecting their broader consortium channel, or, if desired, -this private channel can broadcast some level of reference data to their -consortium channel. - -This is powerful! This provides for great flexibility and potent capabilities, -along with the interoperability of multiple blockchain ledgers within one -consortium. This is the first of its kind and allows organizations to curate -Hyperledger Fabric to support the myriad use cases for different businesses -and industries. Hyperledger Fabric has already been -successfully implemented in the banking, finance, and retail industries. - -We welcome you to the Hyperledger Fabric community and are keen to learn of your -architectural and business requirements, and help determine how Hyperledger -Fabric can be leveraged to support your use cases.