# Plasma Chamber Spec(OVM version)
# Introduction
Hello! This document describes Cryptoeconomics Lab's L2 client and framework specification.
### Who should read this document
This document is written primarily for developers who will use our OVM core framework.
- Developers who wants to contribute to develop our OVM client should read SDK and framework spec described here (link).
- Developers who want to integrate our OVM framework to new blockchain system should read L1 adaptor spec described here (link).
- Developers who want to contricute to OVM language and L2 smart contract should read OVM spec and DSL section.
## Background
### What is OVM?
### Universal Client-
### CEL's framewor- k
Since OVM is concept we had to implement concrete system to benefit from OVM's- advantage.
CEL's framework is making OVM real by some components, OVM contract, OVM client and compiler.
## Contributers
Cryptoeconomics Lab, inc.
OVM was proposed by Plasma Group.
# Core Design
* L1 agnostic design
* Hybrid Layer 2 construction using OVM
* Multi-platform design
Once developer write the appilcation, it runs on many L1 and many platforms.
And also they don't have to write less client logic as possible.
**table of contents**
* SDK Spec
* Framework Spec
* L1 Adaptor
* Client Spec
* OVM Spec
## Whole Architecture
## Compatibility
### Serialization
Plasma Chamber uses ethereum ABI encoding.
### Github repositories of our implementation
[Client Core](https://github.com/cryptoeconomicslab/wakkanay): L1 agnostic OVM Client.
[Ethereum Client](https://github.com/cryptoeconomicslab/wakkanay-ethereum): Ethereum specific L2 implementation using Client Core.
[Lite Client](https://github.com/cryptoeconomicslab/wakkanay-plasma-lite-client): Plasma specific lite client using ethereum client.
[Contract](https://github.com/cryptoeconomicslab/ovm-contracts): group of contracts that are needed to support OVM’s claim decision.
# Plasma SDK Spec
### Basic APIs
* getBalance
### Send Transaction API
### Query API
[Great step to query language](https://github.com/cryptoeconomicslab/plasma-rust-framework/pull/255#discussion_r329358113) by @tkmct
# L1 Adaptor Spec
The main purpose of implementing L1 Adaptor is to support new Layer 1 blockchain.
Developer can implement L1 Adaptor following interfaces below.
* Coder
* Wallet
* ContractWrapper
* EventWatcher
## Coder
Coder provides Encoder for specific Layer 1 block chain. Developer can implement Encoding adapted new blockchain.
L1 adaptor must implements Encoder and Decoder for following primitive types.
* Address
* BigNumber
* Bytes
* Tuple
* Struct
* List
## Wallet
Wallet's responsibility is key management. Wallet provides L1 specific private key management ways.
### Wallet Class
## ContractWrapper and EventWatcher
ContractWrapper and EventWatcher provides concrete interface to access L1 Contract.
### AdjudicatorContract Class
### CommitmentContract Class
### DepositContract Class
### ERC20Contract Class
### OwnershipPayout Class
## Examples
* [ethereum](https://github.com/cryptoeconomicslab/wakkanay-ethereum)
* [tezos](https://github.com/cryptoeconomicslab/wakkanay-tezos)
# Client Spec
Design client spec to fit many platforms such as mobile phone, browser and micro computer.
https://hackmd.io/3003WCghTou-oXGBcTmuUg?both
# OVM Spec
## Overview
OVM is the concept to standardize L2 dispute logic. L2 developers write property to define dispute logic for Layer 2 protocol.
Every properties are claimed to the same Contract called Adjudication Contract. Properties are written by predicate logic and it can be prove to true or false under dispute logic.
For example, users deposit their asset to Deposit Contract and finally withdraw asset from Deposit Contract. In this scenario, Property stands for the condition which users can withdraw money from Deposit Contract.
In this document, we describe how we can implement OVM contract.
### Property
Property stadns for dispute logic and we can claim every Properties to Adjudicator Contract. Property has its predicate address and array of input.
e.g.) This claim stands for the preimage of hash doesn't exist.
```
PreimageNotExists(hash) := Not(∃preimage ∈ Bytes(): IsValidPreimage(hash, preimage))
```
In this case, the PreimageNotExists(hash) property is like following structure.
```
{
predicateAddress: Not.address,
inputs: [{
predicateAddress: ThereExists.address,
inputs: ["preimage", {
predicateAddress: IsValidPreimage,
inputs: [hash, "preimage"]
}]
}]
}
```
e.g.) Plasma Checkpoint Property stands for history of StateUpdate is valid.
```
Checkpoint(su) := ∀b < B: ∀su ∈ SU(): su().
```
#### Inputs of Property
|Primitive Type|size|description|
|---|---|---|
|Address|20|encoded by L1 specific Coder|
|Bytes|20-|bytes|
|Integer|32|encoded by L1 specific Coder|
|Property||Nested property will be encoded by Coder|
|Range|64|encoded by L1 specific Coder|
|Constant|1-19|"C" + bytes(constant value)|
|Label|1-19|"L" + bytes|
|Variable|1-19|"V" + bytes(variable name)|
### Decider and Quantifier
We are using quantifier elimination technich to make OVM contract imeplementation simple.
There are 2 rules. So evetything is decider in our implementation.
|original proposition|eliminated|
|---|---|---|
|∀b∈Quantifier(a):Foo(b)|∀b∈Bytes(a):Not(Quantifier(b, a)) or Foo(b)|
|∃b∈Quantifier(a):Foo(b)|∃b∈Bytes(a):Quantifier(b, a) and Foo(b)|
### Local information
Deciders use local information to make decision.
# Contract Spec
## Adjudacation Contract
### claimProperty
Claims property and instantiate new challenge game.
### isDecided
Gets the claim is decided or not.
### decideClaimToTrue
Set the game decision true whose dispute period has passed.
### decideClaimToFalse
Set the game decision false when its challenge is set true.
### removeChallenge
Removes challenge whose decision is set as false.
### setPredicateDecision
This is called from Predicate. It sets a game decision. For example, you know signature of `IsValidSignature(message, address, signature)`, you can set the game decision true which has this claim through `IsValidSignature` predicate.
### challenge
Adds new challenge game. AC must check the challenge is valid of parent game.
## Predicate
### Required functions of each Predicate
* isValidChallenge
* decide
isValidChallenge validates valid child node of game tree. I explain game tree.
I write the "challenge rule table" defining `challenge` function which applies the challenge table below recursively.
For example, `challenge(¬p) = p`.
#### Valid Challenge
|A|challengeInput|B|
|--|--|--|
| ¬p | ∅ | B,p|
| p0 ∧p1 | i ∈ {0,1} | B,¬pi \| challenge(pi)|
| p0 ∨p1 | ∅ | B,¬p0 ∧¬p1|
| ∃x ∈ X : p(x) | ∅ | B, ∀x ∈ X : ¬p(x)|
| ∀x ∈ X : p(x) | t∈X | B, ¬p(x/t) \| challenge(p(x/t)) |
If we have `∀x ∈ X : ∀y ∈ Y : p(x, y)`, challenge is `¬p(x/s,y/t)`.
"|" means if left isn't atomic.
#### Immediately decide table
|original|witness|condition|
|---|---|---|
|P_0 ∨ P_1|i| `decide(p_i)`|
|¬¬P|∅| `decide(P)`|
|∃x ∈ X : p(x)|t∈X| `decide(p(x/t))`|
|P_0 ∧ P_1|∅| `decide(P_0) and decide(P_1)` |
### Deposit Contract example
An example of Plasma deposit contract.
Deposit contract provides checkpoint property.
```
deposit(amount: uint256, initialStateObject: Property) {
Range range = calculateNextRange(amount);
stateUpdate = StateUpdate(range, initialStateObject)
Property checkpointProperty = checkpoint(range, block_number, stateUpdate)
storeProperty(checkpointProperty)
}
```
You can see description [here](https://github.com/cryptoeconomicslab/ovm-contracts/blob/master/contracts/DepositContract.sol#L55).
### Commitment Contract
Commitment contract provides StateUpdate property.
```
verify_inclusion(state_update): bool {
return MerkleTree[state_update.block_number].checkMembership(state_update)
}
```
(TODO: write description)
## Plasma Predicate
We can construct Plasma Predicate from atomic predicates.
Plasma predicate can be instantiate as StateObject. StateObject is Property and its inputs differs by each Plasma Predicate.
e.g.) OwnershipPredicate has only owner address in 0 index of inputs.
#### StateUpdate
```
struct StateUpdate {
blockNumber: Integer,
tokenAddress: Address,
range: Range,
stateObject: Property
}
Property({
address: StateUpdate.address,
inputs: [depositContractAddress, range, blockNumber, stateObject]
})
```
### Ownership Predicate
```
Ownership(owner, tx) := ∃sig ∈ Bytes(), IsValidSignature(tx, owner, sig).
```
#### Required functions of predicate
* isValidChallenge
* decide
* finalizeExit
(TODO: write description about finalizeExit of Plasma Predicate)
### Payout Contract
# Domain Specific Language
Predicate Logic
```
Ownership(owner, tx) := ∃sig ∈ Bytes(), IsValidSignature(tx, owner, sig).
```
DSL
```
def ownership(owner, tx) := SignedBy(tx, owner)
```
### Compiling Property
We can compile big property to small single property, and also we can build library for complex property such as atomic swap.
#### Why compile?
To avoid big property, we need wrapperd decider synthesized by multiple deciders.
However developers don't want to write specific decider and predicate.
So, OVM compiler should compile Properties with free variables.
#### How compile
https://hackmd.io/@syuhei/rySwGUOvS
#### Custome generator
If you wanna support new L1 protocol, you can develop specific generators following [generator interface](https://github.com/cryptoeconomicslab/ovm-compiler/blob/master/packages/generator/src/CodeGenerator.ts) and [abstract syntax tree](https://github.com/cryptoeconomicslab/ovm-compiler/blob/master/packages/transpiler/src/CompiledPredicate.ts) of DSL.
We can show 2 examples of generator in https://github.com/cryptoeconomicslab/ovm-compiler/tree/master/packages, solidity-generator and ethereum-generator.(ethereum-generator generates EVM bytecode).
## Reference
### Atomic Predicates
* Equal(a, b)
* IsLessThan(num, upperBound)
* IsValidSignature(message, signature, publicKey, verifierKey)
* IsValidHash(hash, preimage)
* IsContained(sub: Range, range: Range)
* VerifyInclusion(leaf, token, range, root, inclusion_proof)
* IsSameAmount(amount, range)
* VerifyConcat(bytes, a, b)
* VerifyRoot(root, address, block_number)
### Library
* SignedBy(message, publicKey, verifierKey)
* IncludedAt(leaf, token, range, root)
### Quantifier
* LessThan(upperBound)
* Root(address, block_number)
* Concat(a, b)
* Hash(preimage)
* Range(start, end)
* SU(block_number, token, range?)
* Tx(token, range, block_number)
# Challenges
* L2 fee mechanism
* In the case of that clients discard and update local information(O.Rollup)
* circular reference property