mirror of https://github.com/poanetwork/quorum.git
55 lines
2.2 KiB
Markdown
55 lines
2.2 KiB
Markdown
|
|
# Design
|
|
|
|
## Public/Private State
|
|
|
|
Quorum supports dual state:
|
|
|
|
- Public state: accessible by all nodes within the network
|
|
- Private state: only accessible by nodes with the correct permissions
|
|
|
|
The difference is made through the use of transactions with encrypted (private) and non-encrypted payloads (public).
|
|
Nodes can determine if a transaction is private by looking at the `v` value of the signature.
|
|
Public transactions have a `v` value of `27` or `28`, private transactions have a value of `37` or `38`.
|
|
|
|
If the transaction is private, the node can only execute the transaction if it has the ability to decrypt the payload.
|
|
Nodes who are not involved in the transaction cannot decrypt the payload and are therefore unable to process the transaction.
|
|
As a result all nodes share a common public state which is created through public transactions and have a local unique private state.
|
|
|
|
This model imposes a restriction in the ability to modify state in private transactions.
|
|
Since it's a common use case for a (private) contract to read data from a public contract the virtual machine has the ability to jump into read only mode.
|
|
For each call from a private contract to a public contract the virtual machine will change to read only mode.
|
|
If the virtual machine is in read only mode and the code tries to make a state change the virtual machine stops execution and throws an exception.
|
|
|
|
The following transactions are allowed:
|
|
|
|
```
|
|
1. S -> A -> B
|
|
2. S -> (A) -> (B)
|
|
3. S -> (A) -> [B -> C]
|
|
```
|
|
|
|
and the following transaction are unsupported:
|
|
|
|
```
|
|
1. (S) -> A
|
|
2. (S) -> (A)
|
|
```
|
|
|
|
where:
|
|
- `S` = sender
|
|
- `(X)` = private
|
|
- `X` = public
|
|
- `->` = direction
|
|
- `[]` = read only mode
|
|
|
|
### State verification
|
|
|
|
To determine if nodes are in sync the public state root hash is included in the block.
|
|
Since private transactions can only be processed by nodes that are involved its impossible to get global consensus on the private state.
|
|
|
|
To overcome this issue the RPC method `eth_storageRoot(address[, blockNumber]) -> hash` can be used.
|
|
It returns the storage root for the given address at an (optional) block number.
|
|
If the optional block number is not given the latest block number is used.
|
|
The storage root hash can be on or off chain compared by the parties involved.
|