A view of Plasma Cash for Ethereum
At FiNC we are examining blockchain technology, and scalability solutions for the Ethereum Blockchain are one of the topics which we are particularly interested in. As the title suggests, this article discusses Plasma Cash, a new scalability solution for the Ethereum Network. It is currently being discussed widely by the Ethereum community .
For those who want to know why scalability solutions for Ethereum Blockchain matter, I would suggest you check out Johannes Hagemann’s article.
When I first read the Plasma Cash specification many questions arose in my mind. Some were easy to find convincing answers on the Internet, but for many I struggled to find answers that satisfied my curiosity. Therefore, I tried to analyze several open source Plasma Cash implementations to understand it more deeply. After collating those implementations, I found the strongest candidate is Loom Network’s implementation which has been released recently . I decided to systematize what I had learnt about Plasma Cash from an engineer perspective to share it with my colleague and external engineers who are also interested in Blockchain.
3. Plasma Cash for ERC721 Tokens
Generally, a scalable Ethereum Blockchain model consists of the following components:
(1) Client application
A mobile or web app that uses a web3 library (A library for interacting with Ethereum nodes) to communicate with both Root Chain and Plasma Chain.
(2) Root Chain
Root Chain hosts an ERC721 Token Contract and a Plasma Contract, where ERC721 Token Contract supplies and manages Non-Fungible Tokens (NTFs). For example, the Axiom Zen company has deployed the CryptoKittiesCore smart contract on Ethereum Blockchain which is an ERC721 Token Contract. This smart contract supplies and manages Non-Fungible CryptoKitties tokens like my lovely kitty:
He has a unique DNA string producing his unique appearance that is distinct from all kitties over the CryptoKitties world :)
Plasma Contract is deployed on the Root Chain (Ethereum) and has main functions:
- Handle Deposit events: In order to transact ERC721 tokens on the Plasma Chain, the users first need to deposit their tokens to the Plasma Contract and get Non-Fungible Plasma Coins in return.
- Handle Exit events: When the users want to exit their tokens from the Plasma Chain, they submit exit requests directly to the Plasma Contract on the Root Chain.
(3) Plasma Chain
Plasma Chain is also a Blockchain and currently being run by one operator (authority) who may be any company providing ERC721 tokens. Plasma Chain has the following characteristics:
- It consists of blocks, each block can contain a single transaction or multiple transactions depending on its type. Each block also maintains one Sparse Merkle Tree.
- Users are free to transact and use their Plasma Coins on the Plasma Chain in any way, including transferring it to other users on the Plasma Chain .
- It periodically submits the Merkle root of the current block to the Plasma Contract, showing any changes in ownership of the Plasma Coins.
3.2. Deep dive into Plasma Cash implemented by Loom Network
I guess that if you read this post up to here, maybe some questions arose in your mind, such as: How does Deposit work? How does Plasma Chain organize blocks? How does Transaction get executed? How does Exit work? In this section, I will try to answer those questions in a practical manner by dissecting Loom Network’s Plasma Cash source code.
Firstly, let’s git clone the Plasma Cash source code from Loom Network’s repository here . Alright, let’s start the journey.
3.2.1. Deposit ERC721 Tokens
Before the users can perform transactions related to their ERC721 tokens on the Plasma Chain, the users need to deposits their ERC721 tokens to the Plasma Chain. Depositing process proceeds sequentially through steps:
- Step (1): Client calls the
depositToPlasma(uint tokenId)function on the ERC721 Token Contract (ERC721 Token Contract must implement this function) using certain web3 library. The
tokenIdis ID of an ERC721 token.
- Step (2):
depositToPlasma()transfers the specified
tokenIdto the Plasma Contract. If the transferring succeeds, then
depositToPlasma()will calls the
onERC721Received()function on the Plasma Contract.
The Plasma Contract is implemented in the file:
with the contract name
RootChain contract provides a mapping
coins for storing Plasma Coins which are represented by
struct Coin instances. The
RootChain contract also keeps track of
currentBlock which is current block number of the Plasma Chain. In addition, it provides a mapping
childChain for storing Merkle roots of the Plasma Chain blocks.
- Step (3): Now that the control is passed to the
onERC721Received()function on the Plasma Contract. It proceeds to call
currentBlockby 1, then it generates an unique
uint64number) and creates a
coin(a Plasma Coin) based on the input parameters. The
coinstores crucial information such as the
tokenId, the ERC721 Token Contract’s address, owner’s address (the address of who owns that
tokenId), etc. And, the
coinis stored into the mapping
slotposition. Finally, the
deposit()function emits a
Depositevent including the unique
slotnumber and the
currentBlocknumber. Because the Plasma Chain is watching
Depositevents, when it receives the
Depositevent, it passes the event data and the control to a callback function.
The Plasma Chain is implemented at the business tier of a Flask REST API server in the directory:
Blocks are organized as follows:
There are 2 types of blocks on the Plasma Chain, Deposit Block and Plasma Block. A Deposit Block includes only 1 transaction which is called Deposit Transaction, while a Plasma Block may includes many transactions. The initial block is always a Deposit Block and Deposit Blocks are placed between Plasma Blocks (orange blocks in the above figure). Two consecutive Plasma Blocks have
blockNumbers difference is
N (in the above figure,
N = 1000). The type of a block can be identified programmatically using a trick like this: A block that
blockNumber % N != 0is a Deposit Block, while A block that
blockNumber % N == 0 is a Plasma Block.
- Step (4): The callback function creates a Deposit Transaction based on the received Deposit event data. The Deposit Transaction stores the
slotnumber into its
uidfield and the depositor’s address into its
new_ownerfield. This transaction is a true Unspent Transaction Output (UTXO). The callback function also creates a Deposit Block to include only the Deposit Transaction. The Deposit Block gets added to the
blocksdictionary with the key is the
blockNumberwhich is extracted from the Deposit event data. The Deposit process finishes here.
Summarily, the Deposit process turns a ERC721 token into a Plasma Coin on the Root Chain and a corresponding UTXO on the Plasma Chain. Because one Plasma Coin maps with one UTXO, we can think of UTXOs as Plasma Coins. Now, the owner can spend the Plasma Coin on the Plasma Chain at will.
3.2.2. Spending Plasma Coins on the Plasma Chain
Suppose that Alice uses a client application to register to an ERC721 Token Contract and receive 5 tokens with
tokenIds: 1, 2, 3, 4, 5. Alice deposits 3 tokens 1, 2 and 3 to Root Chain and receives pairs of deposit
slot number and deposit
blockNumber by catching Deposit events:
(deposit_slot1, deposit_block_number1) --> coin1
(deposit_slot2, deposit_block_number2) --> coin2
(deposit_slot3, deposit_block_number3) --> coin3
Now Alice wants to send
coin3 to Bob, what Alice is going to do is: Alice creates a
Transaction object from input parameters:
uid = deposit_slot3
prev_block = deposit_block_number3
new_owner = Bob’s address
Alice signs the transaction with her private key and then she encodes the transaction object using RLP encoding scheme. Next, Alice calls the Plasma Chain’s API
send_transaction through the HTTP endpoint
/send_tx. Upon receiving the request from Alice, the Plasma Chain decodes the serialized transaction object and validates it. If the transaction object is valid, it gets added to the current block on the Plasma Chain.
coin3, Alice also needs to send the history of
coin3 to Bob by some way (currently, this is not standardized yet). But what is the history of
The history of
coin3 consists of 2 collections of proofs:
- Inclusion proofs: An inclusion proof consists of a
blockNumberand a Merkle Proof for the said coin in a block with the
blockNumberis greater than or equal the Deposit Block’s
blockNumber. And, that block must includes a least one transaction related to the said coin. In this example, there is only one block with
blockNumber = 3003that includes one transaction related to
coin3. Therefore, there is only one inclusion proof.
- Exclusion proofs: An exclusion proof consists of a
blockNumberand a Merkle Proof for the said coin in a block with the
blockNumberis greater than the Deposit Block’s
blockNumber. And, that block must not include any transaction related to the said coin. By this definition, Exclusion proofs may have quite big size when the number of blocks grows really bigger.
Getting back to Bob, before Bob can spend
coin3, Bob needs to verify the history of
coin3 to ensure that
coin3 is valid.
3.2.3. Creating Plasma Blocks
Like Bitcoin Blockchain and Ethereum Blockchain, Plasma Chain also has a consensus algorithm which is so-called Proof of Authority (PoA). An authority /operator/validator may be a certain company running several nodes allowing them to submit the current block’s Merkle root to the Root Chain and create a new block for the Plasma Chain. For example, Loom Network is an operator of the Loom DAppChain which is a Plasma Chain.
Periodically, the Plasma Chain operator submits the current Plasma Block’s root to the blockchain. The frequency of block submissions can be either some time constant, or can be depending on a metric such as Merkle Tree sparseness. 
3.2.4. Exiting Plasma Coins
Exiting is a mechanism allowing the users to quit transacting on the Plasma Chain fairly and safely. The users then can get back ERC721 tokens by transferring their exited Plasma Coins back to the ERC721 Token Contract.
Plasma Cash requires the users to watch their Plasma Coins (by listening to
StartedExit events emitting from the Root Chain) to protect them from fraudulences. This watching task may be automated by client application or delegated to the third party. If the users detect an fraudulent exit, they should challenge against that fraudulent exit.
To exit a Plasma Coin, the user need to make a transaction directly to the Root Chain. That transaction calls the
startExit() function on the Plasma Contract with required parameters:
blockNumber and Merkle proof for the Plasma Coin in the previous block,
blockNumber and Merkle proof for the Plasma Coin in the exiting block, and a bond amount (a small ETH amount).
There are 3 major Exit — Challenge cases needing to be considered seriously :
18.104.22.168. Exit Spent Coin Challenge
A malicious user tries to exit a coin at the exiting block with
blockNumber = 2000 and the coin owner notices that the exit is fraudulent. The coin owner fetches exit information from the Root Chain and the coin history from the Plasma Chain. If there exists a block in the coin history that its
blockNumber is greater than the exiting block’s
blockNumber, the coin owner will trigger a CHALLENGE AFTER by sending the challenging block’s
blockNumber and the Merkle proof for the exiting coin at that challenging block to the Root Chain. The Root Chain will terminate the exit immediately and the malicious user’s bond will be slashed and transferred to the coin owner.
22.214.171.124. Exit Double Spend Challenge
If there exists a challenging block in the coin history that is between the previous block and the exiting block, and the previous transaction (at the previous block) is the parent transaction of the challenging transaction (at the challenging block), this means that the coin was spent double at the previous block, the exit will be undergone a CHALLENGE BETWEEN and terminated immediately. The exiter’s bond will also be slashed and transferred to the coin owner.
126.96.36.199. Exit With Invalid History Challenge
Suppose that for some reason, the coin history becomes invalid and the exiter submits 2 seemingly valid transactions at blocks
3000 to the Root Chain. The coin owner suspects that the exit is fraudulent, and decides to attest that he/she can exit the coin at block
1000 by submitting 2 valid transactions at blocks
1000 and making a CHALLENGE BEFORE against the exiter. The exiter has to respond the coin owner’s challenge with a valid child transaction of the challenging transaction. But that child transaction doesn’t exist, and so the exit will be eventually canceled.
In summary, the 3 Exit — Challenge cases above are modeled as follows :
When a Plasma Coin is created through the deposit process, the coin is assigned a
DEPOSITED state. When a exiter starts exiting the coin, its state is transitioned to
EXITING. If the exit is valid, the coin’s state is eventually transitioned to
EXITED. Otherwise, either the exit is terminated and the coin’s state is transitioned back to
DEPOSITED or the exit is challenged by CHALLENGE BEFORE and the coin’s state is transitioned to
CHALLENGED. If the exiter can respond the CHALLENGE BEFORE, the coin’s state is transitioned back to
EXITING, and after a maturity period, its state is eventually transitioned to
EXITED. Conversely, the coin’s state is transitioned back to the initial state
I started this blog post with a WHY: Why do scalability solutions for Ethereum Blockchain matter? and diverted the answer to another blog. Next, I tried to draw your attention into a walkthrough of Plasma Cash which is a new scalability solution for the Ethereum Network. I hope that I helped you see some aspects of it rather clearly. However, I think if you read this blog post up to here, definitely, your mind is spinning with many other WHYs: Why X? Why Y? Why Z, etc and maybe many HOWs as well. If you are really interested in demystifying them, please drop a comment. Then, we can start a brainstorming together. Besides, I also have an intention of considering demerits of Plasma Cash and how Plasma XT (next generation of Plasma Cash) can fix them in the near future. Stay tuned.