Plasma Cash Developers’ Guide: Everything You Need to Know (+ How to Use Loom’s Plasma CLI)

Dev Bharel
Loom Network
Published in
9 min readJan 4, 2019

--

Update:

Loom Network is building a fundamental infrastructure platform to help Ethereum scale for real world use cases, and it’s the first Ethereum scaling solution to be live in production.

Loom allows developers to run large-scale applications by deploying to high-throughput Ethereum sidechains, while maintaining the security benefits of Ethereum mainnet.

In a previous article, we talked about moving assets from Loom to Ethereum mainnet using Transfer Gateways. In this article, we’ll be talking about another way to do so: Plasma Cash.

In a nutshell, Plasma Cash allows users to securely transfer their digital assets onto sidechains from Ethereum mainnet without the need to trust the sidechain. Each asset you transfer to a sidechain gets assigned a unique serial number and has its own transaction history.

Loom has built a shared sidechain called PlasmaChain that utilizes both Transfer Gateways and Plasma Cash functionality.

Let’s revisit Transfer Gateways for a minute, see how Plasma Cash works differently, and then dive into the Plasma Cash command line interface that Loom recently released.

Transfer Gateways Revisited

Transfer Gateways make use of at-will oracles to move assets between chains. That is, no interaction happens between chains without being initiated by a human.

Charlie can buy a card on Ethereum mainnet and then deposit it on the Transfer Gateway contract on Ethereum mainnet. This triggers an Oracle (server) listening to that contract to issue an ownership change request for the corresponding asset on PlasmaChain (or another Loom sidechain). Then Charlie can go and withdraw that asset on PlasmaChain. The token may only be “live” either on Ethereum mainnet or PlasmaChain. To move between these two chains requires “burning” it on the sending chain by transferring ownership to the Transfer Gateway contract.

How Is Plasma Cash Different?

Plasma Cash works slightly differently. Loom sidechains utilizing Plasma Cash periodically report Merkle proofs to Ethereum mainnet as “checkpoints”.

The Plasma Cash implementation works by having an Ethereum Plasma Contract (EPC) that lives on Ethereum mainnet and a Loom Plasma Contract (LPC) that communicates with the Ethereum mainnet contract.

A user starts with a token on Ethereum mainnet. They then Deposit that token with the EPC, which emits an event. This event is picked up by a sidechain oracle, which proceeds to create a block on the sidechain with a single transaction that includes the deposited asset — a single transaction makes the “exit” (or withdrawal) process easier.

This transaction credits the user with a Plasma Cash token on PlasmaChain, which represents their deposited asset. The user can freely transact and use that token on the sidechain in any way, including transferring it to other users.

PlasmaChain will periodically checkpoint to the EPC on Ethereum mainnet by submitting a Merkle proof of each of its blocks, allowing for verification of token ownership changes.

Merkle Proof Checkpoints

Plasma Cash chains (and in fact all blockchains) make use of a nifty data structure called a Merkle Tree to store data about the transactions in a block.

In a Bitcoin or Ethereum block, there might be an untold number of transactions. So how can we verify that a certain transaction was included in a certain block?

Imagine you wanted to show that transaction A was in block 500. One way to approach this would be to have everyone store all of the blocks’ raw data, and then go to block 500 and read through the list of transactions until you found a transaction matching A. However, this would require massive storage resources to maintain.

Saving time and space

To save both computation time and storage space, with each block, we also generate a Merkle Root hash of the block’s transactions. These hashes are used as “summaries” of the block, and can be used for validation.

A Merkle Tree hashes the transactions together to represent the Merkle Root of the block — a single, fixed-length hash representing all the transactions in that block.

An example of a Merkle Tree

For example, this Merkle Tree is composed of four transactions, A through B. Each transaction is first hashed to create Hash(A), Hash(B) and so on. Then, Hash(A) and Hash(B) are hashed together to create the next level of the tree: Hash(Hash(A) + Hash(B)). On the right side of the tree, the same has happened with transactions C and D.

The final Merkle Root hash in this example is therefore:

Hash( Hash(Hash(A)+Hash(B)) + Hash(Hash(C)+Hash(D) ) 

Because of the construction of the tree is recursive, we can actually use this root hash along with the Merkle path to create a proof that can be used to verify any given transaction for a given block.

For example:

Verifying if transaction K is included in this block

If a user wanted to validate with a node that transaction K was in this block, then the node would only need to keep a list of block Merkle Roots. The user would provide (a) the block number the transaction is in, (b) the transaction K, and (c) the Merkle proof.

The Merkle proof constitutes of Hash(K), Hash(L), Hash(IJ), Hash(MNOP) and Hash(ABCDEFGH). The missing pieces, Hash(KL), Hash(IJKL), Hash(IJKLMNOP) can be computed from the proof by the node, and the resulting root hash for that block should match the root hash on file.

We can see the space savings here:

Space savings with Merkle Trees

Why is this important?

By using Merkle Root hashes, we can “back up” a blockchain to another chain without replicating its whole database of transactions. This means that, storage-wise, it’s feasible for us to save a summary of PlasmaChain’s entire history on Ethereum mainnet.

PlasmaChain oracles periodically submit these summaries — a set of Merkle Roots for all the new blocks since last summary — to the EPC. This smart contract on Ethereum mainnet can be used to secure the PlasmaChain.

Plasma Exits

To exit their tokens from the PlasmaChain, the user can interact directly with the EPC on Ethereum mainnet, submitting a Merkle proof that they are the current owner of the token.

They then enter a “challenge wait period”, during which, anyone can provide proof that the person trying to withdraw tokens is not the valid owner of those tokens.

After this wait period, the user’s tokens will be available on Ethereum mainnet.

Plasma Cash CLI

Okay, let’s get down in the dirt and actually try out the new Plasma Cash CLI, published by Loom.

You can view the source here: https://github.com/loomnetwork/plasma-cli

This CLI tool is available as an npm package, so we can install it using:

$ npm install -g plasma-cli

If you have issues with this step, you might need to make sure you’re using Node v10.9.x.

Before we can use plasma-cli, we need to create a config.json file with the right parameters. You can use the commands by passing in all these arguments through the command line, but I would highly recommend defining it as a config file for ease of use.

A proper json object will have the following fields:

{
"ethPrivateKey": "",
"dappchainPrivateKey": "",
"plasmaAddress": "",
"startBlock": "",
"ethUrl": "",
"ethEventsUrl": "",
"dappchainUrl": "",
"contractName": "",
"dbPath": ""
}

Let’s break down what each of these lines mean.

ethPrivateKey: The private key associated with your Ethereum account.

dappchainPrivateKey: The private key associated with your Loom sidechain (i.e. PlasmaChain, in this case) account.

plasmaAddress: The address of the Ethereum Plasma Cash contract on whichever Ethereum chain you’re connecting to. If you’re connecting to Rinkeby, the address of the EPC is 0xd028e13a0b37e4b758b003a793cb6f0f6531ba75.

startBlock: The block at which the EPC was deployed. This is used for event filtering, and makes it so the programs will only look at blocks after this one.

eth-url: The url for an Ethereum node. By default, it’s http://localhost:8545 for a local Ethereum node. I would suggest setting up a free Infura.io account to get an easy API url (e.g. https://rinkeby.infura.io/v3/{YOUR_PROJECT_ID}).

ethEventsUrl: The url for listening to Ethereum events. This is WebSocket (unlike the HTTP url for eth-url), which is a lot more efficient for transferring data than multiple HTTP requests, and has lower overhead overall. If you’re connecting to Rinkeby, try wss://rinkeby.infura.io/ws

dappchainUrl: The url for the Loom sidechain node that you want to interact with. For PlasmaChain testnet (extdev) the url is http://test-z-asia1.dappchains.com

contractName: This is not necessary and just gives a name to the contract you’re interacting with; plasmacash should work fine.

dbPath: This is a path to store the data locally for easy access; /tmp/pcashDB.jsob will suffice for this field.

Making a Transfer Using the CLI

When you have a config file ready, we can start up the Plasma Cash CLI tool with:

$ plasma-cli --config config.json

You’ll be greeted with a empty prompt. This is normal. It just means it initialized the CLI tool and is ready to receive commands. Try help for a list of commands this new prompt will accept.

If we do myCoins we should see [] letting us know we have no current coins deposited. Let’s go ahead and deposit 1000000000000000 Wei (or about 0.001 ETH) into the contract to turn it into coins we can use on the PlasmaChain.

NOTE: To do this, you’ll need to have ETH in your Rinkeby account; otherwise, you’ll get an insufficient funds error.

$ depositETH 1000000000000000

This should take maybe 30 seconds to confirm the transaction, and you should end up seeing something like this:

Note that this is the output of two commands: depositETH and then myCoins, which I used to verify that my coins were properly deposited. The output will have a lot of <BN: x>, which stands for large integers encoded in the BigNumber format (standard for Ethereum based interactions). We actually only need to worry about the first line, slot: <BN: 967...> This number is your coin ID and what you’ll use to transfer or exit the coin.

Due to the way Plasma Cash works, when you convert that Wei into a Plasma Cash token, that token represents the entire value of the Wei and cannot be further split or combined (this functionality is under development and will be available in the future). Therefore, you now have ONE coin with the value of 0.001 ETH to use. You can’t use 0.0005 ETH somewhere or combine two 0.001 ETH coins to make a 0.002 coin. You’d have to exit and redeposit to get tokens of varying value.

The process is the same if you’re trying to transfer ERC20 or ERC721 tokens, except you also need to provide the address for the token contract: depositERC20 <address> <amount> or depositERC721 <address> <coinId>. The <address> field will be the address of the token contract.

To transfer your coin to another person, you can use:

transfer <coinId> <newOwner>, where in our case, our 0.001 ETH coin is coinId: 96726d…, as noted in the slot field of the output.

The receiver of the coin — on their CLI — should then call recieve <coinId> to confirm ownership of the coin. If they don’t do this, the coin will still be listed as owned by the sender.

To withdraw your coins from the Plasma Cash system, you need to exit and finalize a coin.

Exiting and Finalizing a Coin

First, we need to start an exit by calling exitCoin <coinId> . The client will start an exit by charging you a deposit for the challenge. During the challenge period, anyone with proof can challenge that you don’t own the coin (and so can’t exit), and receive the deposit as a reward for calling out a false exit. During this time, the “state” of the coin (if you get coin info through coin <coinId> or myCoins) is 1, meaning that the coin is in a challenge period.

After the dispute period has passed, we can finalize <coinId> the coin, which will put it in state 2, ready to be withdrawn. Then simply do withdraw <coinId>, and withdrawBonds to withdraw the coin and to return all the funds you’ve placed as a deposit.

And That’s It!

Hope this was a useful introduction to working with Plasma Cash via the Plasma CLI. If you run into any issues, feel free to pop into our Loom SDK chat on Telegram, and someone will be happy to help you out.

Loom Network is the multichain interop platform for scaling high-performance dapps — already live in production, audited, and battle-tested.

Deploy your dapp to Loom’s Basechain once and reach the widest possible user base across all major blockchains today.

New to Loom? Start here.

Want to stake your LOOM tokens and help secure Basechain? Find out how.

Like what we’re doing here? Stay in the loop by signing up for our private mailing list.

--

--