Technical Guide | Plasma-core Implementation Architecture

Plasma is a set of protocols that allow individuals to easily deploy high-throughput, secure blockchains. Even if "Plasma" is completely malicious, the smart contract on the Ethereum main chain can ensure the safety of users' funds. This eliminates the need for a reliable hooking mechanism like a side chain. Plasma is unregulated, allowing for prioritization of scalability without sacrificing security.

We envision many of the future of Plasma, giving users the freedom to choose where to trade. So, while releasing our Plasma implementation, we created PlasmaRegistry.vy. The registry allows the new chain to join the network by listing its IP/DNS address, custom "name" string and its contract address. The registry contract verifies the trusted deployment, so users can rest assured that any contract on the registry can be safely deposited.

This article focuses on Plasma's current protocols, progress, and recent developments from the research community.

Plasma has the following properties:

  • The "fixed denomination" issue in Plasma Cash.
  • The block size varies with the number of transactions, not the amount of deposits.
  • The light client proves that it is scaled by the logarithm of the block size and the block is linearly stored, making the operator the only (computing) bottleneck of the system.
  • The exit process allows the exit to specify only the most recent transaction, not the transaction and its parent transaction.
  • Inter-chain atomic exchange lays the foundation for a decentralized exchange protocol.
  • Unlimited deposit capacity.

Our implementation follows the above specifications and provides the following:

  • Command line Plasma operator written in Javascript.
  • The Plasma client implementation in Javascript comes with a command line wallet.
  • Support for smart contracts for ETH and ERC20 tokens written in Vyper.
  • An integrated JSON RPC that allows clients to download and verify light client certificates and transactions.
  • Plasma operator block browser.
  • Simulate the client group and generate the transaction to load the test.
  • Plasma "registered" contract, which lists a set of verified security contracts and carrier IP addresses for users to explore.

The rest of this article will provide a comprehensive discussion of our specifications, where the code is located, and what it does.

Our Github offers all our implementations under the MIT license:

Plasma operator: Start your own plasma and deploy it to testnet.

Plasma-core: core plasma client function – balance logic.

Plasma-node: Node.js wrapper for implementing plasma-core of the CLI

Plasma-js-lib: A JS helper for building web applications that integrate plasma transactions.

Plasma contract: PlasmaChain.vy and PlasmaRegistry.vy Vyper contract.

Plasma-explorer: A block browser hosted by an operator.

Plasma-utils: A shared utility for creating plasma specifications.

Plasma: Integration testing of the above components.

The following is the architecture of the plasma-core implementation:

Plasma operator implemented architecture:

1. General definitions and data structures

This section describes the terminology of the protocol components. These data structures are encoded and decoded by library serialization of plasma utils. An exact byte/byte binary representation of all data structures for each structure can be found in the pattern.

Token ID assignment

The basic unit of any plasma asset is expressed as a coin. Like the standard plasma cash, these coins are irreplaceable. We refer to the index of the token as coinID, 16 bytes. They are assigned in the order in which each asset (ERC 20 / ETH) is deposited. It is worth noting that all assets in the chain share the same ID space, even if they are different ERC20 or ETH. This means that transactions across all asset classes (which we call tokenType or token) share the same tree, providing maximum compression.

We do this by letting the first 4 bytes reference the tokenType of the coin, and the next 12 represent all possible coins for that particular tokenType.

For example, the 0th tokenType is always ETH, so the first ETH deposit will give the depositor coin 0x00000000000000000000000000000000 the right to spend.

The total coins received per deposit are exactly (the number of tokens stored) / (minimum mark denomination) a lot.

For example: suppose tokenType 1 is DAI, the coin denomination is 0.1 DAI, and the first depositor sends 0.5 DAI. This means that its tokenType == 1, so the first depositor will receive the coinID from 0x00000001000000000000000000000000, including the coin 0x00000001000000000000000000000004.

Denomination

In fact, the denomination will be much lower than 0.1. Instead of storing the denomination directly in the contract, it stores a decimal set map for each type of mark, indicating the decimal point shift between the number of stored ERC20 (or WEI of ETH) and the number of received plasma coins. These calculations can be found in the Depositerc20, Depositeth, and FinalizeExit functions in smart contracts.

//Note: for this version, decimalOfsets is hardcoded to 0 because we lack support in the client/operator code.

2, within the trading range of coins

Transfer

A transaction consists of a specified block number and an array of Transfer objects that describe the details of each transaction scope. The pattern (length in bytes) from plasma-utils:

We can see that each Transfer in the transaction specifies tokenType, start, end, sender, and recipient.

Typed and untyped boundaries

One thing to note above is that the start and end values ​​are not 16 bytes like coinid, but 12 bytes. In the above section on deposits, this should make sense. To get the actual coinID of the transport description, we connect the 4 bytes of the token field to the left of start and end. We usually refer to the 12-byte version as transfer's untypedStart and untypedEnd, where the connected versions are called typedStart and typedEnd. These values ​​are also exposed by the serializer.

Another note: In any transfer, the corresponding coinID is defined to include start and end exclusive. That is, the exact coinID of the transfer is [typedStart, typedEnd]. For example, the first 100 ETH coins can be transferred using Transfer, where transfer.token = 0, transfer.start = 0, transfer.end = 100. The second 100 will have transfer.start = 100 and transfer.end = 200.

Multiple and transfer/transaction atomicity

The transaction mode consists of a 4-byte block number (transactions are only valid if they are included in a particular plasma block) and an array of Transfer objects. This means that a transaction can describe multiple transfers that are either all atomic or independent of the containment and validity of the entire transaction. This will be the basis for decentralized and defragmentation in subsequent releases.

 

Serialization

As shown above, plasma-utils implements a custom serialization library for data structures. Both JSON RPC and smart contracts use byte arrays encoded by serializers.

The encoding is very simple, the concatenation of each value is fixed to the number of bytes defined by the pattern.

For encodings involving variable-size arrays, such as transaction objects that contain one or more transfers, a single byte number precedes a single byte. You can find the tests for the serialization library here.

Currently, we have the following pattern of objects:

  • Transfer
  • UnsignedTransaction
  • Signature
  • SignedTransaction
  • TransferProof
  • TransactionProof

This article reprints the public number: Blockchain Research Laboratory

The content of Haina College will be centered on: blockchain technology, product community, economic model and other comprehensive knowledge system output. Feel free to contact the author WeChat: csschan1120