- 1.An accumulator, in this case an incremental Merkle Tree.
- 2.A nullifier boolean mapping.
These values can be accessed through the
New state objects (UTXOs) are appended to the Merkle Tree and emitted in contract events. Consumed state is invalidated by adding adding the nullifier to the mapping ensuring that old state can't be used twice without compromising privacy.
The contract maintains a mapping of the current and historical Merkle Tree roots so that proofs can be created against the Merkle Tree.
The RAILGUN contract verifies a a set of transaction circuits (JoinSplit with varying input and output UTXO counts) which are the only circuits allowed to write state changes.
External contracts have two primary means of adding functionality on top of the private state:
- 1.Using the Merkle Tree + nullifier set to generate read-only proofs.
- 2.Using the RAILGUN JoinSplit circuit with the adapt fields to add additional verification to state transitions.
These 2 ways of interacting with the core RAILGUN contracts can be combined to enable a number of use cases. Some examples are contained in the next section.