This Draft Specification is copyright © 2022
Enterprise Ethereum Alliance Incorporated (EEA).
It is made available under the terms of the
Apache License version 2.0.
This is an editors' draft of material that might be developed into
Enterprise Ethereum Alliance Permissined Blockchain Deployment Guidance.
It has not been approved for publication by the Enterprise Ethereum Alliance (EEA)
Core Specifications Working Group nor anyone else.
It is not appropriate to quote or reference this document except as
"Work in Progress", and it should be considered unreliable and unstable in its present state.
Please send any comments to the EEA Technical Steering Committee at
This document describes good practices and information that is useful when deploying
an Enterprise Ethereum permissioned blockchain.
Enterprise Ethereum is the set of enterprise-focused extensions to
public Ethereum that are defined in the Enterprise Ethereum Alliance
Client Specification [[EEA-clients]]. These extensions provide the ability
to perform private transactions, and enforce access controls (permissioning),
for Ethereum blockchains that use them. Such blockchains are formally known as
Enterprise Ethereum Permissioned Blockchains.
Public Ethereum is the public
blockchain-based distributed computing platform featuring smart contract
(programming) functionality defined by the [[Ethereum-Yellow-Paper]], [[EIPs]],
and associated specifications. The mainnet is a public ethereum
blockchain, with `chainId` and `NetworkId` values of 1.
There are other public ethereum blockchains, usually with slightly different
characteristics. For example "testnets" like Ropsten, Rinkeby, and Goerli
are all used to test Ethereum technnology.
About the EEA Client Specification
The Enterprise Ethereum Client Specification [[EEA-clients]] defines
the implementation requirements for Enterprise Ethereum clients,
including the interfaces to external-facing components of
Enterprise Ethereum and how they are intended to be used.
A partial list of the use cases [[EEA-client-usecases]] that specification attempts to address
is available, as an editors' draft for a work in progress.
A companion document, the Enterprise Ethereum Alliance Permissioned Blockchains Specification
[[EEA-chains]] defines requirements for Enterprise Ethereum blockchains to ensure that
clients that conform to the Client Specification can work interopably on blockchains
that meet the requirements defined in that document.
The Client Specification includes requirements and APIs that are described as
This means that a requirement or API is in early stages of development
and might change as feedback is incorporated.
Implementors are encouraged to implement these experimental requirements,
with the knowledge that requirements in future versions of the Specification
are not guaranteed to be compatible with the current version.
Please send comments and feedback on experimental portions of the Specification
to the EEA via [https://entethalliance.org/contact/](https://entethalliance.org/contact/).
Difference to public Ethereum Blockchains
An Enterprise Ethereum Permissioned Blockchain extends the standard capabilities
of Ethereum with the following changes:
An Enterprise Ethereum Client is required to implement a form of private transaction;
either restricted private transactions or unrestricted private transactions.
Enterprise Ethereum clients implement the `eea_sendTransaction` and
`eea_sendRawTransaction` JSON-RPC-API methods to submit private transactions to the blockchain.
- Restricted Private Transactions
- Transactions communicated directly between the parties involved.
These are notarised in a marker transaction on the blockchain,
that records a transaction took place, but does not contain the details
of the transaction. Instead, those details are only available to nodes that are party
to the transaction.
- Unrestricted Private Transactions
- Transactions that are recorded on the blockchain, but only parties to the
transaction have the necessary information to interpret the full meaning
of the transaction, using a mechanism such as zero-knowledge proofs.
The Enterprise Ethereum client specification defines a standard form of
Network Configuration Parameters, using a JSON object in the genesis block that
Enterprise Ethereum Clients are required to interpret.
The Enterprise Ethereum-specific parameters defined are:
- The maximum size of a smart contract to be valid for deployment.
It can either specify an integer, which means a number of kilobytes,
or a JSON object describing limits applied for a range of blocks,
to enable nodes to correctly validate when trying to sync an existing
blockchain where the value has changed over time.
- The address to use when calling the connectionAllowed method.
- This specifies the address to use when calling the transactionAllowed method.
- The optional
- The address of an Organization Registry contract, if there is one.
Conforming Enterprise Ethereum Clients implement the Byzantine Fault-tolerant [[QBFT]]
Consensus Algorithms defined by the EEA, and the Clique Proof of Authority algorithm defined in [[EIP-225]].
Most clients implement more consensus algorithms. Clients
that also operate on the pre-merge MainNet need to implement EthHash (Proof of Work).
An Enterprise Ethereum Permissioned blockchain can implement an
This is a contract defined in the chainspec [[EEA-chains]] that establishes if an account
is acting on behalf of a known organization.
Implementations might provide
enabling convenience of interaction through additional language bindings. These
libraries might include [[web3j]], [[web3.js]], [[Nethereum]],
[[protocol-buffers]], or a REST API.
Enterprise Management Systems
Performance and Scalability
Performance is important to many (but not all) Enterprise Ethereum use cases.
However, performance is multidimensional; attempts to require specific
performance targets on a single aspect generally leads to all implementations
being optimised for that target instead of meeting the varying needs of
Enterprise Ethereum customers.
There are some common goals however. Specifically, increasing the cost of a
blockchain over time is incompatible with many use cases, and many use cases
need to ensure significant scalability is feasible.
Constant Power Requirements
The computing power to validate blocks is meant to remain constant over time,
regardless of the blockchain size or the number of network participants. The
constant power requirements include:
- Ensuring the power required to validate a block does not increase
Off-chain processing is a mechanism that can improve scalability. Likewise,
Sharding, a mechanism proposed for Ethereum 2.0, will probably improve
Storage and Ledger Sublayer
Implementations might implement data storage used for optional off-chain
operations. For example, implementations could locally choose to cache the
results from a trusted oracle or store information related to other systems
extensions not covered by the
Persistent storage that is resistant to brute force attacks generally uses a
"defense-in-depth" approach. For example, instead of relying on restricted access
to protect plain text storage, an implementation can further protect the data
by encrypting it with an Authenticated Encryption with Additional Data (AEAD) algorithm,
such as one described in [[RFC5116]].
## Blockchain deployment and operations
In this chapter, we will discuss blockchain deployment and operation principles.
The initial goal of blockchain is to remove intermediates and run without interference of other agents, maximizing independence of hardware, network and software.
In short order, blockchain software should run on different machines in different locations, hosted by different providers (ideally self-hosted), running different implementations of the blockchain protocol.
The goal is to mimic the structure of the Internet, where there is enough information redundancy that it would be possible for the blockchain network to survive a rift of connections.
A blockchain client - the name of the software interfacing with the chain - is meant to run in an adversarial environment, where every piece of information it encounters must be validated. The only information initially provided is the genesis block of the chain. The software syncs up all blocks and recomputes the state of the chain from scratch.
Operators typically migrate between nodes by spinning up a new node and allowing the new node to sync with the existing node.
Blockchain nodes use a cryptographic identity to identify themselves on the network. When the chain starts, the node exposes this identity. Blockchain networks communicate boot nodes that allow users to enter the network and discover additional peers.
Separately, Blockchain nodes can contain the cryptographic identity of the user operating the chain. In that case, the key is stored as a file alongside the data of the chain. The user has to unlock their account upon starting the software.
Alternatively, users can use a separate wallet to sign their transactions and only send validated and signed transactions to the chain. This method provides additional security to transactions as well.
Public chain clients connect to initial boot nodes, which help them discover new nodes, from which they can get entrance to the network and peer randomly, ensuring that they are not peered with a super-majority of dishonest nodes.
In private chains, discovery is typically disabled. Instead, all peers know of all other peers at startup through a configuration file. The configuration file contains the IP, port and public key of the peers. Additional peers can be added at runtime through a command.
### Private blockchain considerations
#### Private enclave
Quorum adds one more layer of communications with the addition of a private enclave. Private enclaves communicate with all other private enclaves on the network, using point-to-point communications. Private enclaves hold keys to store private data associated with the private state held by the instance.
#### Private blockchain consensus algorithms
Quorum uses consensus algorithms such as Raft, Clique or IBFT. They all require different types of uptime:
- Clique requires 100% uptime of the signer node, or no blocks can be accepted
- Raft requires a leader to be elected, which requires a minimum of 3 nodes to perform the election. If the leader experiences downtime, the vote restarts.
- IBFT is meant to remain reliable if two thirds of the validators are able to cast votes.
Additionally, Clique and IBFT strongly tie the consensus to the identity of the clients running the network.
All those considerations play a role in picking the right algorithm for your blockchain.
### Example of a private blockchain deployment
- A consortium of four companies assembles to create shared infrastructure in the form of a blockchain. They elect to use Raft as its consensus algorithm.
- Each participant runs a blockchain node.
- They all deploy independently the software on machines they own, and send to each other the IP, port, and public key of their nodes.
- They decide on an initial genesis block, allocating funds to each member. They create a genesis block file. They also create a static nodes file. All members use both files to configure their clients and turn on their blockchain.
- Once the chain is able to function, they configure private enclaves that connect to their blockchain node. They share their private enclave IP and port and use it as part of the configuration of their enclaves, so they can connect directly.
- They now turn on their private enclave and node and can start exchanging data.
### Deployment lifecycle
#### Initial deployment
Smart contracts have the opportunity to set permissions during the initialization phase of the contract. Typically, the account that deploys the contract is set as the owner. It is possible to create more complex situations with multiple owners.
#### Proxy contracts
Whenever a contract is upgraded, it changes its address. Therefore, it is very important to use a proxy contract that will allow it to keep the same address for all peers. In the same way, a contract should use an interface to control access to its public methods. This interface should not change. Instead, the contract should adopt additional interfaces if necessary.
## Interfacing with blockchain software
Ethereum clients expose to users an interface which accepts JSON payloads and responds with JSON data, over HTTP, websockets, or UNIX file socket.
### Querying data on chain
Users may write solidity and invoke contract functions marked with the modifier “view” to execute read-only functions. The EVM executes the query and returns the output of the execution against the local node state.
### Executing transactions
Users also may send transactions to be included in blocks. They can either send a signed transaction, or submit a transaction to be signed on one of the accounts on the blockchain node.
Ethereum identifies different types of transactions:
- Deploying a contract
- Sending funds between accounts
- Invoking contract functions
## Developing against a blockchain
web3.js and ethers.js are popular frameworks used by Ethereum to connect via JSON-RPC and perform operations transparently. They allow deployment of contracts, execution of transactions, and more as described below.
It is strongly advised to connect to a blockchain node from server-side rather than client-side, as users browsers are insecure environments, and they can close a browser window while an operation is ongoing.
## Project structure
We recommend, as much as it is possible, to use a single code repository for all assets. Assets generally consist of smart contracts, backend code, frontend application and deployment scripts, alongside unit tests for all components, documentation and integration tests.
### Code contributions
Code contributions to the project must be made as pull requests, so the functionality is tracked as a single set of commits. Each contribution should run tests to ensure its validity, and be reviewed and approved for merge by a team member.
Releases should primarily consist of a tag of the git repository.
Any package made from the repository should be signed by the developer’s GPG key and its signature should be outlined next to the download file.
### Blockchain smart contract security testing
- Perform static analysis with [Slither](https://github.com/crytic/slither).
- Run the smart contracts through [Mythx](https://mythx.io/) to review them, so they can be flagged for vulnerabilities. If the development team uses Mythx, ask for the report.
- In particular, check any math. All math operations should use [OpenZeppelin libraries](https://github.com/OpenZeppelin/openzeppelin-contracts) to perform safe math.
- Run through functional testing and make sure all functionality requested works as expected.
### Network testing
Network testing consists in checking the security of the network against attackers.
Tools such as Nessus or Qualys perform network tests by checking for open ports and validating the TLS and SSL cryptographic algorithms allowed to connect to the system.
### Migrations testing
- Check the delta between the two releases in patch form. Make sure the changes make sense.
- Check that sources can be built and match the binaries obtained. Ideally, the build process should generate binaries and archives that have the same hash as the binaries provided.
- Open the smart contracts in VSCode (see [this guide](https://www.trufflesuite.com/tutorials/configuring-visual-studio-code)).
- [Install SOLC](https://solidity.readthedocs.io/en/v0.5.3/installing-solidity.html) (use the same version as used in development)
- Run: `solc --abi --bin /path/to/contracts/file.sol`
- This will generate the bytecode and ABIs.
- Check that the bytecode matches what is deployed.
## Blockchain operations
### Setting up machines
#### Encryption at rest
All machines must use disk encryption at rest, so hard drives cannot be retrieved and read elsewhere by a malicious attacker.
#### Static IPs
The location of a node will be advertised directly by the public IP it advertises on the Internet, especially for public networks. For private blockchains, it’s just as important to have fixed IPs for all nodes available. If using a cloud provider such as AWS, node operators must use a static IP assignment. The DNS name of the machine matters little for peer-to-peer networking as most blockchains do not rely on DNS for discovery.
#### Machine sizing
A typical machine hosting a blockchain should prioritize fast I/O, especially when syncing large states for Ethereum mainnet. SSD disks are necessary.
At least 2 CPUs are necessary to run crypto verifications and secure the network.
A minimum of 8Gb of RAM is advised, especially if the system runs a private enclave such as Tessera.
When running an Ethereum node, the machine should expose the following ports:
- 30303 UDP and TCP for Ethereum traffic
- 8545/8546 for HTTP and WS traffic
- 9000 for the private enclave, if running Quorum
Please note all those ports can be configured to different values as needed.
Ports 8545 and 8546 must be protected from attackers trying to gain access to the JSON-RPC port. If all applications run on the same machine, this port can be closed. Otherwise, it should only be opened to applications running in the same network.
Ports 30303 and 9000 must be available to all other nodes in the network. In the case of a private blockchain deployment, one can set stringent network rules to only allow access to other members. Note additional members may be added over time and those rules will need to be updated as such events occur.
### Securing keys
Keys are irreplaceable in cryptographic systems. They must be protected at all times.
Operators can choose options here, going from least to most stringent.
- Store the key as a mnemonic sequence of words (as described in [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)) in a password manager such as 1Password.
- Use GPG to encrypt the key and share the key with other team members, encrypted with their GPG key for backup.
- Use a cold wallet to store the key. Once set, it never leaves the wallet. The cold wallet must be inserted into a computer to sign content.
- Use a hardware security module (HSM) server that is deployed in a physical data center.
- Use Unbound Key Control system to automate the lifecycle of the key management.
### Genesis block generation
Each network must start with a common genesis block generated initially by an operator. This operation is generally done manually with a text editor.
The genesis block is written in JSON and encodes initial information about the network, allocating money to accounts and initializing state and code for accounts.
An [example of genesis block](https://github.com/ConsenSys/quorum-examples/blob/master/examples/7nodes/genesis.json)
### Static peer configuration
All peers must connect to each other using a configuration file listing all IPs, ports and public keys of each of the nodes. In the case of Ethereum, the static node configuration files contains a JSON array with a list of strings, each string representing the encoded URL of a node, starting with the enode scheme.
## Maturity model
This maturity model is provided to help apply the best practices in this document, with the explicit goal of creating discussions around the development and operations of blockchain-based software.
We first introduce the dimensions of our maturity model, and offer a checklist to help understand the maturity of the software across each dimension.
For each dimension, the checklist will offer a deterministic measure and will allow to list a mitigation that can be fulfilled by the team.
There is some overlap between dimensions, and a particular requirement may come up in a different context. In that case however, different mitigations can be offered.
### Maturity model requirement template
A requirement will have the following attributes:
- **Identifier**: a unique identifier allowing to refer to the requirement
- **Recurrence**: a recurring time period to review the requirement
- **Definition**: the formal description of the requirement
- **Example**: an example of implementation of the requirement
This section of the maturity model deals with the security measures and processes in place to secure the blockchain deployment and operation of the solution.
It concerns the aspects of the physical and operating system operations, its networking, up to the smart contract setup and permission system, as well as how the application interfaces with it.
This section of the maturity model evaluates how much the team running the blockchain can operate independently from the other participants of the blockchain. It concerns everything from the choice of consensus algorithm, the network connectivity and information to other participants to the deployment and ownership of smart contracts.
This section evaluates how flexible the deployment is, and how easy it is to change the deployment to match changes to the business and operating requirements of the solution.
The checklist covers every aspect of the business requirements changes, such as adding a new partner to the chain or changing a smart contract to reflect a new business flow.
##Maturity model checklist
**Data is stored on hard drives encrypted at rest**
"The team sets up machines in the cloud environment with encryption enabled at rest.
Every year, the team conducts an audit to make sure all volumes are set to be encrypted at rest.
When a volume is found to be unencrypted, the team backs up the data and create a new volume."
**Networking limits access to specific ports**
The team relies on an Infrastructure as code tool such as Terraform to enforce which ports are open. The team runs checks annually to make sure the configuration is adequate and no extra ports are open.
**All private keys are secured**
The team assigns a chain of responsibility and document their practices with regards to keys. Every quarter, they review and train on their keys. If they use passwords to secure the keys, they rotate them at the same time.
**Key custody processes are implemented.**
The team gives access explicitly to keys to a specific member of the team for a specific period of time. Keys are always stored encrypted and password protected.
**The team implements and runs network security tests**
The team maintains a set of tests to test the network of the solution. Every quarter, the team runs those tests, using network testing tools, to ensure all tests pass. Whenever a change is made to the solution, network tests run on a staging environment before deployment to production.
**The team implements and runs smart contract tests**
The team maintains a set of tests to test the smart contracts of the solution. Those tests run for each change to smart contracts as part of continuous integration. Functional tests also check the behavior of the system as a whole, and run for each release.
**The team implements and tests for software defects**
The team maintains a set of unit tests to test the solution. Those tests run for each change to the code as part of continuous integration.
The team also maintains integration tests that run against a staging environment.
**The team collects and analyzes logs**
The team collects logs and analyzes them weekly, looking for specific error codes or error patterns that are documented and shared with the team. Every week, an operator compiles the log analysis and shares it with the team.
**The team backs up and restores data**
The team has developed a way to create backups, and is able to restore them to a different environment. Every month, they reset the staging environment with the latest backup, ensuring the solution is still able to perform by exercising integration tests against it.
### SEC-10 N/A
**All participants in the network (smart contract enclave) must be given access to interact with any smart contract**
The team must manage the database of whitelisted addresses as well as access control - should be built into the smart contracts. An unknown address should not be able to access or edit any data in a smart contract.
**Operators run on different machines**
Operators specify and check in establishing the network that all blockchain clients run on different machines.
**Operators run on different cloud providers**
Operators specify and check in establishing the network that nodes of the network use different cloud providers.
**Operators run in different geographical zones**
Operators specify and check in establishing the network that nodes are dispersed geographically, with at least 2 different zones.
**Operators deploy their own contracts**
Operators deploy the contracts that are under their responsibility.
**Operators can upgrade their own contracts**
Operators have access and can upgrade their contracts at will.
**Operators host the software interfacing with the blockchain**
Operators deploy and host the software interfacing with the JSON-RPC interface of the blockchain, so they may control its direct access.
**Operators can change their network configuration (IP, port) without breaking the network**
Operators check monthly that their IP and port allocations are correct for themselves and all the partners. In the event of a change, they prepare for a migration and changing configuration files at that time and perform that change at the same time as the partners.
**Operators can upgrade their blockchain client without consortium downtime**
Operators run tools to update their blockchain client without suffering downtime. They select to upgrade clients outside of business hours.
**Operators can test the system independently**
Operators perform tests against the system and can stage a copy of the system on their own. They can test that the system performs to function, securely, and with appropriate performance, without involving a partner.
**Operators can upgrade smart contracts at will**
Operators run an automated script that securely allows them to upgrade smart contracts at will. They use a proxy contract so they can change the address of the contract without touching all other contracts. All contracts use interfaces, and are maintained so no breaking changes are introduced.
**Operators have complete vision of the usage and data flowing through the system**
Operators can instantly see what requests are in process in the system, what requests and data exchanges occurred in the last 30 days, and the current data stored in the system.
**Operators can test changes to the system using continuous delivery**
Operators build and maintain a deployment pipeline that deploys automatically changes to a staging environment, where tests run to check the behavior of the system.
**Operators can issue and deploy urgent patches for any part of the system (network, blockchain, software, smart contract)**
Operators can cut new releases with an automated script that requires little input. A release can then be deployed automatically. The whole process takes less than 30 minutes.
**Operators can deploy changes without downtime**
Operators stack changes in sequence to avoid breaking changes that would provoke down time. Developers write backwards-compatible code that is able to work with different versions of the software they interface with. Contracts can be first deployed, then used as part of execution in a separate step.
**Operators can modify the consortium configuration at will**
Operators have full access to the consortium configuration, and can add or remove new peers to the network using configuration files.
Enterprise Ethereum clients might support local key management allowing
users to secure their private keys.
Clients might also support secure interaction with an external key
management system for key generation and secure key storage.
For example, implementations could securely interact with a Hardware
Security Module (HSM), a physical device to provide strong and secure key
generation, key storage, and cryptographic processing for deployments where
strong security is needed.
Permissioning Management Examples
The smart contracts that allow Enterprise Ethereum clients to
apply permissioning require a management system behind them. This section
provides some examples of how such a system might work, but each
Enterprise Ethereum blockchain is free to implement whatever system is
suitable, as long as it includes the required functions for clients to query.
Permissioning Contracts: Interoperable on chain node whitelist for testnet
This section describes an approach for achieving interoperable node
permissioning using an on chain white list. The interop is desired between as
many enterprise ethereum clients as possible. Whilst this example is for node
permissioning, the approach can be extended to include account permissioning.
The components described in the remainder of this section align with the
Permissioning Management and Permissioning Enforcement sections described in
the Permissioning Smart Contract section of the Enterprise Ethereum
Alliance Client Specification [[EEA-clients]].
The on chain white list consists of smart contract management functions
essentially implementing the following operations:
- Add a node to whitelist.
- Remove a node from whitelist.
- Get whitelist which returns the nodes in the whitelist.
These smart contract functions can be based on one of the existing
node permissioning white listing smart contracts provided by one of the client
vendors. These include:
- [Autonity whitelist management smart contract](https://github.com/clearmatics/autonity/blob/develop/contracts/autonity/contract/contracts/Autonity.sol)
- [Besu whitelist management smart contract](https://github.com/PegaSysEng/permissioning-smart-contracts/tree/master/contracts)
- [Quorum whitelist management smart contract](https://github.com/jpmorganchase/quorum/tree/master/permission/)
- Strato's whitelist management smart contract is the basis of the
["member groups and authorised users" contracts](#sec-permissioning-contracts-memberGroups-and-authorizedUsers) in this document
These whitelist management functions are called from a Dapp or utility function
via RPC utilising an authorized account to perform the transactions.
Integration with EEA Spec node permissioning `connectionAllowed` smart
The on chain whitelist smart contracts include an implementation of the
node permissioning enforcement function `connectionAllowed` as defined in the EEA
client specification. This function will access the on-chain permissioning data
to determine if a connection is allowed.
Integration for clients that do not yet utilise the EEA Spec node
permissioning smart contract function
Some clients do not yet utilise the EEA Spec node permissioning smart contract
function `connectionAllowed`. Instead, they utilise other non-EEA smart contract
functions to perform this task. In order to integrate these clients into the
permissioned network, they need to operate on the same on-chain permissioning
data. This is achieved by implementing the non-EEA smart contract functions
which access the same on-chain permissioning data as the EEA functions.