Powering New-Age Blockchain Development with Polkadot

Powering New-Age Blockchain Development with Polkadot

Polkadot is a fast-growing ecosystem that enables cross-chain communication within its parachains. Such interoperability and scalability can take blockchain technology to the next level and solve multiple problems like low TPS, high transaction fees, hard forks, and more.

“Polkadot is a sharded blockchain, meaning it connects several chains in a single network, allowing them to process transactions in parallel and exchange data between chains with security guarantees”

Polkadot Litepaper

Talentica’s blockchain team has a lot of experience in building blockchain-based solutions and we always observed evolving innovative technologies to increase our blockchain expertise. We have been working on multiple blockchain frameworks. Among those, we found Polkadot gaining a lot of traction recently. We started exploring this protocol and did some hands-on. Our prior experience with blockchain technology and Rust programming language helped us to gain a good grasp on the framework.

In this blog, I’ll help you understand how to develop and launch a simple Parachain project on Polkadot in the following sections. It is not intended to explore the basics of Polkadot in detail here, but the article will help you have a working local environment for Polkadot parachain development and get familiar with the development process.

Local Setup

Polkadot provides PDKs (which stands for Parachain Development Kit) to ease the development. Currently, there are two functioning PDKs which are Substrate and Cumulus.

The substrate is the underlying framework on which Polkadot itself is built. It is a toolset for blockchain innovators that provides the necessary building blocks for constructing a chain.

Cumulus provides the consensus implementation for a Parachain and the block production logic. It has the interfaces and extensions to convert a Substrate FRAME runtime into a Parachain runtime.

We will do some significant compiling while performing the steps below as everything has to be built locally in the system. Compiling can take noticeable time (based on your system configuration) and storage space.

Install Substrate Prerequisites

Follow the instructions at https://substrate.dev/docs/en/knowledgebase/getting-started/ for setting up a local development environment for Substrate.

Compile the Relay Chain

# Compile Polkadot with the real overseer feature

git clone https://github.com/paritytech/polkadot

cd polkadot

git fetch

git checkout rococo-v1

cargo build –release –features=real-overseer

# Generate a raw chain spec

./target/release/polkadot build-spec –chain rococo-local –disable-default-bootnode –raw > rococo-local-cfde-real-overseer.json

Clone the Substrate Parachain Template

Substrate Parachain Template internally uses Cumulus to convert the substrate sovereign chain to Polkadot parachain. We will use this template as a starting point for our parachain development.

# Clone substrate-parachain-template repo

git clone https://github.com/substrate-developer-hub/substrate-parachain-template.git

Building a Simple Parachain on Polkadot

In this section, we will create a custom “Proof of Existence” chain using the Substrate blockchain development framework and FRAME runtime libraries. This chain is made with the help of substrate tutorials provided by the substrate dev team.

We will use Substrate to create our runtime logic, which will be then compiled to a Wasm executable. This Wasm code blob will contain the entire state transition function of the chain, and is what we will need to deploy our project to Polkadot as a parachain.

About Proof of Existence

Proof of existence is a service that enables the identification of the real owner of a computer file. A user submits a file to the application, from the submitted file a hash value is calculated. The calculated hash can be safely assumed to be unique for an individual file. The hash value of this file is then mapped with some unique properties of the user for identification. A user with the original file can prove his ownership by simply recomputing the hash and matching it with the one stored in the blockchain. With this mechanism, we can certify the existence, ownership, and integrity of the document without the need for a central authority.

Interface and Design

Our PoE API will expose two callable functions:

  • create_claim – allows a user to claim the existence of a file by uploading a file digest.
  • revoke_claim – allows the current owner of a claim to revoke their ownership.

To implement this, we will only need to store information about the proofs that have been claimed, and who made those claims.

Building a Custom Pallet

The Substrate Parachain Template has a FRAME-based runtime. FRAME is a library of code that allows you to build a Substrate runtime by composing modules called “pallets”. You can think of these pallets as individual pieces of logic that define what your blockchain can do! The substrate provides you with multiple pre-built pallets for use in FRAME-based runtimes.

For example, FRAME includes a Balances pallet that controls the underlying currency of your blockchain by managing the balance of all the accounts in your system.

File Structure

Most of our changes will be in the pallets/template/src/lib.rs file inside the substrate parachain template. You can open the Substrate Parachain Template in any code editor, then open the file pallets/template/src/lib.rs

There will be some pre-written code that acts as a template for a new pallet. You can read over this file if you’d like, and then delete the contents since we will start from scratch for full transparency.

Imports and Dependencies

Add the below imports to the file.

#![cfg_attr(not(feature = “std”), no_std)]

use frame_support::{

decl_module, decl_storage, decl_event, decl_error, ensure, StorageMap

};

use frame_system::ensure_signed;

use sp_std::vec::Vec;

Most of these imports are already available because they were used in the template pallet whose code we just deleted. However, sp_std is not available and we need to list it as a dependency.

Add this block to your pallets/template/Cargo.toml file.

[dependencies.sp-std]

default-features = false

version = ‘2.0.0’

Then, Update the existing [features] block to look like this.

[features]

default = [‘std’]

std = [

‘codec/std’,

‘frame-support/std’,

‘frame-system/std’,

‘sp-std/std’,         <– This line is new

]

Configuration

Every pallet has a component called Trait that is used for configuration.

/// Configure the pallet by specifying the parameters and types on which it depends.

pub trait Trait: frame_system::Trait {

/// Because this pallet emits events, it depends on the runtime’s definition of an event.

type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>;

}

Events

Our pallet will only emit an event in two circumstances:

  • When a new proof is added to the blockchain.
  • When proof is removed.

// Pallets use events to inform users when important changes are made.

// Event documentation should end with an array that provides descriptive names for parameters.

decl_event! {

pub enum Event<T> where AccountId = <T as frame_system::Trait>::AccountId {

/// Event emitted when a proof has been claimed. [who, claim]

ClaimCreated(AccountId, Vec<u8>),

/// Event emitted when a claim is revoked by the owner. [who, claim]

ClaimRevoked(AccountId, Vec<u8>),

}

}

Errors

An error can occur when attempting to claim or revoke proof.

// App errors are declared here

decl_error! {

pub enum Error for Module<T: Trait> {

/// The proof has already been claimed.

ProofAlreadyClaimed,

/// The proof does not exist, so it cannot be revoked.

NoSuchProof,

/// The proof is claimed by another account, so the caller can’t revoke it.

NotProofOwner,

}

}

Storage

To add a new proof to the blockchain, we will simply store that proof in our pallet’s storage. To store that value, we will create a hashmap from the proof to the owner of that proof and the block number the proof was made.

// The pallet’s runtime storage items.

decl_storage! {

trait Store for Module<T: Trait> as TemplateModule {

/// The storage item for our proofs.

/// It maps proof to the user who made the claim and when they made it.

Proofs: map hasher(blake2_128_concat) Vec<u8> => (T::AccountId, T::BlockNumber);

}

}

If proof has an owner and a block number, then we know that it has been claimed! Otherwise, the proof is available to be claimed.

Callable Functions

As implied by our pallet’s events and errors, we will have two “dispatchable functions” the user can call in this FRAME pallet:

  • create_claim(): Allow a user to claim the existence of a file with proof.
  • revoke_claim(): Allow the owner of a claim to revoke their claim.

// Dispatchable functions allow users to interact with the pallet and invoke state changes.

// These functions materialize as “extrinsic”, which are often compared to transactions.

// Dispatchable functions must be annotated with weight and must return a DispatchResult.

decl_module! {

pub struct Module<T: Trait> for enum Call where origin: T::Origin {

// Errors must be initialized if they are used by the pallet.

type Error = Error<T>;

// Events must be initialized if they are used by the pallet.

fn deposit_event() = default;

/// Allow a user to claim ownership of an unclaimed proof.

#[weight = 10_000]

fn create_claim(origin, proof: Vec<u8>) {

// Check that the extrinsic was signed and get the signer.

// This function will return an error if the extrinsic is not signed.

let sender = ensure_signed(origin)?;

// Verify that the specified proof has not already been claimed.

ensure!(!Proofs::<T>::contains_key(&proof), Error::<T>::ProofAlreadyClaimed);

// Get the block number from the FRAME System module.

let current_block = <frame_system::Module<T>>::block_number();

// Store the proof with the sender and block number.

Proofs::<T>::insert(&proof, (&sender, current_block));

// Emit an event that the claim was created.

Self::deposit_event(RawEvent::ClaimCreated(sender, proof));

}

/// Allow the owner to revoke their claim.

#[weight = 10_000]

fn revoke_claim(origin, proof: Vec<u8>) {

// Check that the extrinsic was signed and get the signer.

// This function will return an error if the extrinsic is not signed.

let sender = ensure_signed(origin)?;

// Verify that the specified proof has been claimed.

ensure!(Proofs::<T>::contains_key(&proof), Error::<T>::NoSuchProof);

// Get the owner of the claim.

let (owner, _) = Proofs::<T>::get(&proof);

// Verify that the sender of the current call is the claim owner.

ensure!(sender == owner, Error::<T>::NotProofOwner);

// Remove claim from storage.

Proofs::<T>::remove(&proof);

// Emit an event that the claim was erased.

Self::deposit_event(RawEvent::ClaimRevoked(sender, proof));

}

}

}

Compiling the Parachain

After you’ve copied all of the parts of this pallet correctly into your pallets/template/lib.rs file, you should be able to compile your node without warning or error. Run this command in the root directory of the substrate-parachain-template repository to build the node:

# Build the parachain template collator

cargo build –release

# Print the help page to ensure the node built correctly

./target/release/parachain-collator –help

Starting the Nodes

Launch Relay Chain

Run these commands inside the polkadot directory.

# Alice

./target/release/polkadot –chain rococo-local-cfde-real-overseer.json –alice –tmp

# Bob (In a separate terminal)

./target/release/polkadot –chain rococo-local-cfde-real-overseer.json –bob –tmp –port 30334

After starting Bob’s node, Bob’s terminal log should display 1 peer. If not, your local nodes are not discovering each other, in that case, you can add –discover-local subcommand at the end of Bob nodes launch command.

# Bob – If local nodes failed to discover each other

./target/release/polkadot –chain rococo-local-cfde-real-overseer.json –bob –tmp –port 30334 –discover-local

If the problem persists, we have to explicitly specify the bootnodes. For that –bootnodes /ip4/<Node IP>/tcp/<Node p2p port>/p2p/<Node Peer ID> subcommand can be added. To give Alice as Bob’s boot node we have to provide the Alice nodes details with the boot nodes subcommand.

Alice Node IP: 127.0.0.1 (As all the nodes are running in local).

Alice Node p2p port: 30333 (By default, if not specified, any node’s p2p will try to run on 30333 port).

Alice Node Peer ID: Check the Local node identity in Alice Node’s terminal log.

# Bob – If local nodes failed to discover each other

./target/release/polkadot –chain rococo-local-cfde-real-overseer.json –bob –tmp –port 30334 –bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWCL7XCABhEDuMQFNe2dmemtecfMaQueYb5dWstrRNCGAz

Export Parachain Genesis State and Wasm

Run these commands inside the substrate-parachain-template directory.

# Export genesis state

# –parachain-id 200 as an example that can be chosen freely. Make sure to everywhere use the same parachain id

./target/release/parachain-collator export-genesis-state –parachain-id 200 > genesis-state

 

# Export genesis wasm

./target/release/parachain-collator export-genesis-wasm > genesis-wasm

Launch the Parachain

Run these commands inside the substrate-parachain-template directory.

# Replace <parachain_id_u32_type_range> with the parachain id

 

# Collator 1

./target/release/parachain-collator –collator –tmp –parachain-id <parachain_id_u32_type_range> –port 40335 –ws-port 9946 — –execution wasm –chain ../polkadot/rococo-local-cfde-real-overseer.json –port 30335

 

# Collator 2

./target/release/parachain-collator –collator –tmp –parachain-id <parachain_id_u32_type_range> –port 40336 –ws-port 9947 — –execution wasm –chain ../polkadot/rococo-local-cfde-real-overseer.json –port 30336

 

# Parachain Full Node 1

./target/release/parachain-collator –tmp –parachain-id <parachain_id_u32_type_range> –port 40337 –ws-port 9948 — –execution wasm –chain ../polkadot/rococo-local-cfde-real-overseer.json –port 30337

A collator node maintains a full node for the parachain as well as the relay chain. It can be noticed in the above commands that several arguments are passed before the lone –, and several more are passed after it. The arguments passed before — are for the actual collator (parachain) node, and the arguments after the — are for the embedded relay chain node.

Similar to the relay chain if your local nodes are not able to detect each other, you can use the boot nodes subcommand. But in the parachain case, you have to provide the parachain boot node (Collator 1 – Use the Parachain Local node identity) before — and relay chain boot node (Alice) after –.

# Collator 2 – If local nodes failed to discover each other

./target/release/rococo-collator –collator –tmp –parachain-id <parachain_id_u32_type_range> –port 40336 –ws-port 9947 –bootnodes /ip4/127.0.0.1/tcp/40335/p2p/12D3KooWLVBrvKY6r965cYXX3YQq98JTPEbPym1zHhPvNnW8x8EH — –execution wasm –chain ../polkadot/rococo-local-cfde-real-overseer.json –port 30336 –discover-local –bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWCL7XCABhEDuMQFNe2dmemtecfMaQueYb5dWstrRNCGAz

Register the parachain

Open Polkadot-js App and connect to your local relay chain node(Alice/Bob). After successful connection goto Developer→Sudo and fill in the data like the image below.

Once the parachain is registered, you can explore more on the Polkadot-js to get familiar with the app.

Interacting with Proof of Existence Pallet

After successfully registering the parachain, now we should be able to use our parachain to create/revoke a claim on a file.

The Polkadot-js app allows users to interact with all the available pallets in the node. Connect your parachain node with the Polkadot-js app and go to Developer→Extrinsic. Here, select the templateModule pallet and createClaim function. Then select a file to be claimed from your computer and submit the transaction.

If all went well, once the Block is finalized you should see a success message on the screen. Remember, only the owner can revoke the claim! If you select another user account and try to claim the same file, it will throw an error saying The proof has already been claimed.

Note – The Polkadot-js app can be used as an initial testing platform for your parachain. Making a complete application will require you to have a custom UI. You can follow Polkadot’s documentation on tools, utilities, and libraries which will help your front-end javascript application to interact with the polkadot network.

 

Smart Contracts Security Analysis with Manticore

Powered with blockchain technology, smart contracts have become an important factor concerning business transparency. It eliminates the necessity for intermediary services like brokers and agents to facilitate a transaction, is less time-consuming, and enables agent neutrality and automation in signing deals.

The steady adoption of smart contracts on the Ethereum Blockchain has enabled millions of contracts holding numerous dollars in digital currencies, and tiny mistakes during the development of smart contracts on immutable blockchain have caused substantial losses and bring danger for future incidents. Hence, today the secure development of smart contracts is a crucial topic and a variety of other attacks and incidents associated with vulnerable smart contracts could have been avoided.

Smart Contract Attacks

The following is the list of known attacks one should be aware of and defend against while writing a smart contract.

Reentrancy

It occurs when a function makes an external call to another untrusted contract before it resolves the effects that should have been resolved. This can have unexpected effects. In this attack, the attack surface is high in terms of fund loss. The attacker can simply call the function of your smart contract and then re-enter the same piece of code and eventually drain the funds.

Real-World Impact: On 17-Jun-2016, The DAO (Decentralized Autonomous Organization) was one of the major attacks where reentrancy played a major role. As an overview, the attacker was analyzing DAO.sol, where he noticed that there is a function that updates user balances and totals at the end. Later, he found a way to recursively call the function before it finishes its execution so that he can move as many funds as he wants. This resulted in the transfer of around one-third (3.6 million) of ether that had been committed to The DAO.

Access Control

Access control is a very common issue. This problem occurs when someone tries to access functionality in the smart contract to which he was not authorized. To access external contracts functionality, the method or property must be set as external or public. While insecure visibility settings give attackers straightforward ways to access a contract’s private values or logic, access control bypasses are sometimes more subtle.

Solidity has a global variable, tx.origin (deprecated), which returns the address of the account that originally sent the call. Using this variable for authentication leaves the contract susceptible to a phishing-like attack.

Real-World Impact: Rubixi’s (Ponzi scheme) Fees stolen because the constructor function had an incorrect name (used DynamicPyramid instead of Rubixi), allowing anyone to become the owner.

Arithmetic

The data types available in solidity to store an integer can only hold the numbers in a specific range. An over/underflow occurs when an operation is performed that needs a fixed size variable to store a number (or piece of data) that’s outside the range of the variable’s data type. A uint8 for instance can only store numbers within the range [0,255]. Trying to store 256 into a uint8 will end in 0. This can be exploited if user input is unchecked and calculations are performed which result in numbers that lie outside the range of the data type that stores them.

Real-World Impact: The 4chan group who built Proof of Weak Hands Coin (PoWHC, a Ponzi scheme) lost $800k overnight because of over/under flow issues. The problem was in PoWH’s implementation of ERC-20. The attacker exploited the underflow issue to gain an exceedingly large balance of PoWH Coins.

Similarly, on 4/22/2018, an unusual BEC token transaction was recorded. In this particular transaction, someone transferred an extremely large amount of BEC tokens. Later, the analysis proved it to be a classic integer overflow issue.

Unchecked Low-Level Calls

In solidity, you can either use low-level calls such as: address.call(), address.callcode(), address.delegatecall(), and address.send(); or you can use contract calls such as: ExternalContract.doSomething(). Low-level calls will never throw an exception, rather will return false if they encounter an exception, whereas contract calls will automatically throw.

If the return value of a low-level call is not checked, the execution resumes despite the function call throwing errors. This can cause unexpected behavior and break the program logic. A failed call can even be caused by an attacker, who may be able to further exploit the application.

Real-World Impact: In the King of the Ether, an unchecked failed send() caused some monarch compensation payments and over/underpayment refunds to fail to be sent.

Denial of Service

Typically, there are three types of DoS attacks that can happen on a smart contract.

One of them would be an Unexpected Revert, where you were not expecting a transaction to revert, but it is reverting. Despite writing all kinds of functionalities in your Smart Contracts, which are imitating your business requirements, there is still a scenario that a different type of a user, which is not an individual Ethereum address, but another malicious Smart Contract can play with your system and not allow you to completely execute the entire algorithm, which you have written.

The next one is related to Block Gas Limit. The Block Gas Limit is the maximum amount of gas that can go through in a single block. The more complexity, the more competition that your transaction has, the higher is the gas that is required. So, there are chances where some heavy competition can result in your transactions going out of gas. This is often the case in systems that loop over an array or mapping that can be enlarged by users at little cost.

Last is Block Stuffing. So, in this attack, the attacker can place a transaction and then blocks the entire Ethereum network with a lot of transactions so that nobody else can participate in the Smart Contract. To ensure their transactions are being processed by miners, the attacker can prefer to pay higher transaction fees. By controlling the quantity of gas consumed by their transactions, the attacker can influence the number of transactions that get to be mined and included within the block.

Real-World Impact: At one time, GovenMental (an old Ponzi scheme) had accumulated 1100 ether. This Reddit Post describes how the contract required the deletion of a large mapping to withdraw the ether. The deletion of this mapping had a gas cost that exceeded the block gas limit at the time and thus was not possible to withdraw the 1100 ether.

Code Injection via delegatecall

There exists a special variant of a message call, named delegatecall. The DELEGATECALL opcode is just like the standard message call, except that the code executed at the targeted address is run in the context of the calling contract along with the very fact that msg.sender and msg.value remain unchanged. This allows a smart contract to dynamically load code from a different address at runtime. Storage, current address, and balance still refer to the calling contract. Calling into untrusted contracts is extremely dangerous because the code at the target address can change any storage values of the caller and has full control over the caller’s balance.

Real-World Impact: About $31M worth of ether was stolen in the second parity multi-sig attack from primarily 3 wallets. A method initWallet() which was supposed to initialize the wallet was not given proper visibility and was left public. This allowed the attacker to call these functions on deployed contracts, resetting the ownership to the attacker’s address. Then the attacker called the kill() method to self-destruct the contract. As a result, all Parity multi-sig wallets became useless and all funds or tokens in the Parity multi-sig were frozen forever.

Signature Replay

The basic idea of signature replay is that you can use the same signature to execute a transaction multiple times. The attacker can listen to the communication channel and make a copy of the signed message, which is possible if the communication channel is accessible. Then the attacker can resubmit it to the message receiver. The receiver won’t be able to tell the difference unless there is something in the message which identifies whether this message is sent before or not. Typically a cryptographic signature only identifies the signer and the message integrity and nothing more. There is no information on whether the signature is already used or the message has been sent several times.

Time Manipulation

The basic idea of this exploit is that miners can manipulate block.timestamp with some constraints. The constraints are that the time must be after the previous block timestamp and it cannot be too far in the future. Miner’s have the ability to adjust timestamps slightly which can prove to be quite dangerous if block timestamps are used incorrectly in smart contracts.

Real-World Impact: GovernMental (a Ponzi scheme, also discussed in the DoS attack) was also exposed to timestamp attack. In the scheme, the player who joined the round at last and was there for at least a minute got paid. Thus, a miner, who’s a player, could adjust the timestamp (to a future time, to make it look like a minute had elapsed) to make it appear that the player was the last to join for over a minute (even though this is not true in reality).

Front Running

Front-running is a course of action where someone benefits from early access to market information about upcoming transactions and trades, typically because of a privileged position along with the transmission of this information.

Every new blockchain transaction first relays around the network, then it’s selected by a miner and put into a valid block, and finally, the block is well-enough incorporated in the blockchain that is unlikely to be changed. Front-running is an attack where a malicious node observes a transaction after it is broadcast but before it is finalized, and attempts to have its etransaction confirmed before or instead of the observed transaction.

Real-World Impact: Bancor is an ICO that spectacularly raised over $150M in funding over a few minutes. Researchers at Cornell revealed that Bancor was vulnerable to front-running. They pointed out that miners would be able to front-run any transactions on Bancor since miners are free to re-order transactions within a block they’ve mined.

Other Vulnerabilities

The Smart Contract Weakness Classification Registry offers a complete and up-to-date catalog of known smart contract vulnerabilities and anti-patterns along with real-world examples. Browsing the registry is a good way of keeping up-to-date with the latest attacks.

All these vulnerabilities suggest that despite their potential, repeated security concerns have shaken the trust in handling billions of amounts by smart contracts. All the security issues should be arrested before deploying the contract otherwise the cost of vulnerability is much higher. Another attack like DAO that almost brought down the world’s second-largest blockchain will result in a catastrophe.

In the next section, will discuss Manticore. It is based on the symbolic execution of smart contracts for analyzing and detecting various types of vulnerabilities. A symbolic execution tool tries to explore all possible paths of your contract and generate reproducible input for each case. Symbolic execution has a remarkable potential for programmatically detecting broad classes of security vulnerabilities in modern software.

Manticore

Manticore is a symbolic execution tool for the analysis of smart contracts and binaries. It enables the exploration of a large number of execution paths by replacing program inputs with symbolic parameters and studying the conditions on these parameters that determine the execution of each element of the program. It’s pure Python with minimal dependencies.

According to the official documentation, these are the features of Manticore:

  • Program Exploration: Manticore can execute a program with symbolic inputs and explore all the possible states it can
  • Input Generation: Manticore can automatically produce concrete inputs that result in a given

program state.

  • Error Discovery: Manticore can detect crashes and other failure cases in binaries and smart contracts.
  • Instrumentation: Manticore provides fine-grained control of state exploration via event callbacks and instruction
  • Programmatic Interface: Manticore exposes programmatic access to its analysis engine via a Python

Not only the Ethereum Smart Contracts but it can also analyze Linux ELF binaries (x86, x86_64, aarch64, and ARMv7) and WASM Modules. Manticore is notably slow because it goes through different sections of code with a variety of attack scenarios but the end result is worth the wait.

In this blog, our main focus is on Manticore’s CLI tool, although it also offers an expressive and scriptable Python API for custom analyses and application-specific optimizations. Anyone with experience in exploitation or reversing can use the API to create specialized binary analysis tools, and answer a range of questions, such as:

“What is a program input that will cause the execution of this code?” “Can the program reach code X at runtime?”

“At point X in execution, is it possible for variable Y to be a specified value?”

“Is user input ever used as a parameter to libc function X?” “How many times does the program execute function X?”

“How many instructions does the program execute if given input X?”

Please follow this link for installation.

Detecting Vulnerabilities in Smart Contracts

Manticore comes with an easy to use Command Line Tool (CLI) which allows you to quickly generate new program test cases with symbolic execution. It’s capable of input generation, crash discovery, execution tracing, etc.

Let’s take VulnerableToken.sol as an example.

In this contract, users can buy a token by calling the fund method and destroy the token by calling the burn method. A user can take control of the contract by calling the takeOwnership method, which requires the user to have more tokens than the current owner.

Since the fund method automatically grants more tokens to the current owner if the purchased tokens are less than the owner’s balance, it should only be possible to take over the contract by buying more tokens than the current owner has in a single transaction.

Manticore by default will create an attacker account with a balance of 1000, which won’t be enough to surpass the owners’ starting balance of 1 million tokens. It should be impossible to

take over the contract. However, there is a bug in the burn function, if an attacker tries to burn more tokens than they currently own, the possibility is that they will overflow their balance and gain an absurd number of tokens. Let’s run Manticore on this contract and see if it can find the bug.

Use the below command to start the symbolic execution.

$manticore VulnerableToken.sol

Once started, it will automatically generate various test cases with detailed output.

All the generated result files will be stored in a separate folder. We will mainly focus on user_xxxxxxxx.tx and global.findings files in this blog. Details about each file can be found on this link.

The user_xxxxxxxx.tx file contains the details of the transactions that happened in a single test case and global.findings has the results of any detectors that were triggered during execution.

We can see in the CLI, manticores overflow detector first warns an overflow after the second transaction.

It must be calling the fund method immediately followed by burn. By looking through the resulting test cases, we can find the test case which allowed the attacker to take ownership of the contract.

In this test case, after the owner creates the contract, the attacker buys a symbolic number of tokens (902637). Then it calls the burn function with a massive symbolic argument, which overflows the balance and grants them a massive number of tokens. After that, they are able to call takeOwnership and have it stop successfully instead of throwing a revert.

As we have just seen, Manticore was able to symbolically evaluate sequences of the transaction, including one that revealed the bug in the contract

Manticore Detectors

Manticore cli comes with a pack of default detectors turned on (ex. Integer Overflow). These will print warnings as soon as they suspect that a state behaves in a certain way and at the end, this is going to be collapsed at global.findings.

If there is nothing printed on global.findings, we can say that no “bug” has been detected. It means that the implemented detectors did not find any contract path that matches their specific property. You can check the obtained coverage as a measure of exploration completeness.

Manticore will make a great effort to exercise all possible contract paths, though there are certain limitations (dynamic of great size arguments, call data size, number of symbolic transactions, etc).

In the output folder, you will find the transaction trace for all different contract states that manticore found. You can see account balances and all that to check manually that nothing really bad happened.

The findings and detected things depend on the default detectors enabled. The best part of the analysis is all the high coverage test cases you’ll find in the output folder. Ideally, you should check all of it to see if you can break any contract invariant (whatever that is for you) at any of them.

Below is the list of detectors available and activated by default by Manticore.

Detector Description
 

 

 

 

DetectEnvInstruction

Detect the usage of instructions that query environmental/block information:

 

BLOCKHASH, COINBASE, TIMESTAMP, NUMBER, DIFFICULTY, GASLIMIT, ORIGIN, GASPRICE

 

Sometimes environmental information can be manipulated. Contracts should avoid

using it. Unless in special situations.

DetectSuicidal Reachable self destruct instructions
 

DetectExternalCallAndLeak

Reachable external call or ether leak to sender or arbitrary address
DetectInvalid Invalid instruction detection
 

DetectReentrancySimple

Simple detector for reentrancy bugs. Alert if contract changes the state of storage (does a

 

write) after a call with >2300 gas to a user controlled/symbolic external address or the msg.sender address.
 

 

 

 

 

 

DetectReentrancyAdvanced

Detector for reentrancy bugs. Given an optional concrete list of attacker addresses, warn on the following conditions.

 

1)  A successful call to an attacker address (address in attacker list), or any human account address (if no list is given). With enough gas (>2300).

 

2)  A SSTORE after the execution of the CALL.

 

3)  The storage slot of the SSTORE must be used in some path to control flow

DetectIntegerOverflow Detects potential overflow and underflow conditions on ADD and SUB instructions.
 

DetectUnusedRetVal

Detects unused return value from internal transactions
 

 

 

 

 

DetectDelegatecall

Detects DELEGATECALLs to controlled addresses and or with controlled function id. This detector finds and reports on any delegatecall instruction any the following propositions are hold:

 

*  the destination address can be controlled by the caller

 

*  the first 4 bytes of the calldata are controlled by the caller

DetectUninitializedMemory Detects uses of uninitialized memory
DetectUninitializedStorage Detects uses of uninitialized storage
 

 

DetectRaceCondition

Detects possible transaction race conditions (transaction order dependencies). The RaceCondition detector might not work properly for contracts that have only a fallback function.
DetectManipulableBalance Detects the use of manipulable balance in strict compare.

Conclusion

Manticore is a great tool to do static analysis of smart contracts, it’s very flexible and covers a variety of bug types. These bugs, if not detected, could have resulted in a significant loss. Due to manticores’ way of work, it takes a long time to analyze smart contracts and in some cases it even times-out. Also, it consumes significant memory space as well in the system. Apart from these two issues, it’s an excellent tool to find bugs that gets even better with the scriptable Python APIs.

References

Simple Blockchain Framework: An Introduction to Block & Transaction Structure

SimpleBlockchain is a modular, developer-friendly, and open-source framework to develop blockchain applications. In this article, I will be taking through the explanation of the Block and the Transaction structure of the SimpleBlockchain framework. Keep following the GitHub repository for updates.

SimpleBlockchain framework is modular enough to integrate different consensus without changing its other core component. Also, it is generic enough to support multiple applications simultaneously using its generic Block and Transaction structures. We are using Rust language to develop the SimpleBlockchain framework. This article may contain Rust specific code snaps, as I will explain the block and the transaction structures and how they are capable to support these functionalities.

Block

A Blockchain is a chain of blocks where each block is linked with the previous block (the parent block) via adding the previous block hash. Generally, a block contains the previous block hash, miner’s id, transactions list, creation timestamp, state headers, block height, and signature. Figure (1) shows the structure of a block.

Figure (1): – Block Structure in Blockchain

A root block is a topmost block of the blockchain. A peer or an active miner node gathers transactions, executing them on the updated global state from the root block, and then includes other headers details to forge a new bock. In Blockchain, a parent hash or a previous block hash are interchangeable terms. Both terms represent the hash value of the n-1th index block for the nth index block. Since, each block holds a hash of the parent block so that if a malicious peer tries to modify data of any previously appended block, it needs to re-compute and update the parent hash of each block up to the latest block. That is why data tempering in the blockchain is near to impossible. In Figure (2), three blocks are shown Block 101, Block 102, and Block 103. Block 102 is the child of Block 101 and Block 103 is the child of Block 102. Each block has only one child. In the case of two children, one child will be discarded by the blockchain eventually. Now the question emerges is, who is the parent of the first block. Each Blockchain creates a genesis block (first block). This genesis block is created by using a predefined set of values known to everyone in the network.

Figure (2): – Simplified Blockchain

How the block structure generic enough to support the different consensus

The block structure shown in figure (1) is imprecise. In actual implementation, the block structure may contain various other fields depending on the blockchain consensus and the blockchain permission level. Example: – Blockchain consensus POW needs extra fields in block structure such as nonce, a block difficulty unit, and a block reward, etc. Blockchain consensus Gosig needs extra fields in the block such as signer’s list, a block reward, and round number, etc.

There is one more thing we need to consider. Not every field in block structure is used to generate the block signature. Example: Signer’s list in Gosig consensus will be used for the authentication process and will be excluded while generating signatures. We can call these types of extra fields as authentication headers. Besides, the nonce integer, the block difficulty unit, and the block reward are extra fields that are included while generating a block signature. We can call these types of extra fields as custom headers. It is possible to have the only either kind of header type require in the blockchain.

While working on the SimpleBlockchain Framework, we addressed this generic block structure issue, so that developers can integrate different consensus with the SimpleBlockchain framework without doing any extra work on Block Structure. Figure (3) shows the generic block structure of the SimpleBlockchain framework.

Figure (3): – Generic Block Structure

Figure (4) shows an example of the custom headers in the case of Aura Consensus

Figure (4): – Consensus Specific Custom Header

Transaction

A transaction is an activity that tries to modify a blockchain global state.

A Peer executes transactions to forge a new block. When a transaction gets executed, it invokes a function of a smart-contract. Typically, a transaction structure contains From Account, Smart Contract, function, headers, function payload, and signature, etc.

Figure (5): – Transaction Structure in Blockchain

Figure (5) shows a general structure of a transaction. From Account is the transaction invoker’s identity and this identity will be used to authentication the transaction’s digital signature. The smart-contract and the function field contain the application information which will be going to validate and handle the payload data. The function payload is the list of input parameters to the function call. The header field can have various fields such as nonce, timestamp, transaction fee, etc.

The transaction structure depends on the blockchain consensus and application it is supporting at present. That is why we need to make sure that our transaction structure should be generic enough to support these modifications.

Let me show you how the blockchain consensus and applications affect the transaction structure. Let us assume a user wants to build one application on top of the SimpleBlockchain framework that has support for Multi-Signature. In that case, the framework must have that much structural flexibility to add support for the same. On the consensus side, one consensus can have fields such as Gas price or Transaction fee. To resolve the upper mentioned challenges, we created a generic transaction structure shown in Figure (6).

Figure (6): – Generic Signed Transaction Structure

As shown in Figure (6), the txn field stands for serialized data of User-defined internal transaction details. The app_name is an application identification. The header may hold some consensus defined values and timestamp in key-value pair format. The signature field as the name suggests holds the digital signature of the transaction. This signature field data can be multi-signed or the normal one and its validation process will be defined accordingly by the application itself. The developer needs to take care of a transaction data sanitization and the other validations.

Figure (7): – User-defined Transaction Structure for Cryptocurrency Use Case

Figure (8): – User-defined Transaction Structure for Document Review Use Case

How does Transaction Structure support multiple applications?

As shown in Figure (6), the “txn” field contains serialized transaction data of the user-defined application. That means the application developer got free hands to develop application business flow, the validation mechanism, the state management, etc. The only constraint is that the developer must implement traits shown in line no 2 & 3 figure (7) on its Transaction structure. Figure (7) shows a user-defined transaction structure for a cryptocurrency use case where one can trade money with others. Figure (8) shows a user-defined transaction structure for the Document Review use case.

You can find both applications for your reference under a simpleblockchain/src/user module. If you happen to have a new bug or a new idea, feel free to open a new issue.

State Channels: Use Cases and Applications

As I explained in the previous blog, the State Channel solves blockchain scalability, transaction fees, and privacy concerns. In this blog, we’ll look at the potential use cases that can be implemented as decentralized applications (DApps) using State Channels and the approach involved.

For a quick recap of the previous blog, the State Channel is a technique designed to allow users to make multiple transactions without committing all of them to the Blockchain. In the traditional State Channel, the Smart-Contracts defines the initial state of the State Channel. Users can carry out an infinite number of transactions outside the Blockchain by making continuous changes, starting from the initial state. Any user can send the latest state as a closing statement to Smart-Contract on the Blockchain. Also, users can verify each state transition validity using Smart-Contract on the Blockchain.

The State Channel off-chain gives instant-finality and data-privacy with negligible transaction fees. This, in turn, has gone a long way in terms of establishing their importance in case of DApps scalability. Gaming DApps can use the scalability potential of State Channels, wherein participants either buy or sell game artefacts or indulge in gambling like in case of card games. Likewise, video streaming DApps can use State Channels to facilitate applications on a pay-per-use basis. Domains such as Supply Chain Management and P2P micro-payments can also benefit from the scalability and privacy potential of State Channels.

Use Case of State Channels: Supply Chain Management

Our businesses have widened globally, complicating the whole ecosystem of supply chain management. Let us consider the case of the food supply chain. Have we ever imagined the source from where we get our food?

The supply chain in the food industry is defined by associating the following:

  • Crop Origination
  • Food Processing at Refineries
  • Distribution of processed food to retailers
  • Selling of Food Items to Consumers

Since the food supply chain consists of millions of people worldwide with tons of raw materials and food crops, it becomes challenging for the food manufacturers and consumers to know where the different components of the food item belong.

The supply chain’s contracts can be quite complicated, costly, and susceptible to errors due to the involvement of paper-based trails for the change of ownership, letters of credit, bills of lading, and complicated payment terms. Therefore, we can use State Channels to bring in transparency and real-time traceability in the whole supply chain system.

How do State Channels Help?

Supply chain management consists of raw materials, manufacturing, distribution, and consumers. The quality of each raw material, the manufacturing processes, and distributors are tagged uniquely using Hashing algorithms.

Any product includes various raw materials and goes through different manufacturing processes. At the end of the production cycle, they are delivered to the consumer. Therefore, the product off-chain state should keep a record of raw materials, manufacturing processes, and shipping processes.

Figure (1): – State Channel between Supplier and Manufacturer

A Supplier supplies different raw materials to the manufacturer. This process will run in its separate State Channel. By the end of the process of purchasing, the manufacturer receives raw materials from different suppliers. Since these states were finalized already, they will be updated on the Blockchain and represented by the Non-Fungible tokens.

Figure (2): – State Channel for manufacturing Process

The manufacturing step includes multiple processes and consumes a variety of raw materials. When the product is ready, its state will consist of used raw materials token tag from the previous ERC20 tokens and processes tag. The Distribution process will deliver products to retailers, and the end consumer can get it from the retailer.

Figure (3): – State Channel for the delivery process

Figure (4): – State Channel for Retailer

In each process, the off-chain states can include different details and can be verified using a specific verification pattern. These details can be either product’s raw materials, manufacturing process information, or payment information. Therefore, the final state will update the ownership of the product and transfer the equivalent coins to the respected wallets on the Blockchain.

Here, we do not need to attach original letters of credit, bills of lading on the Blockchain. Instead, we should attach hash of that document on the Blockchain, so that users can compare document hash with hash updated on the Blockchain and verify authenticity of the original bills.

In Figure (4), the consumer can verify the product manufacturing details and the delivery process using the finalized state of Figure (3) State Channel. The finalized state from Figure (2) State Channel can be linked-to the verification process of the State Channel in Figure (3). The finalized state of the raw materials purchasing process from Figure (1) State Channel will be attached to the product being made in the State Channel in Figure (2).

This will bring transparency, privacy, and cost reduction in the whole supply chain management.

DApp Components

DApp built using State Channels would be based on a similar set of components, every DApp consists of a user DB component to ensure off-chain states security and a client application responsible for interacting with the Blockchain smart contract and with other participants.

The Smart contract defines the details that are going to be a part of the state structure. The same state structure will be used in the digital signature and verification process. Example: – A State Channel structure for chess game must hold chessboard state, chessboard id, and the Smart-Contract address.

The client application opens a State Channel on the Blockchain, and then the smart contract will initialize the State Channel using given inputs and predefined business logic. This business logic could require an on-chain confirmation from other participants before the State Channel goes into the active state. Once State Channel is activated, the initial state has been updated and available to all participants on the Blockchain. The client applications use this initial state and start off-chain transactions among them. The client applications must keep the latest off-chain state precisely for that they can use separate secure DB components. The non-tempered latest state will prevent all malicious actions of other participants.

Figure (5) shows a simplified architectural overview for a State Channel DApp.

Figure (5): – State Channel Generic Architecture

Conclusion

State Channels trade-off speed, finality, and transaction cost along with unparalleled security. We kept off-chain transaction states in a separate DB component to minimize the security trade-off. We make sure the uniqueness of the state details across the Smart-Contracts on the Blockchain network to prevent replay attacks.

I hope you find this article useful and insightful. To deep dive into some of our work around State Channels, you can check out the GitHub repository. Happy reading!

References

State Channels: An Introduction to Off-chain Transactions

In recent years, Blockchain technology has become a running theme, although the worldwide acceptance of this technology is still inconclusive due to its scalability, anonymity, and transaction costs. In this article, I will make you understand how the issues mentioned above are restricting Blockchain adoption across everyday applications. Let us assume that Alice and Bob are playing a game of chess that is designed at the top of Blockchain technology. For making a move, a player obliges to pay the transaction fee and wait for the move confirmation on the Blockchain as the chess move requires state changes and state changes need to be committed on the Blockchain. Such confirmation time and validation fee inclusion make Blockchain technology inaccessible to tiny hands. Even if we omit the transaction fee issue, the `current Blockchain solutions are not scalable for decentralized applications (DApps). State channel addresses these concerns without significantly increasing the risk of any participant.

What is the State Channel?

State channel is a technique designed to allow users to make multiple Blockchain transactions such as state changes or money transfers, without committing all of the transactions to the Blockchain. In the traditional state channel, only two transactions are added to the Blockchain, but an infinite or almost infinite number of transactions can be made between the participants. Example: In a Chess game built on top of state channels, the chess game beginning move and closing move should be committed on the Blockchain. All other moves can be made off-chain without the involvement of the Blockchain. These off-chain transactions do not require a fee with instant finality.

A  Payment channel is one implementation of the state channels, which deals with money transfers. A state channel is a smart-contract that enforces predefined rules for off-chain transactions. Each transaction creates a new state based on the previous state, signed by each party, which is cryptographically provable on the blockchain. Every new state makes the last state invalid since the smart-contract acknowledges only the highest state as a valid state.

State channels don’t have a “direction” because they are a generalization and a more powerful version of payment channels. Consider a unidirectional channel as one whose state is simply one state value: “Alice’s payment to Bob”. Consider a bidirectional channel as one that has two state values: “Alice’s balance” and “Bob’s balance”.

Working of State channels

In a state channel application, each party must sign an initial (opening) channel transaction, and deposit money according to application business logic. Users need to pay predefined transaction cost each time they either open a new channel or deposit money into the active channel. A deposit transaction deducts money from the depositor’s account and transfers it to the smart-contract address. This depositing mechanism will ensure that there will be no double-spent occur in on-chain or off-chain network. The smart-contract is not authorized to mint or destroy money, therefore in each valid state, all participants combined money equals total deposited money no more and no less. Figure (1) demonstrates a generic idea of the State Channels.

FIGURE(1):- STATE CHANNEL GENERIC SOLUTION

Let us re-consider the example cited above. Alice and Bob want to open one payment channel since they are playing a tic-tac-toe game, and after each game, they want to transfer money. Initially, they both signed the opening transaction and deposited 100 and 100 cash on the board. Alice and Bob are expected to pay transaction fees only at the time of channel opening, and now they can play the infinite number of game rounds without paying transaction fees with instant transaction finality. Assuming they decide to leave the game after the nth round, and the latest state was Alice 75 and Bob 125. Either Alice or Bob can send a channel closing transaction with the latest valid cryptographic state. It will take some time and transaction cost to validate this closing transaction, and the transaction, in turn, will send cash back to the respective wallet.

Payment Channel benefits over on-chain transactions

Cheap

Participants pay validator fees at the time of opening and closing channels. All other transactions are free even though the number of transactions is hundreds or thousands.

Instant Finality

On average, Bitcoin will take about 10 minutes to complete the transaction, and Ethereum will take 15 seconds to 5 minutes if you pay the regular gas price. That means if Alice made a move, the game would stop until the move is confirmed on the chain. On the contrary, payment channel transaction finality depends on the bandwidth of the network, more the bandwidth faster the finality.

Privacy

All on-transactions are registered in the Blockchain ledger and are available in the public domain. Anyone can analyze these Blockchain data and get insights into the individual. On the contrary, state channel off-chain transactions are not committed in the Blockchain except for opening and closing transactions that give participants a considerable degree of privacy.

Scalable

Off-chain transactions do not change the on-chain state, therefore the payment channel Apps are scalable. And if we can build a network of payment channels like the Raiden Network or the Lightning Network, then we don’t have to open a direct channel between the two parties if there is some indirect channel that leads to scalability.

Security

Security of payment channel states depends on how the smart- contract validates the states, what information is included in the states such as (1) state nonce, (2) smart-contract address, (3) channel Id, (4) state and stakeholder status, etc. Each participant shall make a digital signature to validate the current state. The aim of including this information in the state is to make each state universally unique like UUIDS. The smart contracts address and channel id, together used to prevent cross-contract and in-contract replay attacks.

Remaining Challenges

The Payment Channel will lock down the deposited money in the smart-contract and release it after the channel has closed. No one wants to lock up a massive amount of capital in a smart-contract that makes payment channels useful for micro-payments. Each state compels all participants to sign, which is why one offline participant can stop the processing of the payment channel.

I hope you found this article to be insightful and useful. To deep dive into some of our work around state channels, you can check out the GitHub repository.

Should a blockchain node save all the transaction logs?

Introduction:

Blockchain is a technology that drives all the cryptocurrencies. In every one of them, a set of validator nodes are responsible for validating all the transactions. The validators are assumed to be rational and self-interested, i.e. they are only interested in making as much money possible for themselves. Under such assumptions, it is generally assumed that a required majority of the validators would agree on the sequence of transactions that have ever happened on the blockchain.

However, such blockchain validator nodes are generally expensive in terms of the size of the disk space they need. The oldest and most popular cryptocurrency Bitcoin, for example, needs about 200 GB of disk space to store the entire transaction log. This makes it necessary to have a high-speed connection and a lot of time to even get started on mining or validation. This is a problem that prompted researchers to suggest sharding as a solution, i.e. storing only part of the log in each node, but storing the entire log as a whole. Sharding comes with its own challenges when it comes to validating transactions.

But, does it make sense for a node to store the transaction log starting all the way from the genesis block? This is an important question that needs to be answered before such solutions are crafted.

To understand whether saving all the transaction log is possible/necessary, we consider the following points –

1. Is it necessary to store the entire transaction log to validate transactions?
2. Is it more secure to store the transaction log than not storing it?
3. Is it possible to incentivize the validator nodes to store the log?

We take on these points in the rest of the article.

Is it necessary to store the entire transaction log to validate transactions?

To validate a transaction, the only thing that a node needs is to know that state of the blockchain right before the transaction. It is immaterial how that state was achieved. So, it is enough to store the state after each block. In fact, we can go even further – since the blocks that have been mined a long time before the current time are hardly ever going to be undone, it is safe to delete all the previous blocks.

The natural question that comes to our mind is if it would somehow compromise the safety of the blockchain, i.e. – would it somehow make the blockchain to approve a transaction that is not correct based on the current state of the blockchain? To answer this question, we move onto the next section.

Is it more secure to store the transaction log than not storing it?

When thinking about it, we need to think in terms of security of the whole transactions and not just the part on the blockchain. Most transactions have two parts – a payment on blockchain and the receipt of something of value in exchange. The second part of the transaction is not stored in the blockchain. This means the seller that sells the product or the service in exchange for some cryptocurrency relies on the blockchain not to revert the transaction after he/she provides the product or the service. This, in turn, means that there has to be a reasonable time after which the transaction must become completely immutable requiring the block in which it is included to be immutable too. In other words, we need some finality of the transaction and the block. When a block is finalized in some form or other, it is okay to forget what happened before that and simply continue as if that block is the genesis block. This in general means that the transaction history must be stored only up to a short period of time. In the case of Bitcoin, people normally assume that a block is pretty much finalized after an hour of time, so it makes sense to delete all the history before that. That means, in the case of Bitcoin, a validator only needs the list of UTXOs at the end of each of the last few blocks.

We now turn towards our final point.

Is it possible to incentivize the validator nodes to store the log?

As stated earlier, the validators are assumed to be selfish and rational. Which means, they need to be paid or rewarded for doing anything. Since the validators only get paid in cryptocurrency for mining the blocks in all public blockchains, that’s the only thing they should be doing. We have also seen that the storage of the data is not necessary for doing the job of validating. Therefore, there is no incentive for any validator to store the entirety of the transaction logs starting from the genesis. If we indeed want the rational validator to store the entire history of the transactions, we must sufficiently incentivize the validators to do so. We may want to require proof of storage of all the transactions in a block for it to be considered valid. Is it possible to do it? Yes indeed, if we change the proof-of-work consensus protocol as follows –
1. Let a block being proposed be B and the corresponding proof-of-work be p. This means that p is the nounce such that hash(B||p) < threshold.
2. Let the number of transactions before that block be N.
3. Let h = hash(B||hash(p)), where || means concatenation.
4. Compute the remainder r when h is divided by N. Since, h is typically a 256-bit number, it must be the case that h is way greater than N, so this means r is less than both h and N and can be considered a random sample from the set of natural numbers less than N.
5. Let the transaction with the sequence number r be tr. The transactions are indexed from 0 to N-1.
6. Now, the block proposal must be (B||p|| tr ) for it to be considered valid.

It is easy to see that if the validator does not store all of the logs of transactions, it would need more effort to generate valid blocks since it has to throw away all the proof-of-work and start over if the corresponding transaction is not stored by it. More specifically, if a validator stores on a fraction f of all the history, it has to throw away the proof-of-work 1/f times on an average, significantly reducing its average mining reward for the same amount of processing power. It is, therefore, most efficient for any validator to simply store all the transactions from the genesis block. But, such a system is not currently used, so the validators are really doing a social service by still storing all the transactions. However, from our discussion on security, it is clear that such a modification can be quite unnecessary.

Another issue is that when a new validator joins, it must download the entire transaction log from its peers. The peers, however, are not incentivized at all to provide this data to their new peer. They are simply adding a competing mining power while also burdening their own bandwidth to broadcast the information. The least we can do is to relieve them from having to broadcast the entirety of the history of transactions.

Conclusion:

We can see that it is possible to mandate the storage of all the transaction history if we choose to design the blockchain in such a way. However, it seems quite unnecessary and cumbersome. It may even provide more motivation for the existing miners to provide the needed data to any new joiners. We have also seen that there is no advantage of storing the transaction history in terms of the security of the blockchain, so we might as well not want to do so.

Plasma Cash DApp Use Case

The Plasma Framework solves the privacy and scalability issues of the public Ethereum blockchain. In this blog, we will take a closer look at the possible use cases that can be implemented as decentralized application (DApp) using Plasma Cash, and how can those be implemented.

Plasma Cash Use Cases

Plasma Cash converts all deposit tokens into a non-fungible-token (NFT), wherein each NFT token holds a unique and stagnant behavior. Therefore, Plasma Cash can be an ideal fit for applications where assets aren’t divided and ownership is changed frequently. Gaming Dapps can use the scalability potential of Plasma Cash where users exchange game objects modeled as token, for instance any character’s card, suit, or any power. In addition, non-gaming models can also benefit from the scalability and privacy potential of Plasma Cash. For example- Artifact review workflow application (developed as DApp) in an Enterprise, where a given artifact is transferred between users and the artifact can hold one of the states, namely Created, Submitted, Rejected, Accepted, and many more.

Document Review Workflow Use Case

In any enterprise, artifacts such as Product (Service) specifications, quotations, proposals, etc. are created and transferred to multiple departments for evaluation. Each stake holder can reverse it conclusively, accept it, or transfer it ahead, and Plasma Cash is the best fit for an application like this. Here, the artifacts can be modeled as NFT tokens and state changes are similar to NFT ownership transfers. The final state will be transferred to the Ethereum parent chain.

 

Figure (1) shows a simplified workflow of an artifact.

Consider a document created by a user and the document owner has submitted it to another user for review. In this step, the document moves from ‘created’ state to ‘submitted’ state. After successful review, the reviewer will send this document for publication to the third user and the document moves from the ‘submitted’ state to the ‘reviewed’ state. Post publication, the document state is changed to ‘published’ state.

The deposit function of the plasma contract will take document hash as the input and produces an equivalent NFT token as output. As document state is altered, it’s equivalent NFT token goes through corresponding state changes; after publishing the document, the NFT token will be transferred to the Ethereum parent chain using the plasma contract exit function.

DApp Components

DApp built using plasma would be based on a similar set of components i.e. every DApp consists of an operator process, a user component to ensure child chain security to arrest double spend, and a client application responsible for interacting with the child and the parent chain.

The client application deposits a token to the Plasma Chain smart contract on the parent chain, then the smart contract will return an unsigned integer and emit a DEPOSIT event. So far, DApp only has UID knowledge and DApp needs to fetch the deposit block index. For that, DApp needs to monitor all the upcoming blocks on the child chain and check whether the upcoming block has a deposit block with the same UID. The block index is the utmost important property either for security or transferring it to another user. The user component maintains all token’s UID of the user and corresponding block index details and watches the child chain at least once during the exit period. The user component fetches all the upcoming blocks and smart contract states to check incoming tokens, or if anyone has tried an invalid exit or a double-spent, and then, raise counter action appropriately.

Conclusion

We are working on Plasma Cash for use-cases where we need to change one or more states including NFT transfer. In case we have got you interested enough, do check out our work on the GitHub repository.

Plasma Cash Side Chain

Problem with the current solution (blockchain)

Blockchain gives us a reliable, trust-less secure system with no central governance. In spite of having such capabilities, enterprises do not prefer to use public blockchain for building solutions. The primary reasons for this are privacy and scalability. Since all blockchain data is publicly available, one can use blockchain analytic tools to get insights such as a linked public address, spending habits of a user or public address and then who transferred what to whom. The second reason is that scalability is a critical issue with any blockchain. Currently, blockchains handle [3-30] transactions per second, which is nowhere near the mainstream centralized payment system. Example: Visa processes around 1700 transactions per second.

Proposed Solution

Since privacy and scalability are major and widely known interests in the blockchain community, all are trying to solve it in their own way. Joseph Poon and Vitalik Buterin came up with the idea of a child chain called Plasma. A plasma framework is a smart contract that will be deployed on the Ethereum main chain (parent chain). The smart contract will enforce the child chain to follow predefined rules. The plasma child chain is not empowered to create or burn any artifacts such as fungible ERC 20 tokens or non-fungible ERC 721 tokens (NFT). Therefore, to operate on the plasma child chain, users need to transfer their parent chain ERC tokens to the plasma child chain. The plasma child chain is built on the top of the parent chain in a way that whenever it appends a block in the child chain, it must add the Merkle root of that block to the smart contract on the parent chain otherwise that block will be invalid. The plasma framework will solve the privacy problem since no transactional data history will be added to the public parent blockchain. It is using Proof of Authority consensus so that it is far better scalable in terms of transactions per second and will have all the benefits of blockchain technology.

 

Figure (1) shows different variants of the Plasma Framework. Since the idea of the plasma child chain came up, the whole Ethereum community is working on improvements. Therefore, today, multiple designs of plasma framework exist such as Plasma-MVP, Plasma-MoreVP, Plasma-Cash. Individual plasma also has multiple variants with slightly different use-cases.

 

 

Figure (2) shows the generic idea of the Plasma Framework. Each variant of the Plasma Framework implements its Smart Contract using this abstract idea. Therefore, each Plasma smart contract implements the following interface.

Interface:

  • DEPOSIT
  • EXIT
  • CHALLENGE

Including the above-mentioned function, all methods/functions of the smart contract can have different implementation depending on the idea of that Plasma variant.

For example – In Plasma-MVP users must sign a transaction when they make a transfer and again when it gets confirmed. Therefore, for a single successful transfer, the user must sign it twice. Plasma Cash users need to sign only once for a transaction, and each token behaves like NFT.

Plasma Cash

We are working on the Plasma Cash framework and building a decentralized application (DApp) on top of it. The Authority (The Operator) of the child chain is the public address who deployed the smart contract to the parent chain. Only the operator has the authority to append a block into the child chain. The operator can append a block in two ways. First, when a deposit occurs in the parent chain, then the operator will create a block having one UTXO equivalent to the deposited amount. The other way is to create a block by including all token transfer transactions. The smart contract emits a distinct event for each activity in the parent chain so that users listening to the smart contract will get to know all state changes of the smart contract. These events are like meta-data of the child chain.

Let’s take an example of how useful these events are. Assume a user deposited an asset to the plasma smart contract if the operator will not listen to events from the smart contract, it will never get to know that a deposit transaction happened on the parent chain and will not include that transaction’s equivalent NFT token to the child chain. That is why it is necessary for the child chain operator and for the users to listen to the smart contract events.

Once a token is added to the child chain, it can be transferred to any user. The plasma cash is UTXO based model. Therefore, transferring a token implies spending a UTXO and creating another UXTO which holds new ownership. Whenever a user wants to create a transfer request, it will need to provide the UTXO details such as UTXO’s unique ID (UID) and the index of the block in which the UTXO was created.

At any time in the future, a user can transfer its token from the child chain to the parent chain. This process is called the Exit process.  The exit process can be initiated by a token owner to the smart contract on the parent chain. The exit process consumes the given token from the child chain and molds it into the equivalent amount to the parent chain.

 

 

The operator performed all safety validations on the child chain side, and the Plasma smart contract handles all the security checks on the parent chain side. The operator keeps all UTXO states; therefore all double-spent and invalid state transition attempts can be rejected. Figure (3) shows the legitimate operator case. Assuming the operator is behaving according to the predefined rules, there will be no case of block withholding scenario so that the only way of either stealing money from the child chain is invalid Exit request on the Plasma Smart contract. The Plasma smart contract enforces the whole exit process.

 

 

Figure (4) shows the invalid exit scenario and related activities on the child chain and the parent chain. Since the parent chain holds no transactional details of the plasma child chain, therefore, the smart contract will not be able to confirm or decline the upcoming exit requests. Plasma smart contract adds all upcoming exit requests to a waiting queue and either confirm or reject after a predefined waiting period.  This waiting period is described as the Exit Period. The exit request refers to a UTXO, and the UTXO describes a unique NFT token and the owner details. All exit requests referring to different NFT tokens are independent of others and can be processed in likewise order. However, exit requests referring to the same NFT token can cause stealing if they are processed in likewise order. The plasma smart contract evaluates all exit requests in priority order. The priority order is calculated using the exit request’s UTXO details. The exit request referring to UTXO with a lower block index will be executed with a higher priority. Therefore, the last valid token owner can always successfully transfer it to the parent chain.

In the case of the legitimate operator, there will be no invalid transfer possible in the child chain. As described earlier, the only possibility will be an invalid exit request on the parent chain. Any invalid exit request will only finalize after the exit period is over and if there is no valid challenge raised with Merkle proof against it. Merkle proof is the valid transfer history of the NFT token in the Plasma child chain, and it can be either calculated or retrieved. Therefore, valid owners must look at exit requests and need to raise the challenge so.

 

 

In the case of the malicious operator, the operator can accept double-spent and invalid state transitions and include these invalid transactions in the upcoming block. Figure (5) shows the malicious operator scenario. The operator can also withhold a block that symbolizes a block that is added to the child chain but available to users. Due to withholding the blocks, users are not able to decide how to react now. Since an invalid exit request referring to either double-spent or invalid state transition UTXO cannot be declined via any challenge with Merkle proof. When these situations occur, affected users will only have one option to create an exit request referring to the last valid UTXO. In the above-mentioned scenario, no invalid exit request can be executed as finalized if the owner is observing the token states.

This extra burden on users makes the child chain independent of the operator for security.

All security points are mathematically proven in the white paper by Joseph Poon & Vitalik Buterin.

Architecture

 

 

The figure (6) exhibits a simplified architectural overview for a side chain DApp.

Conclusion

If you are curious to see our work, check out the GitHub repository.

In the upcoming blog, I will cover the possible use-cases and DApp implementation of Plasma Cash.

Decentralized Applications – Utilizing the Power of Blockchain Technology

A decentralized application (dapp, Dapp, dApp or DApp) is a computer application that runs on a distributed computing system.

Dapps, by definition, are regular/web/mobile applications built on top of a p2p network with below characteristics

  • Completely Open Source – to gain the trust of potential users and increase transparency
  • No Central Point of Failure – Application data cryptographically stored across all the nodes.
  • Cryptographic Tokens (app currency)- the Dapps must use cryptographic tokens for application usage and incentivization.
  • Decentralized Consensus – to support a trustless environment; and a mechanism to achieve consensus.

In this series of blogs, I am going to describe the common architectural components that constitute a Dapp. A real-world use case will be presented where scarce resources are shared in a distributed and trustless environment with no central authority or intermediaries. Afterwards, I will be providing code snippets of the Dapp built on top of EOSIO blockchain framework using a simple React.js web app along with reference to the git-repo.

Architectural Components

At the very basic, a Dapp has two components. Frontend and Backend. The frontend is a regular web application created using HTML/CSS and other web technologies. However, instead of interacting with a centralized backend server, they interact with blockchain node using smart contract(s). The application data in Dapp is stored in a decentralized way and the wallet-based mechanism is used instead of login/password to store user information in a secure way. In most real-world applications, there is also a need for some backend module where non-transactional/non-critical data is stored and utilized by front-end.

Since a smart contract cannot interact with the outside world, a trusted (and most often decentralized) service is used to fetch live data such as stock price or weather update. These trusted services are called oracles.

Blockchain Node

A full blockchain node stores a full copy of blockchain transactions, current state and blockchain protocol implementation along with API endpoints for clients. This validator node (or minor in bitcoin terms) is responsible for validation of transactions and generation of blocks.

Smart Contract

A smart contract is a cryptographically secure code segment on blockchain executed by validator node when a client triggers some action on that contract. This action takes the blockchain from one valid state to another and requires some incentive for the validator to consume his resource for taking up this task.

Wallet

User management in blockchain is done in a decentralized and secure way using the concepts of public-private key cryptography. Users use their private keys to sign all the transactions and publish a public key for anyone to verify. This allows for password-less authentication across web services and the private key is never revealed to the server or third parties. This private key is never shared with anyone.

These keys are stored safely in a wallet on the user’s mobile or computer and used by the user application while sending transactions.

Techniques like hardware wallets and custodial wallets can be utilized for specific use cases.

Web/Mobile Application

The frontend is a regular HTML/CSS/Javascript application which uses client javascript libraries like web3.js (for ethereum) and EOS.js (for EOSIO) to connect to the blockchain server via JSON RPC protocol and utilize the wallet functionalities for transactions.

Data Storage

1 KB of storage (in form of contract code or data fields) costs 0.032 ETH on Ethereum. In EOS, a user needs to stake 0.053 EOS to access 1KB of memory.

As we can see, Blockchain is not suitable for storing application data as this data needs to be replicated across all network nodes. We need an alternative storage mechanism that is price efficient and follows the distributed systems philosophy of blockchain.

IPFS is designed to create the content-addressable, p2p method of storing and sharing file data. I used IPFS as a mechanism to store our application data such as available parking spaces and retrieve using the generated hash code.

Couple of caveats that we need to take care of:

  • At least one IPFS node should be up and have accepted to store my data.
  • If the data contents are changed, hash codes need to be updated in an application as the stored hash codes are not valid anymore. This can be resolved using IPNS

Communication

Most blockchain frameworks provide ways for one smart contract to execute the action on another contract. This is useful in scenarios where one transaction needs to be triggered by another or there are dependent transactions that need to be executed in sequence.

To communicate some blockchain event to a front-end app, there are different mechanisms provided which differ across blockchains. Most of them provide block-level event notification which can be used to either update the front-end or execute some backend job.

Conclusion

In this blog, we explored the architecture of a common Dapp. In the next part, we will continue with a real-world use case of the blockchain, ParkAssist – a distributed parking space sharing application.