How to Send Private Transactions
Goal
Private Transaction Managers allow to send transactions to a subset of nodes in a private blockchain. This means that only nodes that are party to a given private transaction will be able to view the contents of it.
Private Transaction Manager
Enterprise ready Ethereum clients, such as Hyperledger Besu (formerly named Pantheon) and Quorum, allow to send private transactions through their Enterprise Tx Managers.
Hyperledger Besu’s Enterprise Tx Manager Orion.
Quorum’s Enterprise Tx Managers are Constellation and Tessera.
Private Tx parameters
The following parameters are exclusive for Private Transactions with any Tx Manager:
privateFor
: array[PublicKeys] of the nodes that take part on the Private Transaction.privateFrom
: DATA, 20 bytes – For private transactions, the public key of the sender.
♦ When using Hyperledger Besu’s Tx Manager, Orion
When using Hyperledger Besu’s Tx Manager, Orion, to send a private transaction, Orchestrate first signs the transaction and then sends it to Hyperledger Besu using web3 API. We will need to declare the following variable:
privateTxType
: STRING – If value isrestricted
, the transaction is a restricted private transaction. Ifunrestricted
, the transaction is an unrestricted private transaction. This parameter is equivalent to the parameter calledrestricted
on EEA documentation.
♦ When using Quorum’s Tx Manager Tessera
When using Quorum’s Tx Manager Tessera, Orchestrate does the following:
- Sends the data field of the transaction to Tessera directly. Tessera will store the data and will return a hash of the transaction’s data field;
- Orchestrate receives the hash from Tessera and replaces the value of the transaction’s data field with the received hash. From now on Orchestrate works with a transaction where the actual data is replaced with the hash received from Tessera.
- The transaction (with a hash instead of the data field) is now signed by Orchestrate and sent to Quorum using the web3 API.
To use Tessera we need to use the sendRawPrivateTransaction
method. Quorum’s API documentation can be found here.
Info
Note that Quorum and Tessera are two different processes and they communicate with each other via the network. To get a hash for a private transaction Orchestrate needs to send the transaction’s data directly to the Tessera process. Tessera endpoint is different from a regular web3 endpoint that we use for public transactions.
If we are connecting Orchestrate to multiple chains, we will need to provide a separate Tessera endpoint for each chain id. In order to indicate this mapping we need to use the TESSERA_ENDPOINTS
env. variable as follows:
export TESSERA_ENDPOINTS='{"10":"http://txmanager1:9080", "12":"http://txmanager2:9081"}'
In this case, we are connecting to 2 chains, and we specify that for chain id 10
the endpoint to use is http://txmanager1:9080
and for chain id 12
the endpoint to use is http://txmanager2:9081
.
Note
TESSERA_ENDPOINTS is a JSON object. You can check more info here.
Sending private transactions to a subgroup of nodes
try { const tx = await producer.send({ chainId: 10, protocol: { type: 'ProtocolType.QuorumTessera', },
const tx = await producer.send({ chainId: 10, protocol: { type: ProtocolType.QuorumTessera, }, to: '0xe5ce65038f9d1c841a33cc816ee674f8a0e31e74', call: { // contract: 'SimpleToken', // method: 'constructor()' method: 'transfer(address,uint256)', args: ["0xdbb881a51cd4023e4400cef3ef73046743f08da3", "100000"] }, privateFor: ['BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=', 'QfeDAys9MPDs2XHExtc84jKGHxZg/aj52DTh0vtA3Xc='], privateFrom: 'BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=', gas: 2000000, gasPrice: 0, value: 0, from: '0x7e654d251da770a068413677967f6d3ea2fea9e4' })