diff --git a/README.md b/README.md index 6e6699f04..a3b60fdd1 100644 --- a/README.md +++ b/README.md @@ -13,49 +13,44 @@ Quorum is a fork of [go-ethereum](https://github.com/ethereum/go-ethereum) and i Key enhancements over go-ethereum: -* __Privacy__ - Quorum supports private transactions and private contracts through public/private state separation, and utilises peer-to-peer encrypted message exchanges (see [Constellation](https://github.com/jpmorganchase/constellation) and [Tessera](https://github.com/jpmorganchase/tessera)) for directed transfer of private data to network participants -* __Alternative Consensus Mechanisms__ - with no need for POW/POS in a permissioned network, Quorum instead offers multiple consensus mechanisms that are more appropriate for consortium chains: - * __Raft-based Consensus__ - a consensus model for faster blocktimes, transaction finality, and on-demand block creation - * __Istanbul BFT__ - a PBFT-inspired consensus algorithm with transaction finality, by AMIS. -* __Peer Permissioning__ - node/peer permissioning using smart contracts, ensuring only known parties can join the network -* __Higher Performance__ - Quorum offers significantly higher performance than public geth +* [__Privacy__](http://docs.goquorum.com/en/latest/Privacy/Overview/) - Quorum supports private transactions and private contracts through public/private state separation, and utilises peer-to-peer encrypted message exchanges (see [Constellation](https://github.com/jpmorganchase/constellation) and [Tessera](https://github.com/jpmorganchase/tessera)) for directed transfer of private data to network participants +* [__Alternative Consensus Mechanisms__](http://docs.goquorum.com/en/latest/Consensus/Consensus/) - with no need for POW/POS in a permissioned network, Quorum instead offers multiple consensus mechanisms that are more appropriate for consortium chains: + * [__Raft-based Consensus__](http://docs.goquorum.com/en/latest/Consensus/raft/raft/) - a consensus model for faster blocktimes, transaction finality, and on-demand block creation + * [__Istanbul BFT__](http://docs.goquorum.com/en/latest/Consensus/ibft/ibft/) - a PBFT-inspired consensus algorithm with transaction finality, by AMIS. + * [__Clique POA Consensus__](https://github.com/ethereum/EIPs/issues/225) - a default POA consensus algorithm bundled with Go Ethereum. +* [__Peer Permissioning__](http://docs.goquorum.com/en/latest/Permissioning/Permissions%20Overview/) - node/peer permissioning, ensuring only known parties can join the network +* [__Pluggable architecture__](http://docs.goquorum.com/en/latest/PluggableArchitecture/Overview/) - allows adding additional features as plugins to the core `geth`, providing extensibility, flexibility, and distinct isolation of Quorum features. +* __Higher Performance__ - Quorum offers significantly higher performance throughput than public geth ## Architecture -![Quorum Tessera Privacy Flow](https://raw.githubusercontent.com/jpmorganchase/quorum-docs/master/images/QuorumTransactionProcessing.JPG) +![Quorum Tessera Privacy Flow](https://github.com/jpmorganchase/quorum/blob/master/docs/Quorum%20Design.png) -The above diagram is a high-level overview of the privacy architecture used by Quorum. For more in-depth discussion of the components, refer to the [documentation site](https://docs.goquorum.com). +The above diagram is very high-level overview of component architecture used by Quorum. For more in-depth discussion of the components and how they interact, please refer to [lifecycle of a private transaction](http://docs.goquorum.com/en/latest/Privacy/Lifecycle-of-a-private-transaction/). ## Quickstart -The quickest way to get started with Quorum is by following instructions in the [Quorum Examples](https://github.com/jpmorganchase/quorum-examples) repository. This allows you to quickly create a network of Quorum nodes, and includes a step-by-step demonstration of the privacy features of Quorum. +There are [several ways](https://docs.goquorum.com/en/latest/Getting%20Started/Getting%20Started%20Overview/) to quickly get up and running with Quorum. One of the easiest is to use [Quorum Wizard](https://docs.goquorum.com/en/latest/Getting%20Started/Getting%20Started%20Overview/#quickstart-with-quorum-wizard) - a command line tool that allows users to set up a development Quorum network on their local machine in less than *2 minutes*. + +## Quorum Projects + +Check out some of the interesting projects we are actively working on: + +* [quorum-wizard](http://docs.goquorum.com/en/latest/Wizard/GettingStarted/): Setup a Quorum network in 2 minutes! +* [quorum-remix-plugin](http://docs.goquorum.com/en/latest/RemixPlugin/Overview/): The Quorum plugin for Ethereum's Remix IDE adds support for creating and interacting with private contracts on a Quorum network. +* [Cakeshop](http://docs.goquorum.com/en/latest/Cakeshop/Overview/): An integrated development environment and SDK for Quorum +* [quorum-examples](http://docs.goquorum.com/en/latest/Getting%20Started/Quorum-Examples/): Quorum demonstration examples +* [qubernetes](http://docs.goquorum.com/en/latest/Getting%20Started/Getting%20Started%20Overview/#quorum-on-kubernetes): Deploy Quorum on Kubernetes +* [quorum-cloud](http://docs.goquorum.com/en/latest/Getting%20Started/Getting%20Started%20Overview/#creating-a-network-deployed-in-the-cloud): Tools to help deploy Quorum network in a cloud provider of choice +* [quorum.js](http://docs.goquorum.com/en/latest/quorum.js/Overview/): Extends web3.js to support Quorum-specific APIs +* Zero Knowledge on Quorum + * [ZSL](https://github.com/jpmorganchase/quorum/wiki/ZSL) POC and [ZSL on Quorum](https://github.com/jpmorganchase/zsl-q/blob/master/README.md) + * [Anonymous Zether](https://github.com/jpmorganchase/anonymous-zether) implementation + -## Further Reading -Further documentation can be found in the [docs](docs/) folder and on the [documentation site](https://docs.goquorum.com). ## Official Docker Containers The official docker containers can be found under https://hub.docker.com/u/quorumengineering/ - -## See also - -* [Quorum](https://github.com/jpmorganchase/quorum): this repository -* [Quorum Documentation](https://docs.goquorum.com) -* [quorum-examples](https://github.com/jpmorganchase/quorum-examples): Quorum demonstration examples -* [qubernetes](https://github.com/jpmorganchase/qubernetes): Deploy Quorum on Kubernetes -* [Quorum Community Slack Inviter](https://www.goquorum.com/slack-inviter): Quorum Slack community entry point -* Quorum Transaction Managers - * [Constellation](https://github.com/jpmorganchase/constellation): Haskell implementation of peer-to-peer encrypted message exchange for transaction privacy - * [Tessera](https://github.com/jpmorganchase/tessera): Java implementation of peer-to-peer encrypted message exchange for transaction privacy -* Quorum supported consensuses - * [Raft Consensus Documentation](https://docs.goquorum.com/en/latest/Consensus/raft/) - * [Istanbul BFT Consensus Documentation](https://github.com/ethereum/EIPs/issues/650): [RPC API](https://docs.goquorum.com/en/latest/Consensus/ibft/istanbul-rpc-api.md) and [technical article](https://medium.com/getamis/istanbul-bft-ibft-c2758b7fe6ff). __Please note__ that updated istanbul-tools is now hosted in [this](https://github.com/jpmorganchase/istanbul-tools/) repository - * [Clique POA Consensus Documentation](https://github.com/ethereum/EIPs/issues/225) and a [guide to setup clique json](https://modalduality.org/posts/puppeth/) with [puppeth](https://blog.ethereum.org/2017/04/14/geth-1-6-puppeth-master/) -* Zero Knowledge on Quorum - * [ZSL](https://github.com/jpmorganchase/quorum/wiki/ZSL) wiki page and [documentation](https://github.com/jpmorganchase/zsl-q/blob/master/README.md) - * [Anonymous Zether](https://github.com/jpmorganchase/anonymous-zether) implementation -* [quorum-cloud](https://github.com/jpmorganchase/quorum-cloud): Tools to help deploy Quorum network in a cloud provider of choice -* [Cakeshop](https://github.com/jpmorganchase/cakeshop): An integrated development environment and SDK for Quorum - ## Third Party Tools/Libraries The following Quorum-related libraries/applications have been created by Third Parties and as such are not specifically endorsed by J.P. Morgan. A big thanks to the developers for improving the tooling around Quorum! diff --git a/docs/Permissioning/Basic NetworkPermissions.md b/docs/Permissioning/Basic NetworkPermissions.md new file mode 100644 index 000000000..e647007e6 --- /dev/null +++ b/docs/Permissioning/Basic NetworkPermissions.md @@ -0,0 +1,24 @@ +# Basic Network Permissioning + +Basic Network Permissioning is a feature that controls which nodes can connect to a given node and also to which nodes the given node can dial out to. It is managed at the individual node level by providing the `--permissioned` command line flag when starting the node. + +If the `--permissioned` flag is set, the node looks for a file named `/permissioned-nodes.json` . This file contains the whitelist of enodes that this node can connect to and accept connections from. Therefore, with permissioning enabled, only the nodes that are listed in the `permissioned-nodes.json` file become part of the network. If the `--permissioned` flag is specified but no nodes are added to the `permissioned-nodes.json` file then this node can neither connect to any node nor accept any incoming connections. + +The `permissioned-nodes.json` file follows the below pattern, which is similar to the `/static-nodes.json` file that is used to specify the list of static nodes a given node always connects to: + ``` json + [ + "enode://remoteky1@ip1:port1", + "enode://remoteky1@ip2:port2", + "enode://remoteky1@ip3:port3", + ] + ``` + +Sample file: (node id truncated for clarity) + ``` json + [ + "enode://6598638ac5b15ee386210156a43f565fa8c485924894e2f3a967207c047470@127.0.0.1:30300", + ] + ``` + +!!! warning + Every node has its own copy of the `permissioned-nodes.json` file. If different nodes have different lists of remote keys, then each node may have a different list of permissioned nodes which may have an adverse effect on the network. \ No newline at end of file diff --git a/docs/Permissioning/Contract Design.md b/docs/Permissioning/Enhanced Permissions Model/Contract Design.md similarity index 98% rename from docs/Permissioning/Contract Design.md rename to docs/Permissioning/Enhanced Permissions Model/Contract Design.md index 8ac217231..678f55cc1 100644 --- a/docs/Permissioning/Contract Design.md +++ b/docs/Permissioning/Enhanced Permissions Model/Contract Design.md @@ -1,6 +1,6 @@ # Smart Contract design for permissions The permissions model is completely built on smart contracts. The smart contract design is as below: -![contract design](images/ContractDesign.png) +![contract design](./images/ContractDesign.png) The permissions smart contract design follows the Proxy-Implementation-Storage pattern which allows the implementation logic to change without changing the storage or interface layer. A brief description of the smart contracts is below: diff --git a/docs/Permissioning/Overview.md b/docs/Permissioning/Enhanced Permissions Model/Overview.md similarity index 74% rename from docs/Permissioning/Overview.md rename to docs/Permissioning/Enhanced Permissions Model/Overview.md index f34cc0bc1..ed0c20422 100644 --- a/docs/Permissioning/Overview.md +++ b/docs/Permissioning/Enhanced Permissions Model/Overview.md @@ -1,6 +1,9 @@ -# Introduction -The [current permission model](../Old%20Permissioning) within Quorum is limited to node level permissions only and allows a set of nodes which are part of `permissioned-nodes.json` to join the network. The model has been enhanced to cater for enterprise level needs to have a **smart contract based permission model**; this has the flexibility to manage nodes, accounts and account level access controls. The overview of the model is as depicted below: -![permissions mode](images/PermissionsModel.png) +# Enhanced Permissions Model +The Enhanced Permissions Model caters for enterprise-level needs by having a **smart contract-based permissioning model**. This allows for significant flexibility to manage nodes, accounts, and account-level access controls. + +An overview of the model is as depicted below: +![permissions mode](./images/PermissionsModel.png) + ### Key Definitions * Network - A set of interconnected nodes representing an enterprise blockchain which contains organizations * Organization - A set of roles, Ethereum accounts and nodes having a variety of permissions to interact with the network @@ -13,4 +16,4 @@ The [current permission model](../Old%20Permissioning) within Quorum is limited As depicted above, in the enhanced permissions model, the network comprises a group of organizations. The network admin accounts defined at network level can propose and approve new organizations to join the network, and can assign an account as the organization administration account. The organization admin account can create roles, create sub organizations, assign roles to its accounts, and add any other node which is part of the organization. A sub organization can have its own set of roles, accounts and sub organizations. The organization administration account manages and controls all activities at the organization level. The organization administrator can create an admin role and assign the same to a different account to manage the administration of a sub organization. The access rights of an account are derived based on the role assigned to it. The account will be able to transact via any node linked to the sub org or at overall organizations level. A sample network view is as depicted below: -![sample mode](images/sampleNetwork.png) +![sample mode](./images/sampleNetwork.png) diff --git a/docs/Permissioning/Permissioning apis.md b/docs/Permissioning/Enhanced Permissions Model/Permissioning apis.md similarity index 99% rename from docs/Permissioning/Permissioning apis.md rename to docs/Permissioning/Enhanced Permissions Model/Permissioning apis.md index e04d7f584..68078431b 100644 --- a/docs/Permissioning/Permissioning apis.md +++ b/docs/Permissioning/Enhanced Permissions Model/Permissioning apis.md @@ -315,7 +315,9 @@ curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPer > quorumPermission.addOrg("ABC", "enode://3d9ca5956b38557aba991e31cf510d4df641dce9cc26bfeb7de082f0c07abb6ede3a58410c8f249dabeecee4ad3979929ac4c7c496ad20b8cfdd061b7401b4f5@127.0.0.1:21003?discport=0&raftport=50404", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {from: eth.accounts[0]}) "Action completed successfully" ``` + If there are any pending items for approval, proposal of any new organization will fail. Also the enode id and accounts can be linked to one organization only. + ```javascript tab="geth console" > quorumPermission.addOrg("ABC", "enode://3d9ca5956b38557aba991e31cf510d4df641dce9cc26bfeb7de082f0c07abb6ede3a58410c8f249dabeecee4ad3979929ac4c7c496ad20b8cfdd061b7401b4f5@127.0.0.1:21003?discport=0&raftport=50404", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {from: eth.accounts[0]}) Error: Pending approvals for the organization. Approve first @@ -336,8 +338,8 @@ Error: Account already in use in another organization at web3.js:6347:15 at web3.js:5081:36 at :1:1 - ``` + ### `quorumPermission_approveOrg` This api can be executed by a network admin account (`from:` in transactions args) only for approving a proposed organization into the network. #### Parameters @@ -812,6 +814,7 @@ curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPer ``` ## Roles +### Account access types The table below indicates the numeric value for each account access type. | AccessType | Value | @@ -864,4 +867,4 @@ The table below indicates the numeric value for various node status. | Approved | 2 | | Deactivated | 3 | | Blacklisted | 4 | -| Recovery initiated for Blacklisted Node | 5 | \ No newline at end of file +| Recovery initiated for Blacklisted Node | 5 | diff --git a/docs/Permissioning/Usage.md b/docs/Permissioning/Enhanced Permissions Model/Usage.md similarity index 88% rename from docs/Permissioning/Usage.md rename to docs/Permissioning/Enhanced Permissions Model/Usage.md index daf0cf09b..43d90ede7 100644 --- a/docs/Permissioning/Usage.md +++ b/docs/Permissioning/Enhanced Permissions Model/Usage.md @@ -1,13 +1,4 @@ - -**This section describes the usage of permission model for creation of a network, initial set up and management of network. The network management activities can be broadly categorized into:** - -* [Initial network set up](#initial-network-set-up) -* [Proposing a new organization into the network](#proposing-a-new-organization-into-the-network) -* [Organization admin managing the organization level permissions](#organization-admin-managing-the-organization-level-permissions) -* [Suspending an organization temporarily](#suspending-an-organization-temporarily) -* [Revoking suspension of an organization](#revoking-suspension-of-an-organization) -* [Assigning admin privileges at organization and network level](#assigning-admin-privileges-at-organization-and-network-level) - +Managing the advanced permissioning model can be broadly categorized into the following activities: ### Initial network set up Please refer to [set up](../setup). For an existing network running with an older version of Quorum: @@ -99,7 +90,7 @@ then the network will have the following configuration once it has started up: ``` ### Proposing a new organization into the network -Once the network is up, the network admin accounts can then propose a new organization into the network. Majority approval from the network admin accounts is required before an organization is approved. The APIs for [proposing](../Permissioning%20apis#quorumpermissionaddorg) and [approving](../Permissioning%20apis#quorumpermissionapproveorg) an organization are documented in [permission APIs](../Permissioning%20apis) +Once the network is up, the network admin accounts can then propose a new organization into the network. Majority approval from the network admin accounts is required before an organization is approved. The APIs for [proposing](../Permissioning%20apis#quorumpermission_addorg) and [approving](../Permissioning%20apis#quorumpermission_approveorg) an organization are documented in [permission APIs](../Permissioning%20apis) #### Example An example to propose and approve an organization by name `ORG1` is as shown below: @@ -182,7 +173,7 @@ The new node belonging to the organization can now join the network. In case the ### Organization admin managing the organization level permissions Once the organization is approved and the node of the organization has joined the network, the organization admin can then create sub organizations, roles, add additional nodes at organization level, add accounts to the organization and change roles of existing organization level accounts. -To add a sub org at `ORG1` level refer to [addSubOrg API](../Permissioning%20apis#quorumpermissionaddsuborg) +To add a sub org at `ORG1` level refer to [addSubOrg API](../Permissioning%20apis#quorumpermission_addsuborg) ```javascript > quorumPermission.addSubOrg("ORG1", "SUB1", "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0", {from: eth.accounts[0]}) "Action completed successfully" @@ -199,7 +190,7 @@ To add a sub org at `ORG1` level refer to [addSubOrg API](../Permissioning%20api } ``` -For adding a sub org the enode id is not mandatory. For the newly created sub org if the org admin desires to add an administration account, the org admin account will have to first create a role with `isAdmin` flag as `Y` and then assign this role to the account which belongs to the sub org. Once assigned the account will act as org admin at sub org level. Refer to [addNewRole API](../Permissioning%20apis#quorumpermissionaddnewrole) +For adding a sub org the enode id is not mandatory. For the newly created sub org if the org admin desires to add an administration account, the org admin account will have to first create a role with `isAdmin` flag as `Y` and then assign this role to the account which belongs to the sub org. Once assigned the account will act as org admin at sub org level. Refer to [addNewRole API](../Permissioning%20apis#quorumpermission_addnewrole) ```javascript > quorumPermission.addNewRole("ORG1.SUB1", "SUBADMIN", 3, false, true,{from: eth.accounts[0]}) "Action completed successfully" @@ -259,7 +250,7 @@ The account `0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0` is now the admin for su }] ``` -To add an account to an organization refer to [addAccountToOrg API](../Permissioning%20apis#quorumpermissionaddaccounttoorg). +To add an account to an organization refer to [addAccountToOrg API](../Permissioning%20apis#quorumpermission_addaccounttoorg). ```javascript > quorumPermission.addAccountToOrg("0x283f3b8989ec20df621166973c93b56b0f4b5455", "ORG1.SUB1", "SUBADMIN", {from: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) "Action completed successfully" @@ -280,7 +271,7 @@ To add an account to an organization refer to [addAccountToOrg API](../Permissio }] ``` -To suspend an account [updateAccountStatus](../Permissioning%20apis#quorumpermissionupdateaccountstatus) API can be invoked with action as 1. +To suspend an account [updateAccountStatus](../Permissioning%20apis#quorumpermission_updateaccountstatus) API can be invoked with action as 1. ```javascript > quorumPermission.updateAccountStatus("ORG1.SUB1", "0x283f3b8989ec20df621166973c93b56b0f4b5455", 1, {from: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) "Action completed successfully" @@ -300,7 +291,7 @@ To suspend an account [updateAccountStatus](../Permissioning%20apis#quorumpermis }] ``` -To revoke suspension of an account [updateAccountStatus](../Permissioning%20apis#quorumpermissionupdateaccountstatus) API can be invoked with action as 2. +To revoke suspension of an account [updateAccountStatus](../Permissioning%20apis#quorumpermission_updateaccountstatus) API can be invoked with action as 2. ```javascript > quorumPermission.updateAccountStatus("ORG1.SUB1", "0x283f3b8989ec20df621166973c93b56b0f4b5455", 2, {from: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) "Action completed successfully" @@ -321,7 +312,7 @@ To revoke suspension of an account [updateAccountStatus](../Permissioning%20apis }] ``` -To [blacklist an account updateAccountStatus](../Permissioning%20apis#quorumpermissionupdateaccountstatus) API can be invoked with action as 3. Once blacklisted no further activity will be possible on the account. +To [blacklist an account updateAccountStatus](../Permissioning%20apis#quorumpermission_updateaccountstatus) API can be invoked with action as 3. Once blacklisted no further activity will be possible on the account. ```javascript > quorumPermission.updateAccountStatus("ORG1.SUB1", "0x283f3b8989ec20df621166973c93b56b0f4b5455", 3, {from: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) "Action completed successfully" @@ -342,7 +333,7 @@ To [blacklist an account updateAccountStatus](../Permissioning%20apis#quorumperm }] ``` -To [add nodes addNode ](../Permissioning%20apis#quorumpermissionaddnode) at organization and sub organization level by the org admin. +To [add Nodes ](../Permissioning%20apis#quorumpermission_addnode) at organization and sub organization level by the org admin. ```javascript > quorumPermission.addNode("ORG1.SUB1", "enode://eacaa74c4b0e7a9e12d2fe5fee6595eda841d6d992c35dbbcc50fcee4aa86dfbbdeff7dc7e72c2305d5a62257f82737a8cffc80474c15c611c037f52db1a3a7b@127.0.0.1:21005?discport=0", {from: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) "Action completed successfully" @@ -358,7 +349,7 @@ To [add nodes addNode ](../Permissioning%20apis#quorumpermissionaddnode) at orga }] ``` -Org admin can manage the status of the nodes by using [updateNodeStatus](../Permissioning%20apis#quorumpermissionupdatenodestatus) API. To deactivate a node the API can be invoked with action 1. +Org admin can manage the status of the nodes by using [updateNodeStatus](../Permissioning%20apis#quorumpermission_updatenodestatus) API. To deactivate a node the API can be invoked with action 1. ```javascript > quorumPermission.getOrgDetails("ORG1.SUB1").nodeList [{ @@ -372,7 +363,7 @@ Org admin can manage the status of the nodes by using [updateNodeStatus](../Perm }] ``` -To activate the node back invoke [updateNodeStatus](../Permissioning%20apis#quorumpermissionupdatenodestatus) API with action 2. +To activate the node back invoke [updateNodeStatus](../Permissioning%20apis#quorumpermission_updatenodestatus) API with action 2. ```javascript > quorumPermission.updateNodeStatus("ORG1.SUB1", "enode://eacaa74c4b0e7a9e12d2fe5fee6595eda841d6d992c35dbbcc50fcee4aa86dfbbdeff7dc7e72c2305d5a62257f82737a8cffc80474c15c611c037f52db1a3a7b@127.0.0.1:21005?discport=0",2, {from:"0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) "Action completed successfully" @@ -388,7 +379,7 @@ To activate the node back invoke [updateNodeStatus](../Permissioning%20apis#quor }] ``` -To blacklist a node invoke [updateNodeStatus](../Permissioning%20apis#quorumpermissionupdatenodestatus) API with action 3. Once blacklisted the node will never be able join the network again. +To blacklist a node invoke [updateNodeStatus](../Permissioning%20apis#quorumpermission_updatenodestatus) API with action 3. Once blacklisted the node will never be able join the network again. ```javascript > quorumPermission.getOrgDetails("ORG1.SUB1").nodeList [{ @@ -410,7 +401,7 @@ Further: * If a node is deactivated no transaction will be allowed from that node ### Suspending an organization temporarily -If there is a need to temporarily suspend all activities of an organization [updateOrgStatus](../Permissioning%20apis#quorumpermissionupdateorgstatus) API can be invoked with action 1. This can be invoked only by the network admin accounts and will reuiqre majority voting. +If there is a need to temporarily suspend all activities of an organization [updateOrgStatus](../Permissioning%20apis#quorumpermission_updateorgstatus) API can be invoked with action 1. This can be invoked only by the network admin accounts and will reuiqre majority voting. ```javascript > quorumPermission.updateOrgStatus("ORG1", 1, {from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d"}) "Action completed successfully" @@ -426,7 +417,7 @@ If there is a need to temporarily suspend all activities of an organization [upd } ``` -To approve the org, suspension majority approval from other network admin accounts is required. The api for the same is [approveOrgStatus](../Permissioning%20apis#quorumpermissionapproveorgstatus). Once approved the org status is marked as suspended. +To approve the org, suspension majority approval from other network admin accounts is required. The api for the same is [approveOrgStatus](../Permissioning%20apis#quorumpermission_approveorgstatus). Once approved the org status is marked as suspended. ```javascript > quorumPermission.approveOrgStatus("ORG1", 1, {from: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e"}) "Action completed successfully" @@ -446,7 +437,7 @@ When the org is suspended no transaction from any of the account linked to the o ### Revoking suspension of an organization -To revoke the suspension of an org [updateOrgStatus](../Permissioning%20apis#quorumpermissionupdateorgstatus) can be called with action as 2. This will require majority approval (API [approveOrgStatus](../Permissioning%20apis#quorumpermissionapproveorgstatus) with action 2). +To revoke the suspension of an org [updateOrgStatus](../Permissioning%20apis#quorumpermission_updateorgstatus) can be called with action as 2. This will require majority approval (API [approveOrgStatus](../Permissioning%20apis#quorumpermission_approveorgstatus) with action 2). ```javascript > quorumPermission.updateOrgStatus("ORG1", 2, {from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d"}) "Action completed successfully" @@ -468,7 +459,7 @@ Once the revoke is approved, all accounts in the organization and sub organizati ### Assigning admin privileges at organization and network level There may be a scenario where one of the accounts at the organization level needs to have network admin level permissions and be able to perform network admin activities. Similarly there can be a need to change the admin account at organization level. Both these activities can be performed by existing network admin accounts only, and will require majority approval from the network admin accounts. The API usage details are as below. -To assign network admin or org admin role to an account invoke [assignAdminRole](../Permissioning%20apis#quorumpermissionassignadminrole). +To assign network admin or org admin role to an account invoke [assignAdminRole](../Permissioning%20apis#quorumpermission_assignadminrole). ```javascript > quorumPermission.assignAdminRole("ORG1", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", "ADMIN", {from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d"}) "Action completed successfully" @@ -482,7 +473,7 @@ To assign network admin or org admin role to an account invoke [assignAdminRole] } ``` -To approve the assignment of network admin role invoke [approveAdminRole](../Permissioning%20apis#quorumpermissionapproveadminrole) API. +To approve the assignment of network admin role invoke [approveAdminRole](../Permissioning%20apis#quorumpermission_approveadminrole) API. ```javascript > quorumPermission.approveAdminRole("ORG1", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {from: eth.accounts[0]}) "Action completed successfully" diff --git a/docs/Permissioning/images/ContractDesign.png b/docs/Permissioning/Enhanced Permissions Model/images/ContractDesign.png similarity index 100% rename from docs/Permissioning/images/ContractDesign.png rename to docs/Permissioning/Enhanced Permissions Model/images/ContractDesign.png diff --git a/docs/Permissioning/images/PermissionsModel.png b/docs/Permissioning/Enhanced Permissions Model/images/PermissionsModel.png similarity index 100% rename from docs/Permissioning/images/PermissionsModel.png rename to docs/Permissioning/Enhanced Permissions Model/images/PermissionsModel.png diff --git a/docs/Permissioning/images/sampleNetwork.png b/docs/Permissioning/Enhanced Permissions Model/images/sampleNetwork.png similarity index 100% rename from docs/Permissioning/images/sampleNetwork.png rename to docs/Permissioning/Enhanced Permissions Model/images/sampleNetwork.png diff --git a/docs/Permissioning/setup.md b/docs/Permissioning/Enhanced Permissions Model/setup.md similarity index 100% rename from docs/Permissioning/setup.md rename to docs/Permissioning/Enhanced Permissions Model/setup.md diff --git a/docs/Permissioning/Permissions Overview.md b/docs/Permissioning/Permissions Overview.md new file mode 100644 index 000000000..50dfe2e61 --- /dev/null +++ b/docs/Permissioning/Permissions Overview.md @@ -0,0 +1,6 @@ +# Quorum Permissioning Overview +Quorum supports two network permissioning models. + +* [Basic network permissioning](../Basic%20NetworkPermissions): Controls which nodes can connect to a given node and also to which nodes the given node can dial out to. + +* [Enhanced network permissioning](../Enhanced%20Permissions%20Model/Overview): Caters for enterprise-level needs by having a **smart contract-based permissioning model**. This allows for significant flexibility to manage nodes, accounts, and account-level access controls. diff --git a/docs/Privacy/Tessera/Tessera Services/Enclave.md b/docs/Privacy/Tessera/Tessera Services/Enclave.md index 7882fb51d..34e43d3b5 100644 --- a/docs/Privacy/Tessera/Tessera Services/Enclave.md +++ b/docs/Privacy/Tessera/Tessera Services/Enclave.md @@ -30,15 +30,12 @@ The Enclave **performs** the following actions on request: ## Where does the Enclave sit in the private transaction flow? -The Enclave is the innermost actor of the sequence of events. The below diagram demonstrates where the Enclave sits: - -![Quorum Tessera Privacy Flow](https://github.com/jpmorganchase/tessera/raw/master/Tessera%20Privacy%20flow.jpeg) - -As the diagram shows, each Enclave interacts only with it's own transaction manager and no-one else. - -Tessera provides different types of Enclaves to suit different needs: +The Enclave is the innermost actor of the sequence of events. Each Enclave only interacts with its corresponding Transaction Manager and nothing else. + +See the [Lifecycle of a private transaction](../../../Lifecycle-of-a-private-transaction) for more information. ## Types of Enclave +Tessera provides different types of Enclaves to suit different needs: ### Local Enclave The local Enclave is the classical option that was included in versions of Tessera prior to v0.9. This includes the Enclave inside the same process and the transaction manager. This is still an option, and requires all the Enclave configuration to be inside the same configuration file and the Transaction Manager configuration. diff --git a/docs/Privacy/Tessera/Tessera Services/Keys/Keys.md b/docs/Privacy/Tessera/Tessera Services/Keys/Keys.md index 7046aacac..c80c64a40 100644 --- a/docs/Privacy/Tessera/Tessera Services/Keys/Keys.md +++ b/docs/Privacy/Tessera/Tessera Services/Keys/Keys.md @@ -147,7 +147,19 @@ Password update can be used in multiple ways. Running any of these commands wil ``` All options have been overriden here but only the options you wish to alter from their defaults need to be provided. +### Password-protection algorithm +The following steps detail the process of password-protecting a private key: + + 1. Given private key `K` and password `P` + 2. Generate random Argon2i nonce + 3. Generate random encryption nonce + 4. Stretch `P` using Argon2i (with the Argon2i nonce and custom or default [ArgonOptions](#securing-private-keys)) into a 32-byte master key (`MK`) + 5. Symmetrically encrypt `K` with `MK` and the encryption nonce + ## Using alternative curve key types By default the `-keygen` and `-updatepassword` commands generate and update [NaCl](https://nacl.cr.yp.to/) compatible keys. As of Tessera v0.10.2, the `--encryptor.type=EC` CLI option can be provided to generate/update keys of different types. See [encryptor config](../../../Configuration/Configuration Overview/#encryptor-supporting-alternative-curves-in-tessera) for more details. + +## Rotation +Tessera is built to support rotation trivially, by allowing counterparties to advertise multiple keys at once. The tooling to make rotation seamless and automatic is on our Roadmap. diff --git a/docs/Privacy/Tessera/Usage/Logging.md b/docs/Privacy/Tessera/Usage/Logging.md new file mode 100644 index 000000000..2c11cad2a --- /dev/null +++ b/docs/Privacy/Tessera/Usage/Logging.md @@ -0,0 +1,256 @@ +Messages are written to the logs using these rules for the log level: + +* `ERROR`: system failures or situations that require some action to ensure correct operation of the system. +* `WARN`: notifications that don't require immediate action or that are indications that a transaction failed. +* `INFO`: information message to allow investigation of issues or to provide reassurance that the system is operating correctly. +* `DEBUG`: very verbose logging to assist with investigation of issues + +The log level is written out in uppercase as part of the log message, this can be used for alert monitoring. + +## Errors +Below is a non-exhaustive list of error messages and suggested actions. Braces '{}' indicate where further detail of the root cause is logged as part of the message. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MessageCause
Error decoding message: {error details}Invalid base64 in privateFrom/privateFor from Quorum or in tx hash for resend
Action: Sender needs to provide valid base64
Error occurred: {error details} Root cause: {root cause}Generated for a variety of reasons: +
    +
  • Invalid content in message, e.g.
    curl -X POST "http://localhost:9001/push" \ 
    -H "accept: application/json" \
    -H "Content-Type: application/octet-stream" \
    -d "[ \"a garbage string\"]"
  • +
  • Could not send message to peer, e.g.
    "Root cause: Unable to push payload to recipient url
    http://localhost:9001/"
  • +
+ Action: depends on the root cause in the log message +
Enclave unavailable: {error details}Action: user needs to check why enclave is unavailable (look in log file for enclave)
Entity not found: {error details}API request received against q2tserver/transaction/{key} where key is not a tx hash in the DB
Entity not found:{error details}Thrown if endpoint doesn't exist on that API, e.g.
curl -s http://localhost:9001/invalidendpoint
Security exception {followed by exception message, like "java.lang.SecurityException: No key found for url 127.1.1.1"}Thrown if enableRemoteKeyValidation: true and partyinfo request received from a URL for which we don't hold a public key (i.e. potentially a malicious party).
Note: if key validation enabled then this exception will be thrown during startup whilst the nodes exchange key information.
ERROR c.q.t.a.e.DefaultExceptionMapper - HTTP 400 Bad RequestLogged if received message is corrupt/incorrectly formatted, e.g.
curl -X POST "http://localhost:9001/resend" \
-H "accept: text/plain" \
-H "Content-Type: application/json" \
-d "{ \"some rubbish\" }"
Error while reading secret from fileUnable to read the secret key (password) from file specified by TESSERA_CONFIG_SECRET
+ Action: ensure the secret key file config is correct, and file can be read +
unable to initialize encryption facade {error details}Unable to initialise elliptical curve encryption. Logged error message will give further details
+ Action: check configuration properties +
unable to generate shared secret {error details}Unable to generate shared secret for elliptical curve encryption. Logged error message will give further details.
+ Action: check configuration properties +
unable to perform symmetric encryption {error details}Unable to encrypt data. Logged error message will give further details.
+ Action: check configuration properties +
unable to perform symmetric decryption {error details}Unable to decrypt data. Logged error message will give further details.
+ Action: check configuration properties +
Error when executing action {action type}, exception details: {error details} Unable to start Influx DB. Logged error message will give further details
+ Action: check configuration properties +
Error creating bean with name 'entityManagerFactory'Unable to create connection to database due to failure to decrypt the DB password using the supplied secret key
+ Action: ensure that the correct value is supplied for the secret key +
Config validation issue: {property name} {error details}Invalid configuration detected
+ Action: correct the configuration of the named property. +
Invalid json, cause is {error details}Invalid json in the configuration file
+ Action: check the configuration file for mistakes. +
Configuration exception, cause is {error details}Invalid data in the configuration file
+ Action: check the configuration file for mistakes. +
CLI exception, cause is {error details}Invalid command line
+ Action: The error details will give further information regarding the action to be taken. +
+ +## Warnings +Below is a list of warning messages and possible causes. Braces '{}' indicate where further detail of the root cause is logged as part of the message. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MessageCause
Public key {publicKey} not found when searching for private keyThe key in a transaction is not recognised, i.e. it is not the public key of a known participant node.
Recipient not found for key: {public key}An unrecognised participant is specified in a transaction.
No action needed.
Unable to unmarshal payloadA received message is corrupt, or incorrectly formatted
Remote host {remote host name} with IP {remote host IP} failed whitelist validationLogged if whitelist validation is enabled and the remote host is not in the whitelist.
+ Action: either this is a malicious connection attempt, or mis-configuration +
Ignoring unknown/unmatched json element: {element tag name}An unrecognised element has been found in the config file.
+ Action: remove or correct the config file entry +
Not able to find or read any secret for decrypting sensitive values in configSecret key (password) could not be read from console or password file (see TESSERA_CONFIG_SECRET in docs).
+ Action: correction needed for the secret key or the file access permission +
Some sensitive values are being given as unencrypted plain text in config. Please note this is NOT recommended for production environment.Self explanatory
Not able to parse configured property. Will use default value insteadError in config file
IOException while attempting to close remote session {error details}Only occurs on shutdown, no action needed
Could not compute the shared key for pub {public key} and priv REDACTEDPossible cause is that a public key does not match the configured cryptography algorithm.
+ Action: ensure provided key is correct +
Could not create sealed payload using shared key {shared key}Possible cause is that a public key does not match the configured cryptography algorithm.
+ Action: ensure provided key is correct +
Could not open sealed payload using shared key {shared key}Possible cause that wrong password was given for key file decryption or making a change to the values in the keyfile so that the password no longer works.
+ Action: ensure that password is correct for the keyfile +
Unable to generate a new keypair!Internal error - potentially an issue with jnacl dependency
Exception thrown : {exception message} While starting service {service name}Internal error - failed to start a service
Invalid key found {remote host url} recipient will be ignoredRemote key validation check failed.
No action needed, however it is a possible indication of a malicious node
Push returned status code for peer {remote peer url} was {status code}The peer rejected a transaction 'push' request.
+ Action: check logs on peer to see why it failed +
PartyInfo returned status code for peer{remote peer url} was {status code}The peer rejected a partyInfo request.
+ Action: check logs on peer to see why it failed
Unable to resend payload to recipient with public key {public key}, due to {error details}The peer rejected a transaction push request during a resend operation.
+ Action: check reason message, or logs on peer to see why it failed +
Attempt is being made to update existing key with new url. Please switch on remote key validation to avoid a security breach.Self explanatory
Failed to connect to node {remote node url}, due to {error details}A remote node refused partyinfo request. Can occur if: +
    +
  • remote node is not running
  • +
  • remote node doesn't recognise this node's public key
  • +
  • remote node doesn't have this node's IP registered against a key
  • +
  • etc
  • +
+ Can also be expected to occur when nodes are shutdown/restarted, so not necessarily an error. +
Failed to connect to node {remote node url} for partyInfo, due to {error details}A node failed partyInfo request during resend to peer.
+ Action: check reason message, or logs on peer to see why it failed +
Failed to make resend request to node {remote node url} for key {public key}, due to {error details}Peer communication failed during '/resend' request.
+ Action: check reason message, or logs on peer to see why it failed +
+ +!!! Note + Some messages will be rearranged to correct logging levels in our next release. + + +## To change the default log level + +The level of logging is controlled by the logback configuration file. The default file packaged with Tessera can be seen [here](https://github.com/jpmorganchase/tessera/blob/master/tessera-dist/tessera-launcher/src/main/resources/logback.xml). + +To specify a different logging configuration, pass a customised logback file on the command line using: +`-Dlogback.configurationFile=/path/to/logback.xml` diff --git a/docs/Features/dns.md b/docs/Quorum Features/dns.md similarity index 100% rename from docs/Features/dns.md rename to docs/Quorum Features/dns.md diff --git a/docs/Quorum_Equity_Use_Case.png b/docs/Quorum_Equity_Use_Case.png deleted file mode 100644 index 40d8d287d..000000000 Binary files a/docs/Quorum_Equity_Use_Case.png and /dev/null differ diff --git a/docs/Security/Framework/Quorum Network Security/Nodes/Permissioning/Network Permissioning.md b/docs/Security/Framework/Quorum Network Security/Nodes/Permissioning/Network Permissioning.md deleted file mode 100644 index 53241593e..000000000 --- a/docs/Security/Framework/Quorum Network Security/Nodes/Permissioning/Network Permissioning.md +++ /dev/null @@ -1,42 +0,0 @@ -## Network Permissioning - -Network Permissioning is a feature that controls which nodes can connect to a given node and also to which nodes the given node can dial out to. Currently, it is managed at the individual node level by the `--permissioned` command line flag when starting the node. - -If the `--permissioned` flag is set, the node looks for a file named `/permissioned-nodes.json` . This file contains the whitelist of enodes that this node can connect to and accept connections from. Therefore, with permissioning enabled, only the nodes that are listed in the `permissioned-nodes.json` file become part of the network. If the `--permissioned` flag is specified but no nodes are added to the `permissioned-nodes.json` file then this node can neither connect to any node nor accept any incoming connections. - -The `permissioned-nodes.json` file follows the below pattern, which is similar to the `/static-nodes.json` file that is used to specify the list of static nodes a given node always connects to: - ``` json - [ - "enode://remoteky1@ip1:port1", - "enode://remoteky1@ip2:port2", - "enode://remoteky1@ip3:port3", - ] - ``` - -Sample file: (node id truncated for clarity) - ``` json - [ - "enode://6598638ac5b15ee386210156a43f565fa8c485924894e2f3a967207c047470@127.0.0.1:30300", - ] - ``` - -!!! Note - In the current implementation, every node has its own copy of the `permissioned-nodes.json` file. In this case, if different nodes have a different list of remote keys then each node may have a different list of permissioned nodes - which may have an adverse effect. In a future release, the permissioned nodes list will be moved from the `permissioned-nodes.json` file to a Smart Contract, thereby ensuring that all nodes will use one global on-chain list to verify network connections. - -## Enclave Encryption Technique -The Enclave encrypts payloads sent to it by the Transaction Manager using xsalsa20poly1305 (payload container) and curve25519xsalsa20poly1305 (recipient box). Each payload encryption produces a payload container, as well as N recipient boxes, where N is the number of recipients specified in the `privateFor` param of the Transaction. - - * A payload container contains the payload encrypted with a symmetric key and a random nonce - * A recipient box is the Master Key for the payload container encrypted for the public key of a recipient using a random nonce. (Note that this is basically how PGP works, but using the [NaCl](https://nacl.cr.yp.to/) cryptographic primitives.) - -We currently manually define all public key whitelists, and don’t do automatic rotation of keys, however the system was built to support rotation trivially, by allowing counterparties to advertise multiple keys at once. The tooling to make it seamless and automatic is on the our Roadmap. -We also do not currently have a PKI system, but simply randomly generate keys that are manually added to whitelists (e.g. a registry of authorized counterparties on the blockchain.) The process is currently for operators to generate a keypair and then add the public keys to the whitelists manually. - -## Private Key Storage Algorithm -The following steps detail the technique used to manage the private keys: - - 1. Given a password P - 2. Generate random Argon2i nonce - 3. Generate random NaCl secretbox nonce - 4. Stretch P using Argon2i (and the Argon2i nonce) into a 32-byte master key (MK) - 5. Encrypt Private key in secretbox using secretbox nonce and Argon2i-stretched MK diff --git a/docs/Wizard/GettingStarted.md b/docs/Wizard/GettingStarted.md index 4b314839f..576f3d020 100644 --- a/docs/Wizard/GettingStarted.md +++ b/docs/Wizard/GettingStarted.md @@ -1,5 +1,5 @@ ## Quorum Wizard -[Quorum Wizard](https://github.com/jpmorganchase/quorum-wizard) is a command line tool that allow users to set up a development Quorum network on their local machine in less than 2 minutes. +[Quorum Wizard](https://github.com/jpmorganchase/quorum-wizard) is a command line tool that allows users to set up a development Quorum network on their local machine in less than 2 minutes. ![](docs/quorum-wizard.gif) diff --git a/docs/ZSL-Quorum-POC_Protocol_v0_4.png b/docs/ZSL-Quorum-POC_Protocol_v0_4.png deleted file mode 100644 index 5b4e1e50f..000000000 Binary files a/docs/ZSL-Quorum-POC_Protocol_v0_4.png and /dev/null differ diff --git a/docs/ZSL.md b/docs/ZSL.md deleted file mode 100644 index a81772e74..000000000 --- a/docs/ZSL.md +++ /dev/null @@ -1,97 +0,0 @@ -# ZSL Proof of Concept - -!!! caution - The POC discussed in this section should not be considered production-ready - -## Overview -Quorum supports both Public Contracts (which are executed in the standard Ethereum way, and are visible to all participants in the distributed ledger) and Private Contracts (which are shared between the parties to the private contract using Tessera, but can not be read by other participants). This approach preserves the privacy of the parties to the private contract, and the confidentiality of the private contract’s business logic. However, a key limitation is that it does not support prevention of double-spending for digital assets that are exchanged within private contracts. - -ZSL (zero-knowledge security layer) is a protocol designed by the team behind Zcash, that leverages zk-SNARKS to enable the transfer of digital assets on a distributed ledger, without revealing any information about the Sender, Recipient, or the quantity of assets that are being transferred. - -J.P. Morgan and the Zcash team partnered to create a proof of concept (POC) implementation of ZSL for Quorum, which enables the issuance of digital assets using ZSL-enabled public smart contracts (z-contracts). We refer to such digital assets as “z-tokens”. Z-tokens can be shielded from public view and transacted privately. Proof that a shielded transaction has been executed can be presented to a private contract, thereby allowing the private contract to update its state in response to shielded transactions that are executed using public z-contracts. - -This combination of Tessera’s private contracts with ZSL’s z-contracts, allows obligations that arise from a private contract, to be settled using shielded transfers of z-tokens, while maintaining full privacy and confidentiality. - -For more background, please read the [POC Technical Design Document](https://github.com/jpmorganchase/zsl-q/blob/master/docs/ZSL-Quorum-POC_TDD_v1.3pub.pdf). - -## Implementation -The ZSL proof of concept has been implemented as follows: - -* ZSL-specific code resides in the [zsl-q](https://github.com/jpmorganchase/zsl-q) repo -* The Quorum integration is implemented as a separate branch of the Quorum repo - [zsl_geth1.5](https://github.com/jpmorganchase/quorum/tree/zsl_geth1.5) -* There is also a ZSL-specific branch of the quorum-examples repo - [zsl_geth1.5](https://github.com/jpmorganchase/quorum-examples/tree/zsl_geth1.5) -* The [zsl-q-params](https://github.com/jpmorganchase/zsl-q-params) repo contains the shared parameters required for generating and verifying the zk-SNARK proofs. - -Full instructions on how to install Quorum with ZSL can be found in the [zsl-q README](https://github.com/jpmorganchase/zsl-q/blob/master/README.md). - -Please note that this POC is intended to demonstrate how ZSL can complement Quorum, and provide a platform for experimentation and exploration of different use cases. It implements a simplified, stripped-down version of the Zerocash protocol to enable rapid prototyping. There is no formal security proof for the protocol, exception-handling has not been implemented for proof verification, the software has not been subjected to rigorous testing, and **it should not be considered “production-ready”**. - -Broadly speaking, Quorum ZSL supplies a contract within which virtual funds can be "bundled" into cryptographically obfuscated "notes". Each note represents a store of value, and can be unlocked, or "redeemed", only using a secret spending key. To effect a private transfer, Alice may bundle value into a note, and then transmit the note's secret key to Bob through a private, off-chain channel. Bob may then redeem this note on-chain, revealing, in the process, no public link between Alice and himself. Note that in a previous version, a failure to link _Ethereum_ and _note_ signatures made possible a sort of "front-running" attack; this has been fixed by PR [#587](https://github.com/jpmorganchase/quorum/pull/587). - -## Equity Trade use case example -The following example illustrates a specific use case for Quorum with ZSL - a simple equity trade where Alice is buying ACME shares from Bob. The POC includes a demonstration that implements this example; instructions on how to run it can be found [here](https://github.com/jpmorganchase/zsl-q/blob/master/README.md#example-2---private-contract-trade). - -![Quorum Equity Trade Use Case diagram](Quorum_Equity_Use_Case.png) - -### Beginning State: -* Z-contracts have been created for US dollars (the USD z-contract) and ACME shares (the ACME z-contract), -* Z-tokens have been issued into both contracts by the relevant issuer, then shielded and transferred to Alice and Bob. -* Alice owns some USD z-tokens, and Bob owns some ACME z-tokens. Both their holdings are shielded (i.e. a third-party observer cannot tell who owns what). - -### User Story: -1. **A Private Contract is established between Alice and Bob using Tessera.** - 1. The Private Contract specifies an equity trade of a specific quantity of ACME shares at a specific price in USD, between two specific parties: Alice (who is buying the ACME shares) and Bob (who is selling ACME shares). - 1. The Private Contract references the USD and ACME z-contracts, and the relevant public keys and payment addresses of the parties. - 1. One party initialises the contract (this is the equivalent of bidding/offering). It doesn't matter which party does this - in this example, it's Alice. - 1. After being initialised, the contract state is "Bid" (it would be "Offer" if Bob had initialised it). - -2. **The other party sends the Private Contract a transaction indicating acceptance of the terms.** - 1. In this example, it is Bob who accepts Alice’s bid. - 1. At this point, the trade is "done" (i.e. the terms are agreed and both parties have committed to the trade) and all that remains is for Settlement to take place. Assume that the USD must be paid first. - 1. Contract state: Done. - -3. **The Private Contract instructs Payment.** - 1. When the contract's status updates to Done, it issues an instruction to the Buyer's (i.e. Alice’s) client to pay the relevant amount of USD to the Seller (Bob). - 1. Alice's client receives and queues that instruction, and instructs a shielded payment. - -4. **The Buyers pays USD to the Seller.** - 1. Alice pays the relevant amount of USD z-tokens to Bob's USD payment address by generating the necessary zk-SNARK proof and sending it to the USD z-contract. - 1. A shielded transaction takes place, creating a note within the z-contract which only Bob can spend (i.e. Bob’s USD z-token balance is increased). - 1. Alice’s balance of USD z-tokens is reduced accordingly. - -5. **The Buyer provides evidence of payment to the Private Contract.** - 1. Alice sends the Private Contract a transaction with the output note of the USD payment. - 1. This also transmits the note to Bob so he can spend it. - -6. **The Private Contract verifies the payment.** - 1. The Private Contract calls a constant function on the USD z-contract, using the note supplied by Alice, to verify that the payment is valid. - 1. The z-contract responds in a binary fashion to indicate whether the note commitment is in the z-contract’s note accumulator (in which case the shielded payment is valid) or not. - 1. If it is valid, the contract's status updates to Payment Received, and... - -7. **..the Private Contract instructs Delivery.** - 1. The Private Contract issues an instruction to the Seller's (i.e. Bob’s) client to transfer the relevant amount of ACME shares to the Buyer - 1. Bob's client receives and queues that instruction, and prompts him to make the payment. - -8. **The Seller delivers ACME shares to the Buyer.** - 1. Bob transfers the relevant amount of ACME z-tokens to Alice's ACME payment address by generating the necessary zk-SNARK proof and sending it to the ACME z-contract. - 1. A shielded transaction takes place, creating a note output that only Alice can spend (i.e. Alice’s ACME z-token balance is increased). - 1. Bob’s balance of ACME z-tokens is reduced accordingly. - -9. **The Seller provides evidence of delivery to the Private Contract** - 1. Bob sends the Private Contract a transaction with the output note of the ACME delivery. - 1. This also transmits the note to Alice so she can “spend” the note (i.e. transfer those tokens to someone else). - -10. **The Private Contract verifies delivery.** - 1. The Private Contract calls the ACME z-contract (using a constant function), using the note supplied by Bob, to verify that the transfer is valid. - 1. If it is valid, the contract's status updates to Settled. - -After Alice has delivered the USD z-tokens to Bob in step 5, he can send them to a third party (e.g. Carol). - - * Carol will not be able to ascertain the source of the tokens (i.e. that Bob obtained them from Alice). - * Alice will not be able to ascertain when Bob transfers the tokens to someone else (or who the recipient is). She will be able to see that a transaction has occurred (because the transaction is written to the z-contract on the main Quorum chain which she has access to) but she will not be able to ascertain the Sender, Recipient, nor the quantity of tokens being transferred. - * The same holds true for the ACME z-tokens Alice has obtained from Bob. - -### Protocol -The diagram below illustrates how the cryptographic protocol supports steps 1 thru 6 from the example above. - -![ZSL/Quorum Proof of Concept Protocol (v0.4)](ZSL-Quorum-POC_Protocol_v0_4.png) diff --git a/docs/quorum.js/Overview.md b/docs/quorum.js/Overview.md new file mode 100644 index 000000000..049ad1fd7 --- /dev/null +++ b/docs/quorum.js/Overview.md @@ -0,0 +1,12 @@ +# quorum.js + +## Overview, Installation, Quickstart & Examples +See the [project page README](https://github.com/jpmorganchase/quorum.js). + +## API +This documentation provides additional usage and API information not included in the README. + +quorum.js exports two modules: + +* [`extend`](../extend) +* [`rawTransactionManager`](../rawTransactionManager) diff --git a/docs/quorum.js/RawTransactionManager.md b/docs/quorum.js/RawTransactionManager.md new file mode 100644 index 000000000..79a65b530 --- /dev/null +++ b/docs/quorum.js/RawTransactionManager.md @@ -0,0 +1,164 @@ +The `RawTransactionManager` module of quorum.js provides access to private transaction APIs that require a connection to a [Privacy Manager](../../Privacy/Privacy-Manager). + +## Example +```js +const Web3 = require("web3"); +const quorumjs = require("quorum-js"); + +const web3 = new Web3("http://localhost:22000"); + +const tlsOptions = { + key: fs.readFileSync("./cert.key"), + clcert: fs.readFileSync("./cert.pem"), + cacert: fs.readFileSync("./cacert.pem"), + allowInsecure: false +}; +const enclaveOptions = { + privateUrl: "http://localhost:9081", + tlsSettings: tlsOptions +}; + +const txnMngr = quorumjs.RawTransactionManager(web3, enclaveOptions); + +txnMngr.sendRawTransaction(args); +``` + +## Parameters +| param | type | required | description | +| :---: | :---: | :---: | --- | +| `web3` | `Object` | yes | web3 instance | +| `enclaveOptions` | `Object` | yes | Privacy Manager connection configuration - see [enclaveOptions](#enclaveoptions) | + +### enclaveOptions +| param | type | required | description | +| :---: | :---: | :---: | --- | +| `privateUrl` | `String` | yes (unless `ipcPath` is provided) | Tessera `ThirdParty` server url (if using the Constellation Privacy Manager use `ipcPath` instead) | +| `ipcPath` | `String` | no | path to Privacy Manager `.ipc` socket file, `privateUrl` is preferred | +| `tlsSettings` | `Object` | no | TLS configuration for HTTPS Privacy Manager connections - see [tlsSettings](#tlssettings) | + +### tlsSettings +| param | type | required | description | +| :---: | :---: | :---: | --- | +| `key` | `String` | no | client private key as byte string | +| `clcert` | `String` | no | client certificate (signed/unsigned) as byte string | +| `cacert` | `String` | no | CA certificate as byte string | +| `allowInsecure` | `boolean` | no | do not verify the Privacy Manager's certificate (can be used to allow self-signed certificates) | + +## Methods + +### sendRawTransaction + +!!! info "If using Constellation" + Constellation privacy managers do not support this method. Use [`sendRawTransactionViaSendAPI`](#sendrawtransactionviasendapi) instead. + +```js +txnMngr.sendRawTransaction(txnParams); +``` +Calls Tessera's `ThirdParty` `/storeraw` API, replaces the `data` field in `txnParams` with the response (i.e. encrypted-payload hash), signs the transaction with the `from` account defined in `txnParams`, marks the transaction as private, RLP encodes the transaction in hex format, and submits the signed transaction to the blockchain with `eth_sendRawPrivateTransaction`. + +#### Parameters +1. `txnParams` - The transaction to sign and send + - `gasPrice`: `Number` - Must always be 0 in Quorum networks + - `gasLimit`: `Number` - The amount of gas to use for the transaction + - `to`: `String` - (optional) The destination address of the message, left undefined for a contract-creation transaction + - `value`: `Number` - (optional) The value transferred for the transaction + - `data`: `String` - (optional) Either a byte string containing the associated data of the message, or the initialisation code (bytecode) in the case of a contract-creation transaction + - `from` - `Object`: [Decrypted account object](https://web3js.readthedocs.io/en/v1.2.7/web3-eth-accounts.html#decrypt) + - `nonce`: `Number` - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce + - `privateFrom`: `String` - When sending a private transaction, the sending party's base64-encoded public key to use. If not present *and* passing `privateFor`, the default key as configured in the `TransactionManager` is used + - `privateFor`: `List` - When sending a private transaction, an array of the recipients' base64-encoded public keys + - `isPrivate`: `boolean` - Is the transaction private +1. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. + +#### Returns +A promise that resolves to the transaction receipt if the transaction was sent successfully, else rejects with an error. + +### sendRawTransactionViaSendAPI + +!!! info "If using Tessera" + Tessera privacy managers support [`sendRawTransaction`](#sendrawtransaction) which should be used instead. `sendRawTransactionViaSendAPI` requires exposing the `Q2T` server to the `js` app. Ideally only the `ThirdParty` server should be exposed to such applications. + +```js +txnMngr.sendRawTransactionViaSendAPI(txnParams); +``` + +Calls Privacy Manager's `/send` API to encrypt txn data and send to all participant Privacy Manager nodes, replaces `data` field in `txnParams` with response (i.e. encrypted-payload hash), signs the transaction with the `from` account defined in `txnParams`, marks the transaction as private, and submits the signed transaction to the blockchain with `eth_sendRawTransaction`. + +#### Parameters +1. `txnParams` - The transaction to sign and send + - `gasPrice`: `Number` - Must always be 0 in Quorum networks + - `gasLimit`: `Number` - The amount of gas to use for the transaction + - `to`: `String` - (optional) The destination address of the message, left undefined for a contract-creation transaction + - `value`: `Number` - (optional) The value transferred for the transaction + - `data`: `String` - (optional) Either a byte string containing the associated data of the message, or the initialisation code (bytecode) in the case of a contract-creation transaction + - `from` - `Object`: [Decrypted account object](https://web3js.readthedocs.io/en/v1.2.7/web3-eth-accounts.html#decrypt) + - `nonce`: `Number` - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce + - `privateFrom`: `String` - When sending a private transaction, the sending party's base64-encoded public key to use. If not present *and* passing `privateFor`, the default key as configured in the `TransactionManager` is used + - `privateFor`: `List` - When sending a private transaction, an array of the recipients' base64-encoded public keys + - `isPrivate`: `boolean` - Is the transaction private +1. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. + +#### Returns +A promise that resolves to the transaction receipt if the transaction was sent successfully, else rejects with an error. + +### setPrivate +```js +txnMngr.setPrivate(rawTransaction); +``` +Marks a signed transaction as private by changing the value of `v` to `37` or `38`. +#### Parameters +1. `rawTransaction`: `String` - RLP-encoded hex-format signed transaction +#### Returns +Updated RLP-encoded hex-format signed transaction + +### storeRawRequest +```js +txnMngr.storeRawRequest(data, privateFrom); +``` +Calls Tessera's `ThirdParty` `/storeraw` API to encrypt the provided `data` and store in preparation for a `eth_sendRawPrivateTransaction`. + +#### Parameters +1. `data`: `String` - Hex encoded private transaction data (i.e. value of `data`/`input` field in the transaction) +1. `privateFrom`: `String` - Sending party's base64-encoded public key + +#### Returns +A promise that resolves to the hex-encoded hash of the encrypted `data` (`key` field) that should be used to replace the `data` field of a transaction if externally signing. + +### sendRawRequest +```js +txnMngr.sendRawRequest(rawTransaction, privateFor); +``` +Call `eth_sendRawPrivateTransaction`, sending the signed transaction to the recipients specified in `privateFor`. +#### Parameters +1. `rawTransaction`: `String` - RLP-encoded hex-format signed transaction +1. `privateFor`: `List` - List of the recipients' base64-encoded public keys + +#### Returns +A promise that resolves to the transaction receipt if the transaction was sent successfully, else rejects with an error. + +## Examples + +### Externally signing and sending a private tx + +!!!info + This is not supported by Constellation and requires Quorum v2.2.0+ + +[Code sample](https://github.com/jpmorganchase/quorum.js/blob/master/7nodes-test/deployContractViaHttp-externalSigningTemplate.js). + +1. `storeRawRequest` to encrypt the transaction `data` + ```js + txnManager.storeRawRequest(data, from) + ``` +1. Replace `data` field of transaction with `key` field from `storeRawRequest` response +1. Sign the transaction +1. Mark the signed transaction as private with `setPrivate` + ```js + txnManager.setPrivate(signedTx) + ``` +1. Send the signed transaction to Quorum with `sendRawRequest` + ```js + txnManager.sendRawRequest(serializedTransaction, privateFor) + ``` + +### Other examples +The [7nodes-test](https://github.com/jpmorganchase/quorum.js/tree/master/7nodes-test) directory in the quorum.js project repo contains examples of quorum.js usage. These scripts can be tested with a running [7nodes test network](https://github.com/jpmorganchase/quorum-examples/tree/master/examples/7nodes). \ No newline at end of file diff --git a/docs/quorum.js/extend.md b/docs/quorum.js/extend.md new file mode 100644 index 000000000..1de940e53 --- /dev/null +++ b/docs/quorum.js/extend.md @@ -0,0 +1,21 @@ +The `extend` module of quorum.js allows Quorum-specific APIs to be added to an instance of `web3`. + +## Example +```js +const Web3 = require("web3"); +const quorumjs = require("quorum-js"); + +const web3 = new Web3("http://localhost:22000"); + +quorumjs.extend(web3); + +web3.quorum.eth.sendRawPrivateTransaction(signedTx, args); +``` +## Parameters +| param | type | required | description | +| :---: | :---: | :---: | --- | +| `web3` | `Object` | yes | web3 instance | +| `apis` | `String` | no | comma-separated list of APIs to extend `web3` with. Default is to add all APIs, i.e. `quorumjs.extend(web3, 'eth, raft, istanbul, quorumPermission')` | + +## Methods +See the [Raft](../../Consensus/raft/raft-rpc-api), [Istanbul](../../Consensus/ibft/istanbul-rpc-api/), [Privacy](../../Getting%20Started/api/#privacy-apis), and [Permissioning](../../Permissioning/Enhanced%20Permissions%20Model/Permissioning%20apis) API documentation for API details. diff --git a/docs/theme/partials/footer.html b/docs/theme/partials/footer.html index 5200de545..35f12f011 100644 --- a/docs/theme/partials/footer.html +++ b/docs/theme/partials/footer.html @@ -2,7 +2,7 @@