- Root Chain (RC): refers to a smart contract on the Ethereum (or any other general compute blockchain with a Turing-complete VM).
- Plasma Chain (PC/Operator): refers to Campfire (in our case). The Plasma Chain is where most of the action happens. Its blocks are compressed and recorded on the RC's smart contract.
- Validator Nodes (Vals): a set of nodes that have the privilege to propose blocks to be written to the canonical blockchain. They each have a keypair. 2/3n + 1 validators are required to sign off on a block before it is committed, but once they do, the block is final.
- Watchers: these are auxilliary off-chain light clients that are responsible for checking (corroborating) the blocks that appear on the RC smart contract with blocks received from the PC. In the event that there is Byzantine behaviour, it is their responsibility to alert users to exit their UTXOs.
In Campfire, we implement the PC using Tendermint core (TMC). TMC is a consensus engine that uses a variant of what is known as pBFT. TMC was chosen because:
- It offers a unique architecture (ABCI) that offers app-specific blockchains a high level of flexibility with a rock-solid consensus approach.
- It has finality. This means that once a block is confirmed, it will never be reorganised or otherwise changed.
- It is almost trivial to layer a staking mechanism through the ABCI on top of TMC, which can be a vital game used to keep the token economy stable while discouraging dishonest behaviour from validator nodes.
The UTXO set is the most crucial component of the PC. UTXO stands for Unspent T(X)ransaction Output. This is because it amounts to the record of which addresses (20-byte hashes of public keys) "own" a given number of coins (TRB, in our case).
Example
Actors: Alice and Bob
- Alice owns a UTXO worth 5 TRB (UTXO1). Bob does not own any TRB at all.
- Bob wishes to sell Alice an Apple. Alice "spends" UTXO1 by creating
a
SendMsg, signing it with her private key. - UTXO1 has become an
inputto the transaction. It is "spent". In its place is anoutput(UTXO2), that belongs to Bob.
This mechanism is crucial to the functioning of MVP. This is because it is cheap to prove that a given person "owns" a UTXO on the RC by exploiting Merkle proofs. By comparison, account balances do not by themselves have such a concept of "history", since its balance is adjusted as a side effect of a transaction.
It is worth noting that in the case of Campfire, we make use of "Coinbase" transactions to reward network participants (writers, validator nodes, watchers, etc). A coinbase transaction is simply one in which there are no inputs, and only outputs: the outputs are "created from thin air" as an intrinsic reward for those who contribute to the network.
Similarly, deposit (explained below) transactions are treated in the same
way. Since they are included in the PC based on deposit events occuring on
the RC smart contract, they do not have inputs.
This section describes the barebones interface of the RC Smart Contract.
Methods
Verbatim from MVP Spec
submitBlock(bytes32 root): submits a block, which is basically just the Merkle root of the transactions in the blockdeposit(): generates a block that contains only one transaction, generating a new UTXO into existence with denomination equal to the msg.value depositedstartExit(uint256 plasmaBlockNum, uint256 txindex, uint256 oindex, bytes tx, bytes proof, bytes confirmSig): Requires as input (i) the Plasma block number and tx index in which the UTXO was created, (ii) the output index, (iii) the transaction containing that UTXO, (iv) a Merkle proof of the transaction, and (v) a confirm signature from each of the previous owners of the now-spent outputs that were used to create the UTXO.challengeExit(uint256 exitId, uint256 plasmaBlockNum, uint256 txindex, uint256 oindex, bytes tx, bytes proof, bytes confirmSig): challenges an exit attempt in process, by providing a proof that the TXO was spent, the spend was included in a block, and the owner made a confirm signature.
Properties
queue: priority queue where every element of the queue is anexitstemming from a call tostartExit. The queue is ordered in descending order of the age of the UTXO being exited. The age is represented as follows:(blknum * 1000000000 + txindex * 10000 + oindex)
Note: the RC smart contract keeps "custody" of all the coins received
through deposit (including ERC20). When a UTXO is exited, the smart
contract returns the money from this pool of tokens that it "owns". Note
that ERC20 support is WIP, but well on the way.
Conditions
The following conditions must be met in order for an exit to be finalised on
the RC:
- A UTXO included in a transaction in a block that is recorded on the RC;
- that is >= 14 days old; and
- A signature from the owner of the input that created the UTXO (i.e., the sender), and a signature from the owner of the UTXO (i.e., the receiver).
- The contract "owns" enough tokens to effect the exit.
The semantics of the exit game are somewhat convoluted. Instead of describing it in abstract, an abridged example is provided.
Ex. 1: Non-Byzantine Exit
Actors: Alice
- Alice has UTXOs worth 500 TRB on the PC (Campfire). She wishes to liquidate her TRB by trading it for ETH via Kyber. Therefore, she must "convert" her Campfire TRBs to ERC20 TRBs.
- Using the Tribe Wallet, she initiates an exit by calling
startExit, pointing to her 500 TRB UTXO. - Her exit is is inserted into
queue. - After the UTXO she is exiting reaches an age of 14 days, she is given 500 TRB on Ethereum, and her 500 TRB on the PC (Campfire) is burned.
Ex. 2: Weak out-of-nowhere attack
Actors: Alice, Watcher, Operator
- Alice is an honest user. She ends up with a UTXO worth 100 TRB. This is
included as
Blk1on the RC. nblocks later, the Operator goes rogue. It usessubmitBlockto create a fake block with a UTXO of 100 TRB on the RC,Blk1+n.Blk1+nis however never published on the PC.- The Operator immediately calls
startExitin an attempt to steal the 100 TRB. Theexitis superficially valid, due to the fake blockBlk1+n. - However, a Watcher notices that the
Blk1+ndoes not exist on the PC, and alerts all users to the attack. - As a result, Alice also calls
startExit, pointing to her 100 TRB UTXO. Since her UTXO was created before the fraudulent one created by the Operator, herexithas higher priority in the queue. - Alice and other users who similarly initiate exits get back their TRB before the. When the Operator's exit is finally processed, it fails, as the contract no longer "owns" any tokens - they have been claimed by their rightful owners whose priority was higher in the queue.
Ex. 3: Stronger out-of-nowhere attack with witholding
Actors: Alice, Bob, Watcher, Operator Assumption: total value owned by the RC smart contract is 10 TRB
- Alice broadcasts a transaction spending 10 TRB to Bob. This creates a UTXO
(
UTXO1), whose owner is Bob. The Operator, being dishonest, publishes this on the PC, but "witholds" it, i.e., does not record it on RC. - The operator then creates an invalid transaction creating 10 ETH for themselves
“out of nowhere” and records it on the RC in a block
blk-n(blk-n.tx0). - The Operator immediately exits the fraudulent UTXO in
blk-n.tx0 - Now, the Operator publishes the witheld block as
blk-n+1. - Bob, not knowing that
blk-nis invalid, and thinking that he owns the 10 TRB UTXO, attempts to exit the UTXO. Uh oh! Bob has a lower priority than Operator's malicious exit! - Alice, however, is notified by a Watcher of the malfeasance. Since both Alice and Bob must sign in order for Bob's exit to be processed, Alice refuses to sign, and instead proceeds to exit the 10 TRB UTXO she initially intended to send to Bob.
- Alice exits from her (still technically unspent) 10 TRB UTXO which existed before the operator’s invalid UTXO. The operator’s exit cannot be processed because the contract has no funds remaining.
Note that in this case, Alice and Bob are saved because of the confirmation signatures requirement. This also means that before any physical transfer of assets takes place, both parties to the transaction should verify that the RC smart contract state is valid. Otherwise, Alice may receive physical assets from Bob, and refuse to later pay the 10 TRB that was invalidated due to the Operator's wrongdoing.
Overview
Since users of a Plasma chain can never be online at all times, or may not be alert enough to notice anything fishy going on (particularly in the case of Ex. 3, where the Operator conducts a fairly sophisticated scheme), we introduce the idea of a "Watcher": light clients that track both the RC and PC, reconciling the chains as they are updated.
Components
campfired- Campfire client that keeps a local copy of the blockchain.geth- Ethereum client responsible for tracking state of Plasma blocks.validatord- checks Plasma blocks against the blocks fromcampfired
Implementation Notes
NOTE: THIS IS WIP
validatord maintains a buffered set of blocks (blockset) received from campfired.
This data structure is buffered because it is very likley that campfired
will process blocks at a far higher throughput than the RC. Each time it
receives a Plasma block published to the RC from geth, it looks for the root
hash in the set of blocks.
If a matching block is found in blockset, it should check the
previousHash of the block's header, and check if the last submitted Plasma
block matches
the block pointed to by previousHash. If not, this means that the RC smart
contract's records are no longer in the correct order, and an exit should be
triggered. Otherwise, the block is simply removed from blockset.
If the Plasma block is not found in the set, it should retry on the next
published Plasma block, and perform the same check. If no matching block from
campfired is forthcoming, it should assume that the RC blocks have been
tampered with, and all users should exit.