A Plasma Cash Primer
This primer is written with the intent of encapsulating the information that exists in forums, Medium posts and github into a coherent primer on what the current most mature version of Plasma Cash is (mature being: coded to be put into practice). Many write-ups have vague implementations or leave certain components out and thus it is hard to fully understand the whole setup for the goal of implementing it as a scaling solution.
This Plasma Cash Primer aims to be an understandable, full overview of Plasma Cash as is currently being implemented.
From Plasma:
Plasma is a side-chain. Like other side-chain scaling solutions, it piggy-backs on the main chain’s security by checkpointing it regularly. Where it differs is that if the side-chain misbehaves in any way, a user can still safely exit on the main chain: even in extremes scenarios like where the side-chain just stops outright.
It achieves this due to how the side-chain utilises merkle trees to model state & transitions: being able to determine if a state transition is invalid on a scale faster than actually running the state transition itself. Thus a user is able to submit proofs of fraud to the main chain that occur in the side-chain if the side-chain is being attacked or is misbehaving. These fraud proofs are cheap to verify. The main chain acts as a computational court.
Plasma, similar to Ethereum, aims to allow broad arbitrarily complex state transitions and thus it contains additional complexity.
Plasma Cash, however, uses a similar style of thinking, but focused on specific kinds of applications. Due to the scope being smaller, there’s less complexity involved.
To Plasma Cash:
Plasma Cash is a side-chain scaling solution that scales a certain class of decentralized applications on Ethereum that, for now, primarily tracks ownership of non-fungible tokens (collectibles, access, CryptoKitties, badges, etc). The “Cash” nomenclature refers to how physical cash works (unlike digital cash). Each coin or note is non-fungible denomination (eg a $1 note or 50c coin).
There are proposals that cover making it fungible (like Plasma Debit and others, but which is not covered in this primer). Loom Network & OmiseGo have written implementations for MVP versions of Plasma Cash. Links & references at the end of this primer.
It works by keeping track of on-chain tokens through a Sparse Merkle Tree (SMT) on a Plasma Cash side-chain (secured by any manner of consensus algorithm). Because the main-chain always allows a user to exit, it’s not even always necessary to have a robust decentralized consensus algorithm in the side-chain. It would depend on the application.
An operator is responsible for listening to deposit events on the main chain, registering the tokens AND taking the consensus that forms in the side-chain and posting its information to the main chain. An operator wants to facilitate an economy and could even be rewarded for doing so. It’s in an operator’s best interest to make sure that transactions submitted in the side-chain is valid.
An operator is the bridge between the main chain & Plasma Cash side-chain. The operator can’t defraud users. The service can only be degraded (through like a DDOS attack). Thus, depending on the scenario, in the simplest case, an operator could be just one, single company facilitating an in-game economy. It can just generate the blocks itself without needing any consensus algorithm in the side-chain.
Optional Detour: What’s a Sparse Merkle Tree?
This primer pre-supposes an understanding of what a Merkle Tree is. https://media.consensys.net/ever-wonder-how-merkle-trees-work-c2f8b7100ed3. A Merkle Tree is a class of data structures that allows one to secure and verify data. It’s used quite extensively in blockchains.
A Sparse Merkle Tree is a really interesting variant of a Merkle Tree. It was first proposed by Google in tracking whether certificates have been revoked or not. https://www.links.org/files/RevocationTransparency.pdf.
It works by creating a massive, uncomputably large binary merkle tree composing of 2²⁵⁶ default leaves (if it’s assumed you are using 256 bit hash function, like sha256). Because most paths in the merkle tree (256 hashes down), has a default value, it’s possible to represent this data structure without having to keep it all in state. Different sizes can also be used. It doesn’t have to be 2²⁵⁶.
The reason why this is valuable is because you essentially will deterministically know what position in the tree any information will hold (like a token ID or the hash of any certificate). It will always be in the same position. So for Google, hashing a certificate will always mean it is at a specific leaf in the tree.
In Google’s case, each leaf is either zero or one, where one means, it has been revoked. Doing it this way means that when submitting a merkle root of the whole SMT means you not only show/include a cheap-to-verify proof of what certificates has been revoked, but you ALSO include proofs of certificates that have NOT been revoked (their leaf value is just zero).
So, by proving that a leaf exists or contains some data, is also a proof of non-inclusion of the rest of the state. Once you wrap your mind around it, it’s quite powerful.
For every Plasma block, the merkle root of the SMT is stored in the main chain. This merkle root of the SMT is then checkpointed by an operator into the main Ethereum chain. This operator can go rogue, but not at the loss of the token holders (more on that later).
Every leaf in this SMT is a unique token ID that contains a signed transaction specifying who the current owner is. This unique ID that corresponds to the leaf is chosen based on a deterministic input that generates a hash pointing to the leaf. The design is similar to the UTXO-style transfer in Bitcoin. In order to send, you have to prove you are the current owner, and then sign it over to another owner, who is then able to claim the right to send it along.
A transaction consists of the following components:
uid: it’s unique position in the SMT (a leaf).
previousBlock: every transaction must point to the previous block where the previous transaction occurred in. This creates a chain of history. If it’s a deposit, it is “0”.
denomination: This how much the the specific token holds. These denominations can be anything. If it’s used for an ERC20 fungible (made non-fungible), you essentially create a denomination based on the deposit that’s similar to a note in real life. Eg, a 20 GNO non-fungible token or a 13 GNO non-fungible token.
new_owner The new owner of the transaction.
signature: Signature on the transaction’s hash.
hash: The hash of the transaction’s details (unsigned).
merkle_hash: The hash of transaction’s details that’s also signed by the sender that’s to be included in the merkle tree.
sender: The person transferring the token.
For a deposit transaction, there’s no other transactions in the plasma block that is generated. Because it’s a unique transaction, having *only* a deposit transaction in a block makes it easier to verify when one plans to exit with a deposit transaction. It’s not technically required to have a Plasma block per deposit, but makes things easier & cheaper.
Each token owner keeps the specific token’s transaction history with them as well as all the merkle roots in the plasma chain. These are the merkle roots that have been published to the main chain. When receiving this history & proofs it can on the client side verify that the token history is valid. If the operator misbehaved or if the previous owner sends proofs that don’t match up to the verified on-chain proofs, it will be detected and the token holder won’t accept it. There was then fraudulent behaviour.
In order to remain an operator that performs to its best ability, it checks the following requirements when submitting a transaction to it to avoid building fraudulent or invalid histories.
- Whether the previous Plasma Block specified in the transaction exists.
- Whether the previous tx has been spent already.
- Whether the transaction signature is valid.
After sending and receiving tokens within the Plasma side-chain, a user can exit to the main chain with the tokens they own at that current point in time.
In order to exit, one has to submit a bond & proof that one currently owns the token. The size of the bond should be enough that incentivizes participants to monitor this “court” in order to challenge fraudulent exits. It should not be high enough that users on the Plasma Cash chain would have enough money to exit. For example, you can’t expect someone who owns a $5 sword on the Plasm Cash chain to have access to a $1 million bond.
This fraud proof consists of the transaction that transferred access to oneself, and the previous transaction (which showed a transfer to the previous recipient). Each proof consists of: the transaction itself, the merkle proof, & the plasma blocknumber it occurred in.
Optional Detour: What does a merkle proof look like here?
A merkle proof is all the hashes required to determine if the leaf entity maps to the root. If all the hashes add up to the merkle root hash, then the proof is legitimate.
This medium post describes how one proves that a piece of data is in the tree:
After this proof has been submitted, anyone can challenge that the person exiting is not the truthful owner. A successful challenge will steal the bond of the person exiting as a reward for correctly challenging the exit. This challenge happens on-chain on the main chain. This challenge remains open for selected period of time (say 2 weeks).
There are 3 scenarios in which someone can fraudulently attempt to exit:
- The token it’s trying to exit with has already been transferred/spent to another owner.
- The token it’s trying to exit with has been double spent. It was *also* transferred to someone else and created a separate branch/history.
- The token has an invalid history before the previous transaction that has been submitted. An invalid history means there is a gap in the state changes.
If the operator didn’t misbehave and the clients successfully validated their history before accepting the token, it’s unlikely that scenarios 2 & 3 will ever occur. However, scenario 1 is always possible if someone who had the token in the past wants to exit with the token without the current owner knowing about it. Client services & other monitoring tools are set up such that they aim to challenge it when it happens in order to claim the bond as a reward. Even the operator who is tasked to monitor the side-chain and the main chain for deposits can challenge.
To challenge the above scenarios, you have to submit the following:
Scenario 1 (Spent Tx Challenge): A transaction that spent the current tx (the one you submitted). This means the token was transferred onwards and not legitimately in possession of it anymore. This invalidates the exit immediately and the reward is claimed.
Scenario 2 (Double Spend): Another transaction that spent the previous transaction and does not result in the current tx. This means that the token was double spent. This invalidates the exit immediately and the reward is claimed.
Scenario 3 (Invalid History):
A fraudulent operator can choose to include a transaction starting from a point that’s not attached to the original deposit, basically creating a history from thin air. This invalid history can also occur if the operator purposely withholds blocks. This challenge is interactive, which means that once it is challenged, another user needs to submit the transaction following it, to prove that the history was indeed valid. In order to challenge, one also needs to submit a bond, which is slashed if a follow-up transaction is supplied. If there isn’t a follow-up transaction, then it implies that the history is indeed valid.
Faster exits:
One issue with Plasma Cash is that in order to exit, the challenge period is a certain period.
There are proposals to make it faster to exit, like this proposal from Kelvin Fichter.
Bloom Filters & Checkpointing
One of the issues with Plasma Cash is that each token needs to keep its own history, which is: the transactions issued along with all the merkle proofs of all the Plasma Blocks. This in itself can grow quite substantially. It is estimated that for a small SMT (2¹⁶), the proof can maximally grow to 1gb for EACH token per year!
Bloom Filters, in being able to probabilistically return whether items are in a set are a proposal to make the history more compact.
Another alternative to keeping the proof size smaller is to rely on regular main chain checkpointing, which would allow users to throw away certain parts of the history.
Fungibility:
Plasma Cash works by having each token static with a certain denomination. In the case of a collectible, it’s always just one. This makes it harder for fungible tokens to work in this context. There are however proposals to utilise Plasma Cash to enable fungibility too, called Plasma Debit.
Plasma Cash @ Ujo Music?
Nihar Dalal & I have been exploring scaling solutions for use in Proof-of-Concepts at Ujo Music: from looking at probabilistic payments, counterfactual state channels & Plasma Cash. There’s many ways these new scaling solutions can aid us making new money for artists & musicians by bringing the costs down substantially.
There’s a multitude of ways to decrease the cost of licensing, add streaming payments & other improvements.
Conclusion:
Plasma Cash is a scaling solution that is currently primarily suited towards tracking ownership of assets in a side-chain. Using SMTs and frequently checkpointing into the main chain, users of the Plasma Chain can be guaranteed that their assets would never be stolen or destroyed.
The benefits are that you get scaling improvements at the cost of having ensure that the operator won’t revoke service at any point in time. It’s not possible in this scheme to lose funds, but it possible that the service might be degraded if the operator isn’t functioning (negligently or maliciously).
Plasma Cash as a whole is still evolving. It still needs additional scaling features to make it more feasible in practice (making token history even more compact). There’s likely to be more innovation in the short term that will prove to be useful in providing trustless, scaling solutions. The first implementations are going live soon!
Exciting times!
References:
Thanks:
Thanks Koh Wei Jie, Juan Blanco, Kevin Zhang, Hrishikesh Huilgolkar for feedback & comments. Thanks also to Nihar Dalal & the Ujo team (Jon, Kyle, Jack & Alex for discussions & feedback).
Are the problems interesting to you? Take a look at our careers page at Ujo Music: https://ujomusic.com/careers. Say hi!