Getting Started

This documentation shows your way around DEXON, the next generation blockchain platform.

Overview

Accessing DEXON Network

To create a DEXON wallet and start using DEXON blockchain platform, follow wallet creation guide.

DApp Development

  • To learn abour DApp (decentralized apps) development and build DApps on DEXON, follow DApp development guide.
  • If you have already developed DApps on Ethereum and is planning to move your existing DApp onto DEXON, check out Etherum DApp migration guide.

Node Operation

Fullnode Development

You can contribute to the development of DEXON itself! Get started with DEXON fullnode development guide.

Technical Documentations

To learn more about how DEXON works, check out our technical documenations

Introduction

DEXON is a permissionless, proof-of-stake blockchain system that features high throughput and low latency. Current mainnnet is able to reach 10K TPS, and maintain ~ 1 second confirmation latency.

This documentation shows your way around DEXON, the next generation blockchain platform.

Accessing DEXON Network

To create a DEXON wallet and start using DEXON blockchain platform, follow wallet creation guide.

DApp Development

  • To learn abour DApp (decentralized apps) development and build DApps on DEXON, follow DApp development guide.
  • If you have already developed DApps on Ethereum and is planning to move your existing DApp onto DEXON, check out DApp Development Guide.

Node Operation

Fullnode Development

You can contribute to the development of DEXON itself! Get started with DEXON Fullnode Development Guide.

Technical Documentations

To learn more about how DEXON works, check out our technical documenations

How to use this documentation

This documentation is designed for the users who want to understand or participate in DEXON network.

we list the following categories:

For Developers

For Miners

Network Access Guide

Create Wallet

A cryptocurrency wallet is a store to keep private keys when interacting with blockchains. DEXON foundation provides a chrome extension as wallet for you.

Precautions

There is still no best practice in protecting private keys when holding/using cryptocurrency. What we provide is simply the most convenient way, use it at your own risk.

Wallet Secrets

There are three types of secrets when using a DEXON wallet.

Password

A password is required when accessing secrets through the wallet, ex.

  • export the private key of one account.
  • reveal seed phrases.

Seed Phrases

The seed phrases composed of 12 or 24 words is used to generate private keys for newly created accounts. Since all private keys generated from one set of seed phrases are identical, it can be used to migrate your account from one computer to another.

Accounts

An account in DEXON Wallet is actually a private key, which can be used to interact with DEXON blockchain.

Risks

If your computer gets hacked, the hacker might stole your account or seed phrases, and transfer your digital assets to somewhere else.

Or you may lose your secrets for some reason. If that happened, no one but GOD can access those digital assets.

Install DEXON Wallet

Please go to this link and follow instructions to install DEXON Wallet. If the wallet is freshly installed (not from restoration), you will get 12 seed words, please keep them secretly and safely.

Create New Accounts

When DEXON wallet successfully installed, a default account would be created and ready to use. If you need more accounts, it can be done via DEXON Wallet:

  • click the blockie image on the top-right corner.
  • click Create Account element.
  • click Create Button or give this account a name.

Restore from seed words

The accounts created on one wallet can be migrated to another computer via seed words.

  • install DEXON Wallet. Instead of creating it freshly, choose Import with seed phrase
  • type in those seed phrases you keep secretly before. NOTE: the order of words does matter.
  • setup new password.
  • restore those accounts by creating them again.

Access DEXON Network

There are a few options on how to access DEXON networks. The first is to use the public DEXON RPC endpoint, the second one is to run a fullnode and sync the fullnode locally.

Public RPC Endpoints

The public RPC endpoints are available at:

NetworkRESTfulWebSocketChain ID
Mainnethttps://mainnet-rpc.dexon.orgwss://mainnet-rpc.dexon.org/ws237
Testnethttps://testnet-rpc.dexon.orgwss://testnet-rpc.dexon.org/ws238
Taipei Testnethttps://taipei-rpc.dexon.orgwss://taipei-rpc.dexon.org/ws239

Point your DEXON/Ethereum client to this RPC endpoint and you should be able to read from and send transactions to DEXON networks.

Syncing Fullnode

The testnet could be synchronized with the following command:

gdex --testnet

If you don't know how to build the gdex binary, please follow the wiki page here.

It may take a few hours before your fullnode is fully-synchronised. When it does, you can now point your DEXON/Ethereum client to http://localhost:8545

Note: DEXON's current testnet is still unstable, it might be reset at some point. If it does, you might have to remove the data directory ($HOME/.dexon on Linux, and $HOME/Library/Dexon on MacOS) and re-sync the node.

DApp Development Guide

Hands-on: Hello DEXON

Prefer to learn by examples? follow the steps in Hello DEXON to get a quick grasp of how smart contract, web app and wallet extension all work together as a DApp.

Migrate from Ethereum

If you have already developed DApps on Ethereum, you can skip to Migrate from Ethereum and learn what the differences between DEXON and Ethereum are.

Introduction

DApps are decentralized applications built on top of blockchain platforms like DEXON or Ethereum. At the heart of every DApps are smart contracts. Smart contracts are programs compiled into VM bytecode and deployed onto the blockchain platform.

After deployment, a smart contract resides on an address, just like any other regular account. Everyone in the system can interact with the smart contract by sending transactions to the contract address.

Currently, DEXON uses the same account system as Ethereum. DEXON also has its default VM built from VM Ethereum's virtual machine (EVM). So DApp development on DEXON is almost the same as on Ethereum.

Solidity

The most commonly used language to develop a DEXON/Ethereum DApp is Solidity, which we will introduce briefly in the next section.

DEXON's version of EVM is almost the same as the original EVM, therefore DEXON version of Solidity is almost the same as the original Solidity. If you have built a smart contract on Ethereum, you can usually deploy the exact same contract onto DEXON without any modification.

However, there are still some minor differences between the DEXON's version of Solidity and its Ethereum counterpart, because of the boost in performance and the On-chain Random Oracle that DEXON provides. We will cover these differences in Migrate from Ethereum.

DEXON Remix IDE

Remix is a web-based integrated development environment, originally built for Ethereum. The DEXON version of Remix is available HERE (Github Repository).

With Remix IDE, you can develop, compile, deploy and debug your smart contracts easily from the same interface.

There are other tools for developing and testing smart contracts. However, if you are a beginner in DApp development, we suggest that you try out Remix IDE first.

Interact With Smart Contracts

Once you have deployed your smart contracts on chain, the next step is to interact with your contract from your UI, which can either be a web app or a native mobile app. This section shows you how it's done.

Tools and Libraries

DEXON provides a wide range of tools and libraries for DApp development, listed HERE.

Hello DEXON

This section walks you through the Hello-DEXON Project.

You will learn how to:

  • Compile and deploy smart contracts, on

    • Local mocked DEXON
    • DEXON testnet
  • Run contract tests

  • Run a web UI to interact with the contracts

Let's get started.

Prerequisites

You need to have these installed on your system first:

Setup Project

# Download from github
git clone git@github.com:dexon-foundation/hello-dexon.git

# Get inside project directory
cd hello-dexon

# Install dependencies
npm install

# Setup mnemonic phrases (copy from DEXON Wallet Extension)
cp secret.js.sample secret.js

Then you have to put your mnenonic phrases from DEXON Wallet into secret.js

Project Structure

  • ./contracts
    The smart contracts of the project. The one you should care about is Hello.sol.

  • ./src
    JavaScript code for interacting with the smart contract.

  • ./test
    Contract test cases.

Compile Smart Contract

npm run compile

This will compile your smart contracts and generate ./build/contracts/Hello.json. You can see the bytecode and ABI compiled from Hello.sol.

Test Smart Contract

# Run local Ganache RPC
npm run rpc

# Deploy and test on local RPC
npm run test

This will deploy your contracts onto local Ganache RPC and perform tests on them.

Run Smart Contract on Local Ganache

# Run local Ganache RPC
npm run rpc

# Deploy compiled contracts to local Ganache RPC
npm run migrate:development

# Start web UI
npm run watch

Now, you should have the smart contract running on local Ganache RPC, and have a web UI running on http://localhost:8080

You can start your Chrome browser and navigate to http://localhost:8080 and you should be able to interact with the smart contract.

Remember to choose the network in DEXON Wallet. You should be pointing to http://localhost:8545, which is your local Ganache RPC.

Run Smart Contract on DEXON testnet

# Deploy compiled contracts to DEXON testnet
npm run migrate:testnet

# Start web UI
npm run watch

Now, you should have the smart contract running on DEXON testnet, and, the same as before, have a web UI running on http://localhost:8080

You can start your Chrome browser and navigate to http://localhost:8080 and you should be able to interact with the smart contract.

The difference is that now the contract is running on public network and everyone else in the world can also see your contract on DEXON testnet!

Solidity

What is Solidity?

Solidity is an object-oriented, high-level language for implementing smart contracts. Smart contracts are programs which govern the behaviour of accounts within the Ethereum state.

Solidity was influenced by C++, Python and JavaScript and is designed to target the Ethereum Virtual Machine (EVM).

Solidity is statically typed, supports inheritance, libraries and complex user-defined types among other features.

With Solidity you can create contracts for uses such as voting, crowdfunding, blind auctions, and multi-signature wallets.

When deploying contracts, you should use the latest released version of Solidity. This is because breaking changes as well as new features and bug fixes are introduced regularly. We currently use a 0.x version number to indicate this fast pace of change.

Sample Solidity Contract

Here's a simple Solidity smart contract,

pragma solidity ^0.5.0;

contract Hello {
    uint256 public value;

    event UpdateNumber(uint256 _value);

    function update() public {
        value = rand;
        emit UpdateNumber(value);
    }

    function get() public view returns (uint256) {
        return value;
    }
}

There are two methods available for interaction in this contract: update and get.

  • When update is called, an on-chain random seed is read from rand and stored into the contract variable value.
  • When get is called, the value is read from the contract storage and returned to the caller.

You can find the complete Github repository HERE.

Language Documentation

For more information, check out the full language documentation of Solidity

Remix IDE

Remix is a browser-based compiler and IDE that enables users to build Ethereum contracts with Solidity language and to debug transactions.

To try it out, visit https://remix.dexon.org.

https://github.com/dexon-foundation/remix-ide/releases also gives others ways to use Remix locally. Please check it out.

Documentation

To see details about how to use Remix for developing and/or debugging Solidity contracts, please see this documentation pages. The document pages covers instructions on how to use Remix IDE to develop, deploy, test, debug smart contracts and some tutorials and examples to help you get started.

On chain randomness

One of the most interesting features of DEXON is that it has an on-chain random oracle. An “on-chain” random oracle means that the random source is retrieved directly on the chain itself, instead of having to feed it in by external sources.

Remix IDE also supports this feature You can use the rand keyword in Remix IDE.

Sample code:

pragma solidity ^0.5.0;
contract Rand {
    uint256 value;
    function update() public {
        value = rand;
    }
    function get() view public returns (uint256) {
        return value;
    }
}

Interact with Contracts

WIP

from Web

WIP

from Mobile App

WIP

Migrate from Ethereum

DEXON's version of EVM is almost the same as the original EVM, therefore DEXON version of Solidity is almost the same as the original Solidity. If you have built a smart contract on Ethereum, you can usually deploy the exact same contract onto DEXON without any modification.

However, there are still some minor differences between the DEXON's version of Solidity and its Ethereum counterpart to look out for, as listed below:

Timestamp

The granularity of time is increased in DEXON's version of EVM. Due to the improved performance of DEXON, we may have multiple blocks produced in the same second.

Therefore, in DEXON, we use milliseconds instead of seconds for timestamp. For example

pragma solidity ^0.5.2;

contract Time {

    function getNow() public view returns (uint256)
    {
        return now;
    }
}

calling getNow() of the contract returns a time in milliseconds in DEXON, while in Ethereum, a time in seconds is returned.

Also, the time constants in DEXON's Solidity is also change accordingly (dsolidity >0.5.3).

  • 1 second yields 1000
  • 1 minute yields 60000
  • 1 hour yields 3600000
  • 1 day yields 86400000
  • 1 week yeilds 604800000
  • 1 year yields 31536000000

Gas Limit

In DEXON, there is no unspent gas.

If the actual execution of a transaction costs less gas than the set amount, you still have to pay for the gas amount you've set. So please set the gas amount wisely.

The reason for this is that in DEXON, transaction are not executed at the time they get packed into a block. So the number of transactions that can get into a block depends on the gas amount set in the transactions, not the actual gas amount consumed while executing the transactions.

On-Chain Random Oracle

This is more of an additional feature than Ethereum's EVM.

DEXON provides On-chain Random Oracle. This means you can get unbiased random seeds in your smart contract easily and at low cost.

Here's a simple Solidity smart contract that utilizes DEXON's on-chain randomness,

pragma solidity ^0.5.2;

contract Hello {
    uint256 public value;

    event UpdateNumber(uint256 _value);

    function update() public {
        value = rand;
        emit UpdateNumber(value);
    }

    function get() public view returns (uint256) {
        return value;
    }
}

The rand keyword used in the contract gives you the random seed generated from the threshold signature of a group of block producing nodes.

Tools and Libraries

Here's a list of tools and libraries for developing DApps on DEXON blockchain platform.

Blockchain Explorer

  • DEXONSCAN
    Official blockchain explorer and web wallet for DEXON. You can also check network status and interact with smart contracts in DEXONSCAN.

Development Tools

  • DEXON Remix
    Web-based IDE for developing, compiling, deploying and testing smart contracts.

  • DEXON Truffle
    Toolkit for developing Solidity smart contracts on DEXON, including compiler, contract deployer, test suite and a lot more.

  • DEXON Ganache
    JavaScript mock of DEXON blockchain, for developing and testing smart contracts without actually connecting to a blockchain.

  • sol-tools
    Toolkit for compiling, testing and profiling smart contracts.

  • dsolidity
    Solidity compiler written in C++, supporting additional DEXON-specific opcodes like on-chain random oracle.

  • dsolc-js
    JavaScript bindings for DEXON's dsolidity compiler.

Libraries

  • web3.js
    JavaScript library for accessing DEXON network from browser and Node.js.

  • Mobile SDK
    Native mobile library for accessing DEXON network from iOS or Android apps.

DEXONSCAN

Official blockchain explorer and web wallet for DEXON. You can also check network status and interact with smart contracts in DEXONSCAN.

Usage

Go directly to DEXONSCAN websites and start exploring DEXON networks.

Features

View Network Status

DEXONSCAN provides a comprehensive chart and a series of stats for you to get a grasp of the current network status easily.

View Governance Status

You can check the network governance status on DEXONSCAN, including network configurations like block time, minimum staking amount, round length and currently active block producing nodes.

View Blocks, Addresses and Transactions

Just like every other blockchain explorers, you can check the details of blocks, addresses and transactions on DEXONSCAN.

Wallet

DEXONSCAN provides wallet UI, with connectability to Chrome/Firefox wallet extension, Ledger and TREZOR. You can manage your assets on DEXON easily and securely with DEXONSCAN.

Smart Contract Interactions

Smart contract developers can verify their contract source code on DEXONSCAN. Once it's verified, users can see the contract source code and interact with it on DEXONSCAN UI.

DEXON Remix

Web-based IDE for developing, compiling, deploying and testing smart contracts.

Usage

You can either use our hosted version or download from npm

# Install from npm
> npm install @dexon-foundation/remix-ide -g

# run local DEXON-remix IDE
> dremix-ide

Check out our step-by-step guide for DEXON Remix IDE here

Github

https://github.com/dexon-foundation/remix-ide

Features

  • Smart Contract Editor
    Remix IDE provides a fully functioned solidity code editor.

  • Smart Contract Compiler
    You can compile your smart contract directly from the UI.

  • Contract Deployer Deploy compiled bytecode onto DEXON networks or JavaScript mock network.

  • Debugger
    Test run and add breakpoints to your smart contract source code.

dexon-truffle

Toolkit for developing Solidity smart contracts on DEXON, including compiler, contract deployer, test suite and a lot more.

Usage

# Install from npm
> npm install @dexon-foundation/truffle -g

# run command-line tools
> dexon-truffle init|compile|migrate|test

Github

https://github.com/dexon-foundation/truffle

dexon-ganache

JavaScript mock of DEXON blockchain, for developing and testing smart contracts without actually connecting to a blockchain.

Usage

# Install from npm
> npm install @dexon-foundation/ganache-cli -g

# run local Ganache
> dexon-ganache-cli

Github

https://github.com/dexon-foundation/ganache-cli

https://github.com/dexon-foundation/ganache-core

sol-tools

Toolkit for compiling, testing and profiling smart contracts. Originally developed by 0x team.

Usage

# Install from npm
> npm install @dexon-foundation/sol-compiler -g
> npm install @dexon-foundation/sol-coverage -g
> npm install @dexon-foundation/sol-profiler -g
> npm install @dexon-foundation/sol-trace -g

# run command-line tools
> dsol-compiler
> dsol-coverage
> dsol-profiler
> dsol-trace

Github

https://github.com/dexon-foundation/sol-tools

dsolidity

Solidity compiler written in C++, supporting additional DEXON-specific opcodes like on-chain random oracle.

Usage

Instructions about how to build and install the Solidity compiler can be found in the Solidity documentation

Github

https://github.com/dexon-foundation/dsolidity

dsolc-js

JavaScript bindings for DEXON's dsolidity compiler.

Usage

# Install from npm
> npm install @dexon-foundation/dsolc -g

# run command-line tools
> dsolcjs --help

Github

https://github.com/dexon-foundation/dsolc-js

web3.js

JavaScript library for accessing DEXON network from browser and Node.js.

Usage

# Install from npm
> npm install web3 --save

Get more information for web3.js here

Github

https://github.com/ethereum/web3.js/

Mobile SDK

API

JSON-RPC API

Contents

JSON RPC API

JSON is a lightweight data-interchange format. It can represent numbers, strings, ordered sequences of values, and collections of name/value pairs.

JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol. Primarily this specification defines several data structures and the rules around their processing. It is transport agnostic in that the concepts can be used within the same process, over sockets, over HTTP, or in many various message passing environments. It uses JSON (RFC 4627) as data format.

Geth 1.4 has experimental pub/sub support. See this page for more information.

JavaScript API

To talk to an dexon node from inside a JavaScript application use the web3.js library, which gives a convenient interface for the RPC methods. See the JavaScript API for more. Extend API will support in the future.

JSON-RPC Endpoint

Default JSON-RPC endpoints:

Client URL
Go http://localhost:8545

Go

You can start the HTTP JSON-RPC with the --rpc flag

gdex --rpc

change the default port (8545) and listing address (localhost) with:

gdex --rpc --rpcaddr <ip> --rpcport <portnumber>

If accessing the RPC from a browser, CORS will need to be enabled with the appropriate domain set. Otherwise, JavaScript calls are limit by the same-origin policy and requests will fail:

gdex --rpc --rpccorsdomain "http://localhost:3000"

The JSON RPC can also be started from the gdex console using the admin.startRPC(addr, port) command.

HEX value encoding

At present there are two key datatypes that are passed over JSON: unformatted byte arrays and quantities. Both are passed with a hex encoding, however with different requirements to formatting:

When encoding QUANTITIES (integers, numbers): encode as hex, prefix with "0x", the most compact representation (slight exception: zero should be represented as "0x0"). Examples:

  • 0x41 (65 in decimal)
  • 0x400 (1024 in decimal)
  • WRONG: 0x (should always have at least one digit - zero is "0x0")
  • WRONG: 0x0400 (no leading zeroes allowed)
  • WRONG: ff (must be prefixed 0x)

When encoding UNFORMATTED DATA (byte arrays, account addresses, hashes, bytecode arrays): encode as hex, prefix with "0x", two hex digits per byte. Examples:

  • 0x41 (size 1, "A")
  • 0x004200 (size 3, "\0B\0")
  • 0x (size 0, "")
  • WRONG: 0xf0f0f (must be even number of digits)
  • WRONG: 004200 (must be prefixed 0x)

The default block parameter

The following methods have an extra default block parameter:

When requests are made that act on the state of dexon, the last default block parameter determines the height of the block.

The following options are possible for the defaultBlock parameter:

  • HEX String - an integer block number
  • String "earliest" for the earliest/genesis block
  • String "latest" - for the latest mined block
  • String "pending" - for the pending state/transactions

Curl Examples Explained

The curl options below might return a response where the node complains about the content type, this is because the --data option sets the content type to application/x-www-form-urlencoded . If your node does complain, manually set the header by placing -H "Content-Type: application/json" at the start of the call.

The examples also do not include the URL/IP & port combination which must be the last argument given to curl e.x. 127.0.0.1:8545

JSON-RPC methods

JSON RPC API Reference


web3_clientVersion

Returns the current client version.

Parameters

none

Returns

String - The current client version.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":67}'

// Result
{
  "id":67,
  "jsonrpc":"2.0",
  "result": "Mist/v0.9.3/darwin/go1.4.1"
}

web3_sha3

Returns Keccak-256 (not the standardized SHA3-256) of the given data.

Parameters
  1. DATA - the data to convert into a SHA3 hash.
Example Parameters
params: [
  "0x68656c6c6f20776f726c64"
]
Returns

DATA - The SHA3 result of the given string.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"web3_sha3","params":["0x68656c6c6f20776f726c64"],"id":64}'

// Result
{
  "id":64,
  "jsonrpc": "2.0",
  "result": "0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad"
}

net_version

Returns the current network id.

Parameters

none

Returns

String - The current network id.

  • "237": Dexon Mainnet
  • "238": Dexon Testnet
  • "239": Taipei Testnet
  • "240": Yilan Testnet
Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"net_version","params":[],"id":67}'

// Result
{
  "id":67,
  "jsonrpc": "2.0",
  "result": "3"
}

net_listening

Returns true if client is actively listening for network connections.

Parameters

none

Returns

Boolean - true when listening, otherwise false.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"net_listening","params":[],"id":67}'

// Result
{
  "id":67,
  "jsonrpc":"2.0",
  "result":true
}

net_peerCount

Returns number of peers currently connected to the client.

Parameters

none

Returns

QUANTITY - integer of the number of connected peers.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":74}'

// Result
{
  "id":74,
  "jsonrpc": "2.0",
  "result": "0x2" // 2
}

eth_protocolVersion

Returns the current dexon protocol version.

Parameters

none

Returns

String - The current dexon protocol version.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_protocolVersion","params":[],"id":67}'

// Result
{
  "id":67,
  "jsonrpc": "2.0",
  "result": "0x40"
}

eth_syncing

Returns an object with data about the sync status or false.

Parameters

none

Returns

Object|Boolean, An object with sync status data or FALSE, when not syncing:

  • startingBlock: QUANTITY - The block at which the import started (will only be reset, after the sync reached his head)
  • currentBlock: QUANTITY - The current block, same as eth_blockNumber
  • highestBlock: QUANTITY - The estimated highest block
Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": {
    startingBlock: '0x384',
    currentBlock: '0x386',
    highestBlock: '0x454'
  }
}
// Or when not syncing
{
  "id":1,
  "jsonrpc": "2.0",
  "result": false
}

eth_gasPrice

Returns the current price per gas in wei.

Parameters

none

Returns

QUANTITY - integer of the current gas price in dal.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":73}'

// Result
{
  "id":73,
  "jsonrpc": "2.0",
  "result": "0x09184e72a000" // 10000000000000
}

eth_accounts

Returns a list of addresses owned by client.

Parameters

none

Returns

Array of DATA, 20 Bytes - addresses owned by the client.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": ["0xc94770007dda54cF92009BFF0dE90c06F603a09f"]
}

eth_blockNumber

Returns the number of most recent block.

Parameters

none

Returns

QUANTITY - integer of the current block number the client is on.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

// Result
{
  "id":83,
  "jsonrpc": "2.0",
  "result": "0xc94" // 1207
}

eth_getBalance

Returns the balance of the account of given address.

Parameters
  1. DATA, 20 Bytes - address to check for balance.
  2. QUANTITY|TAG - integer block number, or the string "latest", "earliest" or "pending", see the default block parameter
Example Parameters
params: [
   '0xc94770007dda54cF92009BFF0dE90c06F603a09f',
   'latest'
]
Returns

QUANTITY - integer of the current balance in dal.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0xc94770007dda54cF92009BFF0dE90c06F603a09f", "latest"],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0x0234c8a3397aab58" // 158972490234375000
}

eth_getStorageAt

Returns the value from a storage position at a given address.

Parameters
  1. DATA, 20 Bytes - address of the storage.
  2. QUANTITY - integer of the position in the storage.
  3. QUANTITY|TAG - integer block number, or the string "latest", "earliest" or "pending", see the default block parameter
Returns

DATA - the value at this storage position.

Example

Calculating the correct position depends on the storage to retrieve. Consider the following contract deployed at 0x295a70b2de5e3953354a6a8344e616ed314d7251 by address 0x391694e7e0b0cce554cb130d723a9d27458f9298.

contract Storage {
    uint pos0;
    mapping(address => uint) pos1;
    
    function Storage() {
        pos0 = 1234;
        pos1[msg.sender] = 5678;
    }
}

Retrieving the value of pos0 is straight forward:

curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0", "latest"], "id": 1}' localhost:8545

{"jsonrpc":"2.0","id":1,"result":"0x00000000000000000000000000000000000000000000000000000000000004d2"}

Retrieving an element of the map is harder. The position of an element in the map is calculated with:

keccack(LeftPad32(key, 0), LeftPad32(map position, 0))

This means to retrieve the storage on pos1["0x391694e7e0b0cce554cb130d723a9d27458f9298"] we need to calculate the position with:

keccak(decodeHex("000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001"))

The geth console which comes with the web3 library can be used to make the calculation:

> var key = "000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001"
undefined
> web3.sha3(key, {"encoding": "hex"})
"0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9"

Now to fetch the storage:

curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9", "latest"], "id": 1}' localhost:8545

{"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000000000000000000000000162e"}


eth_getTransactionCount

Returns the number of transactions sent from an address.

Parameters
  1. DATA, 20 Bytes - address.
  2. QUANTITY|TAG - integer block number, or the string "latest", "earliest" or "pending", see the default block parameter
Example Parameters
params: [
   '0xc94770007dda54cF92009BFF0dE90c06F603a09f',
   'latest' // state at the latest block
]
Returns

QUANTITY - integer of the number of transactions send from this address.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0xc94770007dda54cF92009BFF0dE90c06F603a09f","latest"],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0x1" // 1
}

eth_getBlockTransactionCountByHash

Returns the number of transactions in a block from a block matching the given block hash.

Parameters
  1. DATA, 32 Bytes - hash of a block.
Example Parameters
params: [
   '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238'
]
Returns

QUANTITY - integer of the number of transactions in this block.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByHash","params":["0xc94770007dda54cF92009BFF0dE90c06F603a09f"],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0xc" // 11
}

eth_getBlockTransactionCountByNumber

Returns the number of transactions in a block matching the given block number.

Parameters
  1. QUANTITY|TAG - integer of a block number, or the string "earliest", "latest" or "pending", as in the default block parameter.
Example Parameters
params: [
   '0xe8', // 232
]
Returns

QUANTITY - integer of the number of transactions in this block.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByNumber","params":["0xe8"],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0xa" // 10
}

eth_getCode

Returns code at a given address.

Parameters
  1. DATA, 20 Bytes - address.
  2. QUANTITY|TAG - integer block number, or the string "latest", "earliest" or "pending", see the default block parameter.
Example Parameters
params: [
   '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b',
   '0x2'  // 2
]
Returns

DATA - the code from the given address.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getCode","params":["0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x2"],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056"
}

eth_sign

The sign method calculates an Dexon specific signature with: sign(keccak256("\x19Dexon Signed Message:\n" + len(message) + message))).

By adding a prefix to the message makes the calculated signature recognisable as an Dexon specific signature. This prevents misuse where a malicious DApp can sign arbitrary data (e.g. transaction) and use the signature to impersonate the victim.

Note the address to sign with must be unlocked.

Parameters

account, message

  1. DATA, 20 Bytes - address.
  2. DATA, N Bytes - message to sign.
Returns

DATA: Signature

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sign","params":["0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", "0xdeadbeaf"],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0xa3f20717a250c2b0b729b7e5becbff67fdaef7e0699da4de7ca5895b02a170a12d887fd3b17bfdce3481f10bea41f45ba9f709d39ce8325427b57afcfc994cee1b"
}

eth_sendTransaction

Creates new message call transaction or a contract creation, if the data field contains code.

Parameters
  1. Object - The transaction object
  • from: DATA, 20 Bytes - The address the transaction is send from.
  • to: DATA, 20 Bytes - (optional when creating new contract) The address the transaction is directed to.
  • gas: QUANTITY - (optional, default: 90000) Integer of the gas provided for the transaction execution. It will return unused gas.
  • gasPrice: QUANTITY - (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas
  • value: QUANTITY - (optional) Integer of the value sent with this transaction
  • data: DATA - The compiled code of a contract OR the hash of the invoked method signature and encoded parameters. For details see Dexon Contract ABI
  • nonce: QUANTITY - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.
Example Parameters
params: [{
  "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
  "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
  "gas": "0x76c0", // 30400
  "gasPrice": "0x9184e72a000", // 10000000000000
  "value": "0x9184e72a", // 2441406250
  "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
}]
Returns

DATA, 32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available.

Use eth_getTransactionReceipt to get the contract address, after the transaction was mined, when you created a contract.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{see above}],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
}

eth_sendRawTransaction

Creates new message call transaction or a contract creation for signed transactions.

Parameters
  1. DATA, The signed transaction data.
Example Parameters
params: ["0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"]
Returns

DATA, 32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available.

Use eth_getTransactionReceipt to get the contract address, after the transaction was mined, when you created a contract.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":[{see above}],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
}

eth_call

Executes a new message call immediately without creating a transaction on the block chain.

Parameters
  1. Object - The transaction call object
  • from: DATA, 20 Bytes - (optional) The address the transaction is sent from.
  • to: DATA, 20 Bytes - The address the transaction is directed to.
  • gas: QUANTITY - (optional) Integer of the gas provided for the transaction execution. eth_call consumes zero gas, but this parameter may be needed by some executions.
  • gasPrice: QUANTITY - (optional) Integer of the gasPrice used for each paid gas
  • value: QUANTITY - (optional) Integer of the value sent with this transaction
  • data: DATA - (optional) Hash of the method signature and encoded parameters. For details see Ethereum Contract ABI
  1. QUANTITY|TAG - integer block number, or the string "latest", "earliest" or "pending", see the default block parameter
Returns

DATA - the return value of executed contract.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_call","params":[{see above}],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0x"
}

eth_estimateGas

Generates and returns an estimate of how much gas is necessary to allow the transaction to complete. The transaction will not be added to the blockchain. Note that the estimate may be significantly more than the amount of gas actually used by the transaction, for a variety of reasons including EVM mechanics and node performance.

Parameters

See eth_call parameters, expect that all properties are optional. If no gas limit is specified geth uses the block gas limit from the pending block as an upper bound. As a result the returned estimate might not be enough to executed the call/transaction when the amount of gas is higher than the pending block gas limit.

Returns

QUANTITY - the amount of gas used.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_estimateGas","params":[{see above}],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0x5208" // 21000
}

eth_getBlockByHash

Returns information about a block by hash.

Parameters
  1. DATA, 32 Bytes - Hash of a block.
  2. Boolean - If true it returns the full transaction objects, if false only the hashes of the transactions.
Example Parameters
params: [
   '0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331',
   true
]
Returns

Object - A block object, or null when no block was found:

  • number: QUANTITY - the block number. null when its pending block.
  • hash: DATA, 32 Bytes - hash of the block. null when its pending block.
  • parentHash: DATA, 32 Bytes - hash of the parent block.
  • nonce: DATA, 8 Bytes - hash of the generated proof-of-work. null when its pending block.
  • sha3Uncles: DATA, 32 Bytes - SHA3 of the uncles data in the block.
  • logsBloom: DATA, 256 Bytes - the bloom filter for the logs of the block. null when its pending block.
  • transactionsRoot: DATA, 32 Bytes - the root of the transaction trie of the block.
  • stateRoot: DATA, 32 Bytes - the root of the final state trie of the block.
  • receiptsRoot: DATA, 32 Bytes - the root of the receipts trie of the block.
  • miner: DATA, 20 Bytes - the address of the beneficiary to whom the mining rewards were given.
  • difficulty: QUANTITY - integer of the difficulty for this block.
  • totalDifficulty: QUANTITY - integer of the total difficulty of the chain until this block.
  • extraData: DATA - the "extra data" field of this block.
  • size: QUANTITY - integer the size of this block in bytes.
  • gasLimit: QUANTITY - the maximum gas allowed in this block.
  • gasUsed: QUANTITY - the total used gas by all transactions in this block.
  • timestamp: QUANTITY - the unix timestamp for when the block was collated.
  • transactions: Array - Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter.
  • uncles: Array - Array of uncle hashes.
Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByHash","params":["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true],"id":1}'

// Result
{
"id":1,
"jsonrpc":"2.0",
"result": {
    "number": "0x1b4", // 436
    "hash": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331",
    "parentHash": "0x9646252be9520f6e71339a8df9c55e4d7619deeb018d2a3f2d21fc165dde5eb5",
    "nonce": "0xe04d296d2460cfb8472af2c5fd05b5a214109c25688d3704aed5484f9a7792f2",
    "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
    "logsBloom": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331",
    "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
    "stateRoot": "0xd5855eb08b3387c0af375e9cdb6acfc05eb8f519e419b874b6ff2ffda7ed1dff",
    "miner": "0x4e65fda2159562a496f9f3522f89122a3088497a",
    "difficulty": "0x027f07", // 163591
    "totalDifficulty":  "0x027f07", // 163591
    "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "size":  "0x027f07", // 163591
    "gasLimit": "0x9f759", // 653145
    "gasUsed": "0x9f759", // 653145
    "timestamp": "0x54e34e8e" // 1424182926
    "transactions": [{...},{ ... }] 
    "uncles": ["0x1606e5...", "0xd5145a9..."]
  }
}

eth_getBlockByNumber

Returns information about a block by block number.

Parameters
  1. QUANTITY|TAG - integer of a block number, or the string "earliest", "latest" or "pending", as in the default block parameter.
  2. Boolean - If true it returns the full transaction objects, if false only the hashes of the transactions.
Example Parameters
params: [
   '0x1b4', // 436
   true
]
Returns

See eth_getBlockByHash

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1b4", true],"id":1}'

Result see eth_getBlockByHash


eth_getTransactionByHash

Returns the information about a transaction requested by transaction hash.

Parameters
  1. DATA, 32 Bytes - hash of a transaction
Example Parameters
params: [
   "0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"
]
Returns

Object - A transaction object, or null when no transaction was found:

  • blockHash: DATA, 32 Bytes - hash of the block where this transaction was in. null when its pending.
  • blockNumber: QUANTITY - block number where this transaction was in. null when its pending.
  • from: DATA, 20 Bytes - address of the sender.
  • gas: QUANTITY - gas provided by the sender.
  • gasPrice: QUANTITY - gas price provided by the sender in Wei.
  • hash: DATA, 32 Bytes - hash of the transaction.
  • input: DATA - the data send along with the transaction.
  • nonce: QUANTITY - the number of transactions made by the sender prior to this one.
  • to: DATA, 20 Bytes - address of the receiver. null when its a contract creation transaction.
  • transactionIndex: QUANTITY - integer of the transaction's index position in the block. null when its pending.
  • value: QUANTITY - value transferred in Wei.
  • v: QUANTITY - ECDSA recovery id
  • r: DATA, 32 Bytes - ECDSA signature r
  • s: DATA, 32 Bytes - ECDSA signature s
Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"],"id":1}'

// Result
{
  "jsonrpc":"2.0",
  "id":1,
  "result":{
    "blockHash":"0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2",
    "blockNumber":"0x5daf3b", // 6139707
    "from":"0xa7d9ddbe1f17865597fbd27ec712455208b6b76d",
    "gas":"0xc350", // 50000
    "gasPrice":"0x4a817c800", // 20000000000
    "hash":"0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b",
    "input":"0x68656c6c6f21",
    "nonce":"0x15", // 21
    "to":"0xf02c1c8e6114b1dbe8937a39260b5b0a374432bb",
    "transactionIndex":"0x41", // 65
    "value":"0xf3dbb76162000", // 4290000000000000
    "v":"0x25", // 37
    "r":"0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea",
    "s":"0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c"
  }
}

eth_getTransactionByBlockHashAndIndex

Returns information about a transaction by block hash and transaction index position.

Parameters
  1. DATA, 32 Bytes - hash of a block.
  2. QUANTITY - integer of the transaction index position.
Example Parameters
params: [
   '0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331',
   '0x0' // 0
]
Returns

See eth_getTransactionByHash

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockHashAndIndex","params":["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", "0x0"],"id":1}'

Result see eth_getTransactionByHash


eth_getTransactionByBlockNumberAndIndex

Returns information about a transaction by block number and transaction index position.

Parameters
  1. QUANTITY|TAG - a block number, or the string "earliest", "latest" or "pending", as in the default block parameter.
  2. QUANTITY - the transaction index position.
Example Parameters
params: [
   '0x29c', // 668
   '0x0' // 0
]
Returns

See eth_getTransactionByHash

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockNumberAndIndex","params":["0x29c", "0x0"],"id":1}'

Result see eth_getTransactionByHash


eth_getTransactionReceipt

Returns the receipt of a transaction by transaction hash.

Note That the receipt is not available for pending transactions.

Parameters
  1. DATA, 32 Bytes - hash of a transaction
Example Parameters
params: [
   '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238'
]
Returns

Object - A transaction receipt object, or null when no receipt was found:

  • transactionHash: DATA, 32 Bytes - hash of the transaction.
  • transactionIndex: QUANTITY - integer of the transaction's index position in the block.
  • blockHash: DATA, 32 Bytes - hash of the block where this transaction was in.
  • blockNumber: QUANTITY - block number where this transaction was in.
  • from: DATA, 20 Bytes - address of the sender.
  • to: DATA, 20 Bytes - address of the receiver. null when it's a contract creation transaction.
  • cumulativeGasUsed: QUANTITY - The total amount of gas used when this transaction was executed in the block.
  • gasUsed: QUANTITY - The amount of gas used by this specific transaction alone.
  • contractAddress: DATA, 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise null.
  • logs: Array - Array of log objects, which this transaction generated.
  • logsBloom: DATA, 256 Bytes - Bloom filter for light clients to quickly retrieve related logs.

It also returns either :

  • root : DATA 32 bytes of post-transaction stateroot (pre Byzantium)
  • status: QUANTITY either 1 (success) or 0 (failure)
Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id":1}'

// Result
{
"id":1,
"jsonrpc":"2.0",
"result": {
     transactionHash: '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238',
     transactionIndex:  '0x1', // 1
     blockNumber: '0xb', // 11
     blockHash: '0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b',
     cumulativeGasUsed: '0x33bc', // 13244
     gasUsed: '0x4dc', // 1244
     contractAddress: '0xb60e8dd61c5d32be8058bb8eb970870f07233155', // or null, if none was created
     logs: [{
         // logs as returned by getFilterLogs, etc.
     }, ...],
     logsBloom: "0x00...0", // 256 byte bloom filter
     status: '0x1'
  }
}

eth_pendingTransactions

Returns the pending transactions list.

Parameters

none

Returns

Array - A list of pending transactions.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_pendingTransactions","params":[],"id":1}'

// Result
{
"id":1,
"jsonrpc":"2.0",
"result": [{ 
    blockHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
    blockNumber: null,
    from: '0x28bdb9c230f4d5e45435e4d006326ee32e46cb31',
    gas: '0x204734',
    gasPrice: '0x4a817c800',
    hash: '0x8dfa6a59307a490d672494a171feee09db511f05e9c097e098edc2881f9ca4f6',
    input: '0x6080604052600',
    nonce: '0x12',
    to: null,
    transactionIndex: '0x0',
    value: '0x0',
    v: '0x3d',
    r: '0xaabc9ddafffb2ae0bac4107697547d22d9383667d9e97f5409dd6881ce08f13f',
    s: '0x69e43116be8f842dcd4a0b2f760043737a59534430b762317db21d9ac8c5034' 
   },....,{ 
    blockHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
    blockNumber: null,
    from: '0x28bdb9c230f4d5e45435e4d006326ee32e487b31',
    gas: '0x205940',
    gasPrice: '0x4a817c800',
    hash: '0x8e4340ea3983d86e4b6c44249362f716ec9e09849ef9b6e3321140581d2e4dac',
    input: '0xe4b6c4424936',
    nonce: '0x14',
    to: null,
    transactionIndex: '0x0',
    value: '0x0',
    v: '0x3d',
    r: '0x1ec191ef20b0e9628c4397665977cbe7a53a263c04f6f185132b77fa0fd5ca44',
    s: '0x8a58e00c63e05cfeae4f1cf19f05ce82079dc4d5857e2cc281b7797d58b5faf' 
   }]
}

eth_newFilter

Creates a filter object, based on filter options, to notify when the state changes (logs). To check if the state has changed, call eth_getFilterChanges.

A note on specifying topic filters:

Topics are order-dependent. A transaction with a log with topics [A, B] will be matched by the following topic filters:

  • [] "anything"
  • [A] "A in first position (and anything after)"
  • [null, B] "anything in first position AND B in second position (and anything after)"
  • [A, B] "A in first position AND B in second position (and anything after)"
  • [[A, B], [A, B]] "(A OR B) in first position AND (A OR B) in second position (and anything after)"
Parameters
  1. Object - The filter options:
  • fromBlock: QUANTITY|TAG - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
  • toBlock: QUANTITY|TAG - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
  • address: DATA|Array, 20 Bytes - (optional) Contract address or a list of addresses from which logs should originate.
  • topics: Array of DATA, - (optional) Array of 32 Bytes DATA topics. Topics are order-dependent. Each topic can also be an array of DATA with "or" options.
Example Parameters
params: [{
  "fromBlock": "0x1",
  "toBlock": "0x2",
  "address": "0x8888f1f195afa192cfee860698584c030f4c9db1",
  "topics": ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", null, ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x0000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc"]]
}]
Returns

QUANTITY - A filter id.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newFilter","params":[{"topics":["0x0000000000000000000000000000000000000000000000000000000012341234"]}],"id":73}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0x1" // 1
}

eth_newBlockFilter

Creates a filter in the node, to notify when a new block arrives. To check if the state has changed, call eth_getFilterChanges.

Parameters

None

Returns

QUANTITY - A filter id.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newBlockFilter","params":[],"id":73}'

// Result
{
  "id":1,
  "jsonrpc":  "2.0",
  "result": "0x1" // 1
}

eth_newPendingTransactionFilter

Creates a filter in the node, to notify when new pending transactions arrive. To check if the state has changed, call eth_getFilterChanges.

Parameters

None

Returns

QUANTITY - A filter id.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newPendingTransactionFilter","params":[],"id":73}'

// Result
{
  "id":1,
  "jsonrpc":  "2.0",
  "result": "0x1" // 1
}

eth_uninstallFilter

Uninstalls a filter with given id. Should always be called when watch is no longer needed. Additonally Filters timeout when they aren't requested with eth_getFilterChanges for a period of time.

Parameters
  1. QUANTITY - The filter id.
Example Parameters
params: [
  "0xb" // 11
]
Returns

Boolean - true if the filter was successfully uninstalled, otherwise false.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_uninstallFilter","params":["0xb"],"id":73}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": true
}

eth_getFilterChanges

Polling method for a filter, which returns an array of logs which occurred since last poll.

Parameters
  1. QUANTITY - the filter id.
Example Parameters
params: [
  "0x16" // 22
]
Returns

Array - Array of log objects, or an empty array if nothing has changed since last poll.

  • For filters created with eth_newBlockFilter the return are block hashes (DATA, 32 Bytes), e.g. ["0x3454645634534..."].

  • For filters created with eth_newPendingTransactionFilter the return are transaction hashes (DATA, 32 Bytes), e.g. ["0x6345343454645..."].

  • For filters created with eth_newFilter logs are objects with following params:

    • removed: TAG - true when the log was removed, due to a chain reorganization. false if its a valid log.
    • logIndex: QUANTITY - integer of the log index position in the block. null when its pending log.
    • transactionIndex: QUANTITY - integer of the transactions index position log was created from. null when its pending log.
    • transactionHash: DATA, 32 Bytes - hash of the transactions this log was created from. null when its pending log.
    • blockHash: DATA, 32 Bytes - hash of the block where this log was in. null when its pending. null when its pending log.
    • blockNumber: QUANTITY - the block number where this log was in. null when its pending. null when its pending log.
    • address: DATA, 20 Bytes - address from which this log originated.
    • data: DATA - contains the non-indexed arguments of the log.
    • topics: Array of DATA - Array of 0 to 4 32 Bytes DATA of indexed log arguments. (In solidity: The first topic is the hash of the signature of the event (e.g. Deposit(address,bytes32,uint256)), except you declared the event with the anonymous specifier.)
Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0x16"],"id":73}'

// Result
{
  "id":1,
  "jsonrpc":"2.0",
  "result": [{
    "logIndex": "0x1", // 1
    "blockNumber":"0x1b4", // 436
    "blockHash": "0x8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d",
    "transactionHash":  "0xdf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf",
    "transactionIndex": "0x0", // 0
    "address": "0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d",
    "data":"0x0000000000000000000000000000000000000000000000000000000000000000",
    "topics": ["0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5"]
    },{
      ...
    }]
}

eth_getFilterLogs

Returns an array of all logs matching filter with given id.

Parameters
  1. QUANTITY - The filter id.
Example Parameters
params: [
  "0x16" // 22
]
Returns

See eth_getFilterChanges

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterLogs","params":["0x16"],"id":74}'

Result see eth_getFilterChanges


eth_getLogs

Returns an array of all logs matching a given filter object.

Parameters
  1. Object - The filter options:
  • fromBlock: QUANTITY|TAG - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
  • toBlock: QUANTITY|TAG - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
  • address: DATA|Array, 20 Bytes - (optional) Contract address or a list of addresses from which logs should originate.
  • topics: Array of DATA, - (optional) Array of 32 Bytes DATA topics. Topics are order-dependent. Each topic can also be an array of DATA with "or" options.
  • blockhash: DATA, 32 Bytes - (optional) With the addition of EIP-234 (Geth >= v1.8.13 or Parity >= v2.1.0), blockHash is a new filter option which restricts the logs returned to the single block with the 32-byte hash blockHash. Using blockHash is equivalent to fromBlock = toBlock = the block number with hash blockHash. If blockHash is present in the filter criteria, then neither fromBlock nor toBlock are allowed.
Example Parameters
params: [{
  "topics": ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]
}]
Returns

See eth_getFilterChanges

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":74}'

Result see eth_getFilterChanges


db_putString

Stores a string in the local database.

Note this function is deprecated and will be removed in the future.

Parameters
  1. String - Database name.
  2. String - Key name.
  3. String - String to store.
Example Parameters
params: [
  "testDB",
  "myKey",
  "myString"
]
Returns

Boolean - returns true if the value was stored, otherwise false.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"db_putString","params":["testDB","myKey","myString"],"id":73}'

// Result
{
  "id":1,
  "jsonrpc":"2.0",
  "result": true
}

db_getString

Returns string from the local database.

Note this function is deprecated and will be removed in the future.

Parameters
  1. String - Database name.
  2. String - Key name.
Example Parameters
params: [
  "testDB",
  "myKey",
]
Returns

String - The previously stored string.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"db_getString","params":["testDB","myKey"],"id":73}'

// Result
{
  "id":1,
  "jsonrpc":"2.0",
  "result": "myString"
}

db_putHex

Stores binary data in the local database.

Note this function is deprecated and will be removed in the future.

Parameters
  1. String - Database name.
  2. String - Key name.
  3. DATA - The data to store.
Example Parameters
params: [
  "testDB",
  "myKey",
  "0x68656c6c6f20776f726c64"
]
Returns

Boolean - returns true if the value was stored, otherwise false.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"db_putHex","params":["testDB","myKey","0x68656c6c6f20776f726c64"],"id":73}'

// Result
{
  "id":1,
  "jsonrpc":"2.0",
  "result": true
}

db_getHex

Returns binary data from the local database.

Note this function is deprecated and will be removed in the future.

Parameters
  1. String - Database name.
  2. String - Key name.
Example Parameters
params: [
  "testDB",
  "myKey",
]
Returns

DATA - The previously stored data.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"db_getHex","params":["testDB","myKey"],"id":73}'

// Result
{
  "id":1,
  "jsonrpc":"2.0",
  "result": "0x68656c6c6f20776f726c64"
}

shh_version

Returns the current whisper protocol version.

Parameters

none

Returns

String - The current whisper protocol version

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"shh_version","params":[],"id":67}'

// Result
{
  "id":67,
  "jsonrpc": "2.0",
  "result": "2"
}

shh_post

Sends a whisper message.

Parameters
  1. Object - The whisper post object:
  • from: DATA, 60 Bytes - (optional) The identity of the sender.
  • to: DATA, 60 Bytes - (optional) The identity of the receiver. When present whisper will encrypt the message so that only the receiver can decrypt it.
  • topics: Array of DATA - Array of DATA topics, for the receiver to identify messages.
  • payload: DATA - The payload of the message.
  • priority: QUANTITY - The integer of the priority in a range from ... (?).
  • ttl: QUANTITY - integer of the time to live in seconds.
Example Parameters
params: [{
  from: "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1",
  to: "0x3e245533f97284d442460f2998cd41858798ddf04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a0d4d661997d3940272b717b1",
  topics: ["0x776869737065722d636861742d636c69656e74", "0x4d5a695276454c39425154466b61693532"],
  payload: "0x7b2274797065223a226d6",
  priority: "0x64",
  ttl: "0x64",
}]
Returns

Boolean - returns true if the message was send, otherwise false.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"shh_post","params":[{"from":"0xc931d93e97ab07fe42d923478ba2465f2..","topics": ["0x68656c6c6f20776f726c64"],"payload":"0x68656c6c6f20776f726c64","ttl":0x64,"priority":0x64}],"id":73}'

// Result
{
  "id":1,
  "jsonrpc":"2.0",
  "result": true
}

shh_newIdentity

Creates new whisper identity in the client.

Parameters

none

Returns

DATA, 60 Bytes - the address of the new identiy.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"shh_newIdentity","params":[],"id":73}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0xc931d93e97ab07fe42d923478ba2465f283f440fd6cabea4dd7a2c807108f651b7135d1d6ca9007d5b68aa497e4619ac10aa3b27726e1863c1fd9b570d99bbaf"
}

shh_hasIdentity

Checks if the client hold the private keys for a given identity.

Parameters
  1. DATA, 60 Bytes - The identity address to check.
Example Parameters
params: [  "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1"
]
Returns

Boolean - returns true if the client holds the privatekey for that identity, otherwise false.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"shh_hasIdentity","params":["0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1"],"id":73}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": true
}

shh_newGroup

Creates a new group.

Parameters

none

Returns

DATA, 60 Bytes - the address of the new group.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"shh_newGroup","params":[],"id":73}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0xc65f283f440fd6cabea4dd7a2c807108f651b7135d1d6ca90931d93e97ab07fe42d923478ba2407d5b68aa497e4619ac10aa3b27726e1863c1fd9b570d99bbaf"
}

shh_addToGroup

Adds a whisper identity to the group.

Parameters
  1. DATA, 60 Bytes - The identity address to add to a group.
Example Parameters
params: [ "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1"
]
Returns

Boolean - returns true if the identity was successfully added to the group, otherwise false.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"shh_addToGroup","params":["0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1"],"id":73}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": true
}

shh_newFilter

Creates filter to notify, when client receives whisper message matching the filter options.

Parameters
  1. Object - The filter options:
  • to: DATA, 60 Bytes - (optional) Identity of the receiver. When present it will try to decrypt any incoming message if the client holds the private key to this identity.
  • topics: Array of DATA - Array of DATA topics which the incoming message's topics should match. You can use the following combinations:
    • [A, B] = A && B
    • [A, [B, C]] = A && (B || C)
    • [null, A, B] = ANYTHING && A && B null works as a wildcard
Example Parameters
params: [{
   "topics": ['0x12341234bf4b564f'],
   "to": "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1"
}]
Returns

QUANTITY - The newly created filter.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"shh_newFilter","params":[{"topics": ['0x12341234bf4b564f'],"to": "0x2341234bf4b2341234bf4b564f..."}],"id":73}'

// Result
{
  "id":1,
  "jsonrpc":"2.0",
  "result": "0x7" // 7
}

shh_uninstallFilter

Uninstalls a filter with given id. Should always be called when watch is no longer needed. Additonally Filters timeout when they aren't requested with shh_getFilterChanges for a period of time.

Parameters
  1. QUANTITY - The filter id.
Example Parameters
params: [
  "0x7" // 7
]
Returns

Boolean - true if the filter was successfully uninstalled, otherwise false.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"shh_uninstallFilter","params":["0x7"],"id":73}'

// Result
{
  "id":1,
  "jsonrpc":"2.0",
  "result": true
}

shh_getFilterChanges

Polling method for whisper filters. Returns new messages since the last call of this method.

Note calling the shh_getMessages method, will reset the buffer for this method, so that you won't receive duplicate messages.

Parameters
  1. QUANTITY - The filter id.
Example Parameters
params: [
  "0x7" // 7
]
Returns

Array - Array of messages received since last poll:

  • hash: DATA, 32 Bytes (?) - The hash of the message.
  • from: DATA, 60 Bytes - The sender of the message, if a sender was specified.
  • to: DATA, 60 Bytes - The receiver of the message, if a receiver was specified.
  • expiry: QUANTITY - Integer of the time in seconds when this message should expire (?).
  • ttl: QUANTITY - Integer of the time the message should float in the system in seconds (?).
  • sent: QUANTITY - Integer of the unix timestamp when the message was sent.
  • topics: Array of DATA - Array of DATA topics the message contained.
  • payload: DATA - The payload of the message.
  • workProved: QUANTITY - Integer of the work this message required before it was send (?).
Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"shh_getFilterChanges","params":["0x7"],"id":73}'

// Result
{
  "id":1,
  "jsonrpc":"2.0",
  "result": [{
    "hash": "0x33eb2da77bf3527e28f8bf493650b1879b08c4f2a362beae4ba2f71bafcd91f9",
    "from": "0x3ec052fc33..",
    "to": "0x87gdf76g8d7fgdfg...",
    "expiry": "0x54caa50a", // 1422566666
    "sent": "0x54ca9ea2", // 1422565026
    "ttl": "0x64", // 100
    "topics": ["0x6578616d"],
    "payload": "0x7b2274797065223a226d657373616765222c2263686...",
    "workProved": "0x0"
    }]
}

shh_getMessages

Get all messages matching a filter. Unlike shh_getFilterChanges this returns all messages.

Parameters
  1. QUANTITY - The filter id.
Example Parameters
params: [
  "0x7" // 7
]
Returns

See shh_getFilterChanges

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"shh_getMessages","params":["0x7"],"id":73}'

Result see shh_getFilterChanges

Extend JSON-RPC methods

Extend JSON RPC API Reference

eth_sendRawTransactions

Batch creation with new message call transaction or a contract creation for signed transactions.

Parameters
  1. Array, Array of signed transaction data.
Example Parameters
params: [[
"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675",
"0x8eb970870f0724456758bb8eb970870f072445675058bbe8dd67c5d32be8d46e8dd67c5d32d46be805",
]]
Returns

Array, 32 Bytes - Array of available transaction hash.

Use eth_getTransactionReceipt to get the contract address, after the transaction was mined, when you created a contract.

Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendRawTransactions","params":[{see above}],"id":1}'

// Result
{
  "id":1,
  "jsonrpc": "2.0",
  "result": ["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"]
}

eth_getBlockReceiptsByHash

Returns all transaction receipts of a block by block hash.

Parameters
  1. DATA, 32 Bytes - hash of a block
Example Parameters
params: [
   '0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331'
]
Returns

Array - Array of transaction receipt object:

  • Object
    • transactionHash: DATA, 32 Bytes - hash of the transaction.
    • transactionIndex: QUANTITY - integer of the transaction's index position in the block.
    • blockHash: DATA, 32 Bytes - hash of the block where this transaction was in.
    • blockNumber: QUANTITY - block number where this transaction was in.
    • from: DATA, 20 Bytes - address of the sender.
    • to: DATA, 20 Bytes - address of the receiver. null when it's a contract creation transaction.
    • cumulativeGasUsed: QUANTITY - The total amount of gas used when this transaction was executed in the block.
    • gasUsed: QUANTITY - The amount of gas used by this specific transaction alone.
    • contractAddress: DATA, 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise null.
    • logs: Array - Array of log objects, which this transaction generated.
    • logsBloom: DATA, 256 Bytes - Bloom filter for light clients to quickly retrieve related logs.
  • It also returns either :
    • root : DATA 32 bytes of post-transaction stateroot (pre Byzantium)
    • status: QUANTITY either 1 (success) or 0 (failure)
Example
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id":1}'

// Result
{
"id":1,
"jsonrpc":"2.0",
"result": [
    {
       transactionHash: '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238',
       transactionIndex:  '0x1', // 1
       blockNumber: '0xb', // 11
       blockHash: '0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b',
       cumulativeGasUsed: '0x33bc', // 13244
       gasUsed: '0x4dc', // 1244
       contractAddress: '0xb60e8dd61c5d32be8058bb8eb970870f07233155', // or null, if none was created
       logs: [{
           // logs as returned by getFilterLogs, etc.
       }, ...],
       logsBloom: "0x00...0", // 256 byte bloom filter
       status: '0x1'
    },
  ]
}

Introduction

DEXON fullnode supports pub/sub using subscriptions as defined in the JSON-RPC 2.0 specification. This allows clients to wait for events instead of polling for them.

It works by subscribing to particular events. The node will return a subscription id. For each event that matches the subscription a notification with relevant data is send together with the subscription id.

Example:

// create subscription
>> {"id": 1, "method": "eth_subscribe", "params": ["newHeads", {}]}
<< {"jsonrpc":"2.0","id":1,"result":"0xcd0c3e8af590364c09d0fa6a1210faf5"}

// incoming notifications
<< {"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0xcd0c3e8af590364c09d0fa6a1210faf5","result":{"difficulty":"0xd9263f42a87",<...>, "uncles":[]}}}
<< {"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0xcd0c3e8af590364c09d0fa6a1210faf5","result":{"difficulty":"0xd90b1a7ad02", <...>, "uncles":["0x80aacd1ea4c9da32efd8c2cc9ab38f8f70578fcd46a1a4ed73f82f3e0957f936"]}}}

// cancel subscription
>> {"id": 1, "method": "eth_unsubscribe", "params": ["0xcd0c3e8af590364c09d0fa6a1210faf5"]}
<< {"jsonrpc":"2.0","id":1,"result":true}

Considerations

  1. notifications are send for current events and not for past events. If your use case requires you not to miss any notifications than subscriptions are probably not the best option.
  2. subscriptions require a full duplex connection. Geth offers such connections in the form of websockets (enable with --ws) and ipc (enabled by default).
  3. subscriptions are coupled to a connection. If the connection is closed all subscriptions that are created over this connection are removed.
  4. notifications are stored in an internal buffer and sent from this buffer to the client. If the client is unable to keep up and the number of buffered notifications reaches a limit (currently 10k) the connection is closed. Keep in mind that subscribing to some events can cause a flood of notifications, e.g. listening for all logs/blocks when the node starts to synchronize.

Create subscription

Subscriptions are creates with a regular RPC call with eth_subscribe as method and the subscription name as first parameter. If successful it returns the subscription id.

Parameters

  1. subscription name
  2. optional arguments

Example

>> {"id": 1, "method": "eth_subscribe", "params": ["newHeads", {"includeTransactions": true}]}
<< {"id": 1, "jsonrpc": "2.0", "result": "0x9cef478923ff08bf67fde6c64013158d"}

Cancel subscription

Subscriptions are cancelled with a regular RPC call with eth_unsubscribe as method and the subscription id as first parameter. It returns a bool indicating if the subscription was cancelled successful.

Parameters

  1. subscription id

Example

>> {"id": 1, "method": "eth_unsubscribe", "params": ["0x9cef478923ff08bf67fde6c64013158d"]}
<< {"jsonrpc":"2.0","id":1,"result":true}

Supported subscriptions

newHeads

Fires a notification each time a new header is appended to the chain, including chain reorganizations. Users can use the bloom filter to determine if the block contains logs that are interested to them.

In case of a chain reorganization the subscription will emit all new headers for the new chain. Therefore the subscription can emit multiple headers on the same height.

Example

    >> {"id": 1, "method": "eth_subscribe", "params": ["newHeads"]}
    << {"jsonrpc":"2.0","id":2,"result":"0x9ce59a13059e417087c02d3236a0b1cc"}

    << {
  "jsonrpc": "2.0",
  "method": "eth_subscription",
  "params": {
    "result": {
      "difficulty": "0x15d9223a23aa",
      "extraData": "0xd983010305844765746887676f312e342e328777696e646f7773",
      "gasLimit": "0x47e7c4",
      "gasUsed": "0x38658",
      "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069",
      "nonce": "0x084149998194cc5f",
      "number": "0x1348c9",
      "parentHash": "0x7736fab79e05dc611604d22470dadad26f56fe494421b5b333de816ce1f25701",
      "receiptRoot": "0x2fab35823ad00c7bb388595cb46652fe7886e00660a01e867824d3dceb1c8d36",
      "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
      "stateRoot": "0xb3346685172db67de536d8765c43c31009d0eb3bd9c501c9be3229203f15f378",
      "timestamp": "0x56ffeff8",
      "transactionsRoot": "0x0167ffa60e3ebc0b080cdb95f7c0087dd6c0e61413140e39d94d3468d7c9689f"
    },
    "subscription": "0x9ce59a13059e417087c02d3236a0b1cc"
  }
}

logs

Returns logs that are included in new imported blocks and match the given filter criteria.

In case of a chain reorganization previous sent logs that are on the old chain will be resend with the removed property set to true. Logs from transactions that ended up in the new chain are emitted. Therefore a subscription can emit logs for the same transaction multiple times.

Parameters

  1. object with the following (optional) fields
    • address, either an address or an array of addresses. Only logs that are created from these addresses are returned (optional)
    • topics, only logs which match the specified topics (optional)

Example

>> {"id": 1, "method": "eth_subscribe", "params": ["logs", {"address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", "topics": ["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]}]}
<< {"jsonrpc":"2.0","id":2,"result":"0x4a8a4c0517381924f9838102c5a4dcb7"}

<< {"jsonrpc":"2.0","method":"eth_subscription","params": {"subscription":"0x4a8a4c0517381924f9838102c5a4dcb7","result":{"address":"0x8320fe7702b96808f7bbc0d4a888ed1468216cfd","blockHash":"0x61cdb2a09ab99abf791d474f20c2ea89bf8de2923a2d42bb49944c8c993cbf04","blockNumber":"0x29e87","data":"0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003","logIndex":"0x0","topics":["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"],"transactionHash":"0xe044554a0a55067caafd07f8020ab9f2af60bdfe337e395ecd84b4877a3d1ab4","transactionIndex":"0x0"}}}

newPendingTransactions

Returns the hash for all transactions that are added to the pending state and are signed with a key that is available in the node.

When a transaction that was previously part of the canonical chain isn't part of the new canonical chain after a reogranization its again emitted.

Parameters

none

Example

>> {"id": 1, "method": "eth_subscribe", "params": ["newPendingTransactions"]}
<< {"jsonrpc":"2.0","id":2,"result":"0xc3b33aa549fb9a60e95d21862596617c"}

<< {
        "jsonrpc":"2.0",
        "method":"eth_subscription",
        "params":{
            "subscription":"0xc3b33aa549fb9a60e95d21862596617c",
            "result":"0xd6fdc5cc41a9959e922f30cb772a9aef46f4daea279307bc5f7024edc4ccd7fa"
        }
    }

syncing

Indicates when the node starts or stops synchronizing. The result can either be a boolean indicating that the synchronization has started (true), finished (false) or an object with various progress indicators.

Parameters

none

Example

>> {"id": 1, "method": "eth_subscribe", "params": ["syncing"]}
<< {"jsonrpc":"2.0","id":2,"result":"0xe2ffeb2703bcf602d42922385829ce96"}

<< {"subscription":"0xe2ffeb2703bcf602d42922385829ce96","result":{"syncing":true,"status":{"startingBlock":674427,"currentBlock":67400,"highestBlock":674432,"pulledStates":0,"knownStates":0}}}}

Possible future subscription:

  • balance changes
  • account changes
  • nonce changes
  • storage changes in contracts

Node Operator Guide

Run DEXON

Instructions to run a DEXON block proposer node.

Generate Node Key

A node key is required to operate a BP node. Run the following command to generate a node key:

docker run -v $PWD:/mnt -it dexonfoundation/dexon-tools nodekey generate /mnt/node.key

This show output content similar to the following

Node Address: 0x93aA8C9C77De627E665F0b4015B7271B9Be89E83
Public Key: 0x046272a157cbffa00677be00b08c9d47f295539b07e53360754579ad5e933a638ba58dcf850484e7d40b8bc163a920082b2500ee54968db7155c6231c7e4eed592

A file node.key can be found under current working directory. node.key is very important as it contains the node private key. Please save this file securely.

Register your node

  1. Send some DXN to your node key address, 100 DXN should suffice. These DXN are required for the node to send transaction and interact with the consensus protocol. You need to replenish them if it ran out.
  2. Goto the Governance contract page on DEXSCAN.
  3. Navigate to the Write tab and select register from the dropdown menu.
  4. Fill in the information like below, currently, you need 1M DXN to run a BP node. If you don't have enough testnet DXN, ask @wnhuang (telegram) for it.

Register in Governance Contract Page

  1. Hit send to register your node.

After this, your node should be staked.

Note that after staked, the configuration will start to take effect after 2 rounds (2400 blocks).

Start the BP node

Use the following command to start the BP node:

docker run -v $PWD:/mnt -it dexonfoundation/dexon:testnet \
    --testnet \
    --bp \
    --nodekey=/mnt/node.key \
    --datadir=/mnt/datadir \
    --syncmode=fast \
    --cache=1024 \
    --gcmode=archive

Please make sure you have enough disk space in the current working directory.

Content

Objective

The document will contain essential instructions and knowledge for a node operator to successfully run a DEXON BP node.

Background

For node operator to easily establish a DEXON BP node and continuously run the node for mining rewards, DEXON foundation provides the well-designed software supporting the mining mechanism on DEXON blockchain.

Overview

The guide has 3 sections, providing the required knowledge for a node operator to: Set up node, run software, and collect mining rewards.

Environment Setup

How to set up AWS/GCP server?

For AWS, please follow https://docs.aws.amazon.com/quickstarts/latest/vmlaunch/welcome.html

For GCP, please follow https://cloud.google.com/compute/docs/quickstart-linux

System Requirement

Running DEXON BP node has the following requirement:

Hardware Requirement

Tier CPU Memory Bandwidth Estimated Cost
Minimum 4 Cores 2.0+ GHz 8 GB 200Mbps 200~400 USD/mth
Recommend 8 Cores 2.0+ GHz 16 GB 200Mbps 600~800 USD/mth

Software requirement

  • OS: Linux 64 bit.
  • Docker image: dexonfoundation/dexon
  • Docker
  • Go compiler
  • C++ compiler
  • Library: gmp, openssl, pkg-config

Follow the appropriate link below to find installation instructions for your platform.

Software Instruction

Generate Node Key

A node key is required to operate a BP node. Run the following command to generate a node key:

docker run -v $PWD:/mnt -it dexonfoundation/dexon-tools \
    nodekey generate /mnt/node.key

This show output content similar to the following

Node Address: 0x93aA8C9C77De627E665F0b4015B7271B9Be89E83
Public Key:0x046272a157cbffa00677be00b08c9d47f295539b07e53360754579ad5e933a638ba58dcf850484e7d40b8bc163a920082b2500ee54968db7155c6231c7e4eed592

Please store the address and public key which will be used to register a fullnode. A file node.key can be found under the current working directory. node.key is very important as it contains the node private key. Please save this file securely.

Register your node

  1. Sync DEXON blockchain. Use the following command to download all the blocks in DEXON blockchain.
docker run --restart always -v $PWD:/mnt -it dexonfoundation/dexon:latest \
        --bp \
        --nodekey=/mnt/node.key \
        --datadir=/mnt/datadir \
        --syncmode=fast\
        --cache=1024 \
        --gcmode=archive

When you see commit pivot, press control + c.

  1. Send some DXN to your node key address, 500 DXN should suffice. These DXN are required for the node to send transaction and interact with the consensus protocol. You need to replenish them if it ran out.

  2. Send 5 ETH (Ethereum mainnet Ether) to your node key address. This is a very important step. Since DEXON relies on Ethereum mainnet to recover itself in case there is a catastrophic network failure. There are penalties if a BP node failed to propose recovery vote due to insufficient Ether in their node key address, see Rules for node set for more details.

  3. Goto the Governance contract page on DEXONSCAN.

  4. Navigate to the Write tab and select register from the dropdown menu.

  5. Fill in the information like below; currently, you need 1M DXN to run a BP node. If you don't have enough testnet DXN, ask @wnhuang (telegram) for it.

  • Node Public Key (the public key generated above and should not duplicate)
  • Name of the node (maximum length: 32 bytes)
  • Contact email (maximum length: 32 bytes)
  • Node Location (maximum length: 32 bytes)
  • Website URL (maximum length: 128 bytes)

Register in Governance Contract Page The user whose stake is locked (bought DXN coin in private-sale), please contact DEXON Foundation and provide the information below.

  1. Hit send to register your node.

After this, you are successfully staked and the configuration will start to take effect after 2 epochs (2400 blocks).

Note that, the account of node.key and the account to send DXN coin to governance contract are not necessary to be the same. We strongly suggest using different keys to manage the risk.

Start the BP node

Use the following command to start the BP node:

docker run --restart always -v $PWD:/mnt -it dexonfoundation/dexon:latest \
    --bp \
    --nodekey=/mnt/node.key \
    --datadir=/mnt/datadir \
    --syncmode=full \
    --cache=1024 \
    --gcmode=archive

Please make sure you have enough disk space in the current working directory

For more detail instruction about gdex, go to https://github.com/dexon-foundation/dexon or use

docker run -v $PWD:/mnt -it dexonfoundation/dexon --help

Mining Mechanism

DEXON Mining Economy and Mining Rewards

Please read this document, https://github.com/dexon-foundation/wiki/wiki/DEXON-Cryptoeconomics

As an example, initially, each node can expectedly mine 1M * 18.75% = 187.5K DXN coin per year (before total minted tokens hit 1.5B DXN).

Running a RPC node

Content

Overview

A RPC node is the data access layer of blockchains. It usually won't join the mining process but only try to sync the latest confirmed state from other nodes. With those datum in hands, a RPC node can provide these functionalities:

  • Pack and send transactions
  • Allow other services (like wallet or explorer) to access states on blockchains in standard way, like jsonrpc.

System Requirement

Refer to System requirement section in BP node operation guide.

Software Instruction

Different from running a BP node, you don't have to

  • create a node key
  • register your node

The command line to start a RPC node is different, too:

docker run -v $PWD:/mnt -it dexonfoundation/dexon \
        --datadir=/mnt/datadir \
        --syncmode=fast \
        --rpc \
        --rpcapi=eth,net,web3 \
        --rpcaddr=0.0.0.0 \
        --rpcvhosts=* \
        --rpccorsdomain=* \
        --ws \
        --wsapi=eth,net,web3 \
        --wsaddr=0.0.0.0 \
        --wsorigins=* \
        --cache=1024 \
        --gcmode=archive \
        --metrics \
        --pprof \
        --pprofaddr=0.0.0.0

You should be able to see these logs, which simply means your RPC node tries to sync blocks from other peers and it would take a while. If not, make sure tcp/30303 and udp/30303 is not blocked by the firewall.

...
INFO [04-18|12:23:33.783] Imported new state entries  ...
INFO [04-18|12:23:35.647] Imported new state entries  ...
INFO [04-18|12:23:37.714] Imported new block receipts ...
INFO [04-18|12:23:38.471] Imported new block receipts ...
...

To make sure your RPC node is ready for usage, you can try to get the count of blocks it received via this command:

curl -X POST \
     -H "Content-Type: application/json" \
     --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
     http://localhost:8545

You should be able to see something similar in return (0xd482e is the hex form of 870062):

{"jsonrpc":"2.0","id":1,"result":"0xd482e"}

RPC Node for Testnet

It simply to launch a RPC node for testnet by adding network flag --testnet:

docker run -v $PWD:/mnt -it dexonfoundation/dexon \
        --testnet \
        --datadir=/mnt/datadir \
        --syncmode=fast \
        --rpc \
        --rpcapi=eth,net,web3 \
        --rpcaddr=0.0.0.0 \
        --rpcvhosts=* \
        --rpccorsdomain=* \
        --ws \
        --wsapi=eth,net,web3 \
        --wsaddr=0.0.0.0 \
        --wsorigins=* \
        --cache=1024 \
        --gcmode=archive \
        --metrics \
        --pprof \
        --pprofaddr=0.0.0.0

Rule for the DEXON node set

We introduce the rule for node set and give a brief explanation to the functions in DEXON governance contract.

Active condition (permission to be in notary set)

You must deposit enough stake in the governance contract to get the qualification to be selected in the notary set. Sometimes nodes who violate the rule for notary set will be fined some coin. This leads nodes unqualified to be selected in the notary set. Nodes can be re-qualify after paying the fine.

Reward

The reward of each block is calculated as

block_Reward = mining_Velocity * total_Staked * round_Interval / (365*24*60*60)

For example, 100 nodes with each staked 1M DXN and mining velocity is 18.75%, the reward of each block is

100 * 1M * 18.75% * 1 / (365*24*60*60) = 0.5945586 DXN

You can find the parameter information via governance statistic page.

From the description above, the expected reward for each node in 1 day is

100 * 1M * 18.75% * 1 / 365 /100 = 513.7 DXN

Penalty

Nodes shall not engage in any of the following conducts:

  1. Forking or trying to fork blocks at the same height by proposing multiple blocks
  2. Forking or trying to fork votes by submitting multiple votes in the same iteration in the Byzantine Agreement (BA)
  3. Engaging in malicious behaviors in Distributed Key Generation, including without limitation sending wrong secret shares to other nodes, and such behaviors have been complained by other nodes
  4. Producing wrong Share-Sig by sending wrong share signature to common reference string (CRS) or in commit-vote
  5. Failing to finish distributed key generation (DKG)
  6. Failing to propose any blocks during a whole epoch

For 1. to 4., the entire stake will be confiscated immediately by DEXON Foundation. For 5., a fine of the 1 DXN will be imposed and no blocks can be produced until such fine is paid under the governance contract. For 6., a fine of the 100 DXN will be imposed and no blocks can be produced until such fine is paid under the governance contract.

Nodes can pay the fine in the governance contract, see payFine.

Recovery

Currently, DEXON's recovery is built on top of the Ethereum mainnet. All nodes are required to deposit at least 5 Ether to the same node address. Ether used for recovery will be returned after DEXON successfully recovered. However, if DEXON failed to recover and result in a hard fork, the stakes of nodes that did not deposit enough amount of Ether will be confiscated.

Content

Contract Write function

In this section, we briefly introduce some functions that DEXON governance provides to write in.

Register

  1. In DekuSan wallet, switch to the owner's account.
  2. Navigate to the Write tab of the governance contract and select register from the dropdown menu.
  3. Fill in the information like below; currently, you need 1M DXN to run a BP node.
  • Node Public Key (you must hold the corresponding secret key)
  • Name of the node
  • Contact email
  • Node Location
  • Website URL
  1. Click Send and confirm in DekuSan wallet.

Pay Fine

  1. In DekuSan wallet, switch to the account to pay the fine (it doesn't has to be the owner of that node)
  2. Navigate to the Write tab of the governance contract and selectpayFine` from the dropdown menu.
  3. Fill in the amount of fine to pay, and the address of that node.
  4. Click Send and confirm in DekuSan wallet.

NOTE: Don't worry to over pay the fine, the transaction would succeed when the amount you pay matches the fine of that node.

Stake/Unstake

After registering, each node owner can continue depositing more stake into DEXON governance contract. This is super easy to achieve in DEXON governance contract.

  1. Switch to the owner account in DekuSan wallet.
  2. Navigate to the Write tab and select stake from the dropdown menu.
  3. Fill the amount of stake in the contract.
  4. Click Send and confirm in DekuSan wallet.

On the other hand, each node owner can also unstake from DEXON governance contract. This is almost identical to operating stake function.

  1. Switch to the owner account in DekuSan wallet.
  2. Navigate to the Write tab and select unstake from the dropdown menu.
  3. Fill the amount of unstake in the contract.
  4. Click Send and confirm in DekuSan wallet.

To ensure the stability of DEXON blockchain, the duration to withdraw the unstake coin is set 24 epochs, which corresponds around 1 day in real-world time. In the duration, the node can still propose block and earn the reward, but the node sill can be fined if violating any rule. Note that, each node can only unstake once until the unstake is withdrawn.

Withdraw

After unstaking and wait for 24 epochs, the node can withdraw the stake.

  1. Switch to the owner account in DekuSan wallet.
  2. Navigate to the Write tab and select withdraw from the dropdown menu.
  3. Click Send and confirm in DekuSan wallet.

Transfer Node Owner

A node owner can also transfer the owner right to others.

  1. Switch to the owner account in DekuSan wallet.
  2. Navigate to the Write tab and select TransferNodeOwnership from the dropdown menu.
  3. Fill the address of the new owner.
  4. Click Send and confirm in DekuSan wallet.

WARNING: This is an IRREDUCIBLE operation. No one can recover if you transfer to a wrong address. Please double-check the address is correct.

Contract Read function

The latest system parameters can be found in the governance contract. We introduce some fruquently used functions.

nodes

nodes returns the status of a node, where the input is the order of the node. The order of a node can be query by the function nodesOffsetByAddress.

nodeLength

nodeLength returns the current size of the node set.

nodesOffsetByAddress

nodesOffsetByAddress returns the order of a node, where the input is the address of the node.

minStake

minStake returns the minimum stake required to join the node set.

Fullnode Development Guide

Contribute to DEXON Fullnode

Thank you for considering to help out with the source code! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes!

If you'd like to contribute to dexon, please fork, fix, commit and send a pull request for the maintainers to review and merge into the main code base. If you wish to submit more complex changes though, please check up with the core devs first on our gitter channel to ensure those changes are in line with the general philosophy of the project and/or get some early feedback which can make both your efforts much lighter as well as our review and merge procedures quick and simple.

Please make sure your contributions adhere to our coding guidelines:

  • Code must adhere to the official Go formatting guidelines (i.e. uses gofmt).
  • Code must be documented adhering to the official Go commentary guidelines.
  • Pull requests need to be based on and opened against the dev branch.
  • Commit messages should be prefixed with the package(s) they modify.
    • E.g. "eth, rpc: make trace configs optional"

Please see the Developers' Guide for more details on configuring your environment, managing project dependencies and testing procedures.

List of Repositories

  • dexon-consensus: the consensus SDK and simulation.
  • dexon: the DEXON fullnode implementation, based on go-ethereum.
  • governance-abi: the DEXON governance contract interface solidity implementation for generating ABI.
  • dekusan: Chrome wallet extension based on MetaMask.
  • dsolidity: DEXON fork of the solidity compiler, includes extra features supported by DEXON's modification of EVM.
  • DIPs: a place for DEXON Improvement Proposals
  • hello-dexon: a simple DEXON smart contract, demonstrating the on-chain unbiased random oracle
  • dexon-remix-ide: DEXON fork of Remix, a solidity IDE that runs on any modern browsers
  • dexon-truffle: DEXON fork of Truffle, a solidity contract development toolkit.
  • dexon-ganache-cli: DEXON for of Ganache, a mocking Ethereum blockchain implemented in JavaScript. Used for developing and testing smart contracts.

Technical Documentations

Consensus Algorithm V2 Specification

  • ConfigRoundShift: Rounds required for new config to be effective.
  • DKGDelayRound: Ths first round that starts running DKG.

Selection of the notary set size

As mention in our consensus algorithm, we follow the hypergeometric distribution to decide the size of notary set.

Given a node set of size N, the ratio R of Byzantine nodes, and the notary set of size n, then, the probability that more than 1/3 of notary set is Byzantine nodes is

We set the probability to be 10^-8; that is, there is less than one fault during 10000 years in expectation (notary set is re-selected every hour). Assume R=1/5. We can derive the proper size of the notary set according to the equation and the result is shown in the following figure.

Alt text

For convenience, we give two curves to approximate the data points. The first one is y = 70.5 ln(x) - 264, which is the purple dash line and the second one is y = 74 ln(x) - 264, which is the green dash line. The following table is the resilience ratio to the Byzantine given the size of notary set and probability 10^-8.

node set size notary set size resilience notary set size resilience
200 110 0.199 123 0.220
400 159 0.197 174 0.207
600 187 0.194 203 0.202
800 208 0.197 224 0.202
1000 223 0.197 252 0.202
1500 252 0.199 270 0.204
2000 272 0.199 291 0.207
4000 321 0.207 342 0.209

DEXON mainnet will use y = 70.5 ln(x) - 264 to decide the size of the notary set under different sizes of the node set.

DEXON DKG-TSIG Protocol

Parameter

  • λ = MAX(One gossip duraion, transaction confirm latency)
  • Signature = BLS
  • Curve = BLS12_381
  • n = size of notary_set
  • t =

Notes

  • Complaints and nack complaints are stored in governance contract; therefore, the broadcast is reliable.
  • Governance contract will do the sanity check for complaints and nack complaints before adding to its state.
  • Once a validator proposed DKGFinal_i, it can no longer propose any complaint.
  • After DKG finished, if successful qualify nodes size is less than of notary set size, DKG will be rerun with different set of nodes.

Phase 1 ID Registration

@ T < 0

Each validator registers its ID(DKGMasterPublicKey_i) with stake.

After λ

Each validator i broadcasts a DKGMasterPublicKeyReady_i message.

Validator waits until seeing more than 2t+1 DKGGroupPublicKeyReady message than proceeds to Phase 2.

Phase 2 Secret Key Share Exchange

@ T = 0

Each validator i generates n (n = # of ID registered in phase 1) secret key shares (SK_i,0, SK_i,1, ..., SK_i,n) of order t and the secret key share is sent to the corresponding validator (SK_i,j is sent to validator j) via a secure channel.

Each validator i broadcasts the master public key (MPK_i = {MPK_i,0, MPK_i,1, ..., MPK_i,t}) of order t associated with the secret key shares.

Phase 3 Complaint

@ T = (0, λ)

Each validator i calculates public key shares (PK_0,i, PK_1,i, ..., PK_n,i) using corresponding master public key (PK_j,i = F(MPK_j, i)).

Each validator i verifies if the secret key share SK_j,i is associated with the public key share of validator j, PK_j,i. If the verification fails, i broadcast complaint of j, CMP_i,j.

Phase 4 Nack Complaint

@ T = λ

If validator i did not receive SK_j,i, broadcast nack complaint of j, NCMP_i,j.

Phase 5 Anti Nack Complaint

@ T = 2λ

If validator j sees NCMP_i,j for any i, broadcast secret key share SK_j,i.

Phase 6 Rebroadcast Secret

@ T = 3λ

If validator k receive SK_j,i for the first time for i != k, broadcast it again.

Phase 7 Enforce Complaint

@ T = 4λ

If validator k sees SK_j,i for i != k, verifies if the secret key share SK_j,i is associated with the public key share of validator j, PK_j,i. If the verification fails, k broadcast complaint of j, CMP_k,j.

If validator k sees NCMP_i,j for j != k and did not receive SK_j,i, k broadcast nack complaint of j, NCMP_k,j.

Phase 8 DKG Finalize

@ T = 5λ

Each validator i broadcast a DKGFinal_i message.

Phase 9 Sign with CSK

@ T = 6λ

Validator waits until seeing more than 2t+1 final message.

If there are more than t nack complaints to validator j ( (i : for all validator i)), then j is marked as Disqualified.

If there is one complaint, CMP_i,j, to validator j, then j is marked as Disqualified.

Each validator i determines the combined secret key, (k: validator k is not marked as Disqualified)

If a validator i successfully recovered combined secret key, it will broadcast a DKGSuccess_i message.

Each validator i sign the message with CSK_i and broadcast the partial signature, PSign_i.

Each validator i determines the combined public key of validator j, (k: validator k is not marked as Disqualified)

Phase 10 TSIG

@ T = (6λ, +inf)

If validator i is not Disqualified, verify PSign_i with CPK_i.

Collect more than t valid PSign_i and recover TSIG, TSIG.

Phase 11 Verify TSIG

Determines the group public key, (k: validator k is not marked as Disqualified)

Verify TSIG with GPK.

Most blockchains do not have a random source since they are not able to generate an on-chain random number that can not be predicted beforehand. DEXON solves this problem by using threshold signature with BLS scheme. Since this final threshold signature is only known after they are being gathered together, one can not predict the signature before sending the transaction that would be included in the given block.

If you look at the block result using the RPC:

{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
        "dexconMeta": "...",
        "extraData": "0x",
        "gasLimit": "0x7a1200",
        "gasUsed": "0x238f8",
        "hash": "0x78ba157ae54a4784e1f0edbdac2b14e1f38f519d34d3d3164d75016ac90e8227",
        "logsBloom": "...",
        "miner": "0xb6a2e270b54f19b4002d6535a71cfdd1ca1f5fc1",
        "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "nonce": "0x0000000000000000",
        "number": "0x100",
        "parentHash": "0x8da90bea16f9a6edf022030766950636caad7fbd0ef296e7d34da052d0fa4ca7",
        "randomness": "0x895736dfafa3ce4e0f051fac7cc218cb092b67e88b7c25f4cf90e496e91c7d10e55a251e0ff6e655fdc8d866b85fe30c",
        "receiptsRoot": "0xc627d0acef6f0592ffd775e05b4f6b36dce8065a217bf4c9fec0c538b8b46b7d",
        "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
        "size": "0x67b",
        "stateRoot": "0xb728e453a70d2c6d5f9a00857aa697740c16770a696dd8a6594876c2b6f85a84",
        "timestamp": "0x5bcf0935",
        "totalDifficulty": "0x20100",
        "transactions": [
          ...
        ],
        "transactionsRoot": "0x1b1e6b2a70de752b563fbeedb0461dca4af0c56e8dd3147b7a7ea3b2a701f6e6",
        "uncles": []
    }
}

You can see there is a randomness field which standard Ethereum RPC does not have. This randomness field is actually the threshold signature of the block signed by the DKG set.

The DEXON blockchain exposes this randomness source in Solidity with the rand variable, which when accessed, generates a deterministic random number. 'deterministic' means that all nodes will generate the same random number when running the EVM using the block randomness source. The rand variable compiles to a new opcode RAND (0x2f) we added into EVM. The random number is calculated with the following formula:

rand = Keccak( Randomness . Caller . Nonce . RandCallIndex )
  • Randomness is the block randomness signed by DKG set, unique for each block.
    • Note: Randomness field is not available in the initial round.
  • Caller is the address of the contract caller.
  • Nonce is the account nonce of the original caller.
  • RandCallIndex number of times OP_RAND is called in the current transaction.

DEXON Network Cryptoeconomics

DEXON Foundation Last Modified 2019/3/4 v6.0

*This document describes the current plan and vision for the DEXON Network platform. While we intend to attempt to realize this vision, please recognize that it is dependent on a number of factors and subject to a wide range of risks. We do not guarantee, represent or warrant any of the statements in this document, because they are based on our current beliefs, expectations and assumptions, about which there can be no assurance due to various anticipated and unanticipated events that may occur. Please know that we seek to achieve the vision laid out in our whitepaper and website, but that you cannot rely on any of it coming true. Blockchain, cryptocurrencies, other aspects of our technology and these markets are in their infancy and will be subject to many challenges, competition and a changing environment.

Token Allocation

The total supply of DXN tokens is fixed at 4 billion. The genesis token supply is 1 billion DXN and the other 3 billion DXN will be minted as mining rewards after DEXON mainnet launches. The token allocation is shown below:



Figure 1. Token Allocation

  • 75% for Miner’s Reward

    For rewarding miners that actively participate in network consensus and smart contract executions on DEXON Network.

  • 25% for Genesis Supply

    The genesis supply will be distributed to 4 parties, including DEXON Foundation / Team and
    private sale token purchasers under different vesting schedules.

Mining Model

Nodes that actively participate in validating transactions will get DXN tokens as mining rewards based on DEXON’s Proof of Participation Model.

Proof-of-Participation Model

  • Validator Eligibility

A node is eligible to join as a validator if its DXN token deposit reaches the threshold of 1 million DXN. The deposit can come from the node itself or from any other accounts that support the node. It takes 24 hours for the deposit to become effective, and another 24 hours for deposit withdrawals to become effective.

  • Symmetric Validator Power

The validating power and the probability to be selected as a block producer among all validators are both fair and symmetric, meaning that the expected mining rewards of each validator will be the same as well.

  • Mining Rewards

A validator earns transaction processing fees, gas fees, and mining rewards when it actively produces blocks and acks to other blocks.

Adaptive Mining Mechanism

DEXON adopts a novel adaptive mining mechanism that can self-adjust the token minting velocity. The token minting velocity is proportional to the participation rate of mining. If the demand of DXN token is strong, it will attract more token holders to participate in mining for rewards, hence the minting velocity will increase, and vice versa. This will make sure the system can keep demand and supply balanced by itself.

The formula of minting velocity is stated below:

r is total supply growth rate (the annual growth rate of total supply), vis node mining velocity (the annual mining rate of each node), and is mining participation rate (the percentage of deposited tokens in validators relative to current total token circulation). Initially, v is 18.75% and will alter based on the total minted tokens under a half-life condition. The relation between node mining velocity and minted tokens is shown below:
  • v= 18.75% when mainnet launches.

  • v= 9.375% after 1.5 billion DXN tokens are minted.

  • v= 4.6875% after another 750 million DXN tokens are minted, and so on.

As an example, inniitialy each node can mine 1M * 18.75% = 187.5K DXN tokens per year. As total minted tokens hit 1. 5B DXN, the annual mining rate per node will decrease from 18.75% to 9.375%, and as total minted tokens hit 2. 25B DXN, the annual per node mining rate will decrease further from 9.375% to 4.6875%, and so on.



Figure 2. Node Mining Velocity Half-Life Threshold

Mining Rewards in Circulation

Now, let’s consider the influence of mining participation rate. For example, the genesis supply of DXN token is 1 billion, if 500 millions tokens are deposited in validating nodes, the mining participation rate will be 50%. So the total supply growth rate will be 18.75% * 50% = 9.375%. The total mining rewards in circulation based on different participation rates (30%, 50%, 70%) is shown in the figure below:



Figure 3. Total Mining Rewards in Circulation

Assuming the mining participation rate is fixed at 50%, r(total supply growth rate) per year is shown below:



Figure 4. Total Mining Rewards in Circulation

``` [ { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "dkgSuccesses", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "notarySetSize", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "nodes", "outputs": [ { "name": "owner", "type": "address" }, { "name": "publicKey", "type": "bytes" }, { "name": "staked", "type": "uint256" }, { "name": "fined", "type": "uint256" }, { "name": "name", "type": "string" }, { "name": "email", "type": "string" }, { "name": "location", "type": "string" }, { "name": "url", "type": "string" }, { "name": "unstaked", "type": "uint256" }, { "name": "unstakedAt", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "notaryParamBeta", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "miningVelocity", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "lambdaBA", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "minStake", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "crsRound", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "notaryParamAlpha", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "dkgSuccessesCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "dkgFinalizeds", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "blockGasLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "dkgRound", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "totalStaked", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "nodesOffsetByAddress", "outputs": [ { "name": "", "type": "int256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "crs", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "roundLength", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "nextHalvingSupply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "dkgComplaints", "outputs": [ { "name": "", "type": "bytes" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "bytes32" } ], "name": "dkgMasterPublicKeyOffset", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "dkgMPKReadys", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "lastHalvedAmount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "bytes32" } ], "name": "finedRecords", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "lambdaDKG", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "fineValues", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "roundHeight", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "dkgMPKReadysCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "minBlockInterval", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "dkgMasterPublicKeys", "outputs": [ { "name": "", "type": "bytes" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "lastProposedHeight", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "minGasPrice", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "dkgFinalizedsCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "bytes32" } ], "name": "dkgComplaintsProposed", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "nodesOffsetByNodeKeyAddress", "outputs": [ { "name": "", "type": "int256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "lockupPeriod", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "dkgResetCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "anonymous": false, "inputs": [], "name": "ConfigurationChanged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "Round", "type": "uint256" }, { "indexed": false, "name": "CRS", "type": "bytes32" } ], "name": "CRSProposed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "NodeAddress", "type": "address" }, { "indexed": true, "name": "NewOwnerAddress", "type": "address" } ], "name": "NodeOwnershipTransfered", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "NodeAddress", "type": "address" }, { "indexed": false, "name": "PublicKey", "type": "bytes" } ], "name": "NodePublicKeyReplaced", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "NodeAddress", "type": "address" }, { "indexed": false, "name": "Amount", "type": "uint256" } ], "name": "Staked", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "NodeAddress", "type": "address" }, { "indexed": false, "name": "Amount", "type": "uint256" } ], "name": "Unstaked", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "NodeAddress", "type": "address" }, { "indexed": false, "name": "Amount", "type": "uint256" } ], "name": "Withdrawn", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "NodeAddress", "type": "address" } ], "name": "NodeAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "NodeAddress", "type": "address" } ], "name": "NodeRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "NodeAddress", "type": "address" }, { "indexed": false, "name": "Type", "type": "uint256" }, { "indexed": false, "name": "Arg1", "type": "bytes" }, { "indexed": false, "name": "Arg2", "type": "bytes" } ], "name": "Reported", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "NodeAddress", "type": "address" }, { "indexed": false, "name": "Amount", "type": "uint256" } ], "name": "Fined", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "NodeAddress", "type": "address" }, { "indexed": false, "name": "Amount", "type": "uint256" } ], "name": "FinePaid", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "Round", "type": "uint256" }, { "indexed": false, "name": "BlockHeight", "type": "uint256" } ], "name": "DKGReset", "type": "event" }, { "constant": false, "inputs": [ { "name": "NewOwner", "type": "address" } ], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "MinStake", "type": "uint256" }, { "name": "LockupPeriod", "type": "uint256" }, { "name": "MinGasPrice", "type": "uint256" }, { "name": "BlockGasLimit", "type": "uint256" }, { "name": "LambdaBA", "type": "uint256" }, { "name": "LambdaDKG", "type": "uint256" }, { "name": "NotaryParamAlpha", "type": "uint256" }, { "name": "NotaryParamBeta", "type": "uint256" }, { "name": "RoundLength", "type": "uint256" }, { "name": "MinBlockInterval", "type": "uint256" }, { "name": "FineValues", "type": "uint256[]" } ], "name": "updateConfiguration", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "NewOwner", "type": "address" } ], "name": "transferNodeOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "OldOwner", "type": "address" }, { "name": "NewOwner", "type": "address" } ], "name": "transferNodeOwnershipByFoundation", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "NewPublicKey", "type": "bytes" } ], "name": "replaceNodePublicKey", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "nodesLength", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "Round", "type": "uint256" }, { "name": "SignedCRS", "type": "bytes" } ], "name": "proposeCRS", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "Complaint", "type": "bytes" } ], "name": "addDKGComplaint", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "PublicKey", "type": "bytes" } ], "name": "addDKGMasterPublicKey", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "MPKReady", "type": "bytes" } ], "name": "addDKGMPKReady", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "Finalize", "type": "bytes" } ], "name": "addDKGFinalize", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "Success", "type": "bytes" } ], "name": "addDKGSuccess", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "PublicKey", "type": "bytes" }, { "name": "Name", "type": "string" }, { "name": "Email", "type": "string" }, { "name": "Location", "type": "string" }, { "name": "Url", "type": "string" } ], "name": "register", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [], "name": "stake", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "Amount", "type": "uint256" } ], "name": "unstake", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [], "name": "withdraw", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "withdrawable", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "NodeAddress", "type": "address" } ], "name": "payFine", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "Type", "type": "uint256" }, { "name": "Arg1", "type": "bytes" }, { "name": "Arg2", "type": "bytes" } ], "name": "report", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "NewSignedCRS", "type": "bytes" } ], "name": "resetDKG", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ] ```

Configuration Change

Overview

The configuration for DEXON is round based configuration, which is allowed to be changed and applied in upcoming rounds on the fly without shutting down or forking the system. Each configuration will become effective two rounds after updating. Configurable parameters including:

  • MinStake: minimum stake required for becoming a bp.
  • LockupPeriod: time required for funds available for withdrawing after unstake.
  • MinGasPrice: minimum gas price.
  • LambdaBA, LambdaDKG: period for each step for DEXON Byzantine Agreement and DEXON DKG protocol.
  • NotaryParamAlpha, NotaryParamBeta: parameter for calculating notary set size. Refer to Selection of notary set size.
  • RoundLength: the number of blocks in a round.
  • MinBlockInterval: the minimum interval of timestamps between blocks on the blockchain.
  • FineValues: penalty for not following protocol. Refer to Rule for the DEXON node set.

DEXON's automatic recovery mechanism will kick in in the catastrophic event that complete DEXON Network shutdown to ensure DEXON can still reach consensus even without DEXON consensus algorithm.

Nodes in the last notary set will vote on the external decentralized blockchain to determine which block height to be the point of recovery. Once a particular block height h has more than half of the notary set voted, the recovery consensus is reached. Block height of h+1 will be an empty block and DEXON consensus algorithm will continue running at height h+2.

Resource

DEXON Comparison to Other Blockchain

Introduction

This document explains how DEXON is different compared to other blockchain infrastructures. We do our best to explain the main differences, but still, we have the following principles:

  1. We will not dive into details of other projects. We only focus on the differences. For the details, please refer to their websites and whitepapers.
  2. The comparison is based on our current understanding, and projects can be updated frequently. We will update this document if necessary.

Definition

  • Node in this document is a validator or a full node in the network.
  • : network delay between nodes
  • : number of nodes
  • : number of blocks to be confirmed
  • : ack frequency
  • For smart contract column:
    • O: Supprted
    • X: Not supported
    • △: Not supported for now, but is able to support

Table of Contents

Project Throughput (TPS) Latency (seconds) Data Structure Consensus Smart Contract
DEXON10K1chainByzantine agreementO
Algorand875< 60chainByzantine agreement
Bitcoin73600chainlongest chain ruleX
Cardano250300chainOuroborosO
Conflux6400270DAGGHOST
Dfinity500 ~ 10005 ~ 10chainDfinityO
EOS3K165chainlongest chain & Byzantine fault toleranceO
Ethereum20360chainlongest chainO
Hashgraph200K20DAGHederaO
Hyperledger4K< 1chainpluggableO
IOTA500 ~ 800> 180DAGlongest chain ruleX
Kadena10K20DAGChainwebO
NANO70001DAGDPoS votingX
Omniledger6K10chainByzCoinX
Ontology5K20DAGOntorandO
Orbs Helix10NAchainPBFTO
PhantomNANADAGgreedy selection algorithm
Radix3.55chainlogical clockO
Snowflake13004DAGAvalanche
SpectreNA1 ~ 10DAGblock voting algorithmX
Stellar1K ~ 10K2 ~ 5chainStellar ConsensusO
TendermintNA1 ~ 3chainPBFT
ThunderellaNA1.5chainBFT + longest chain
TONM+5DAGBFTO
ViteNA10DAGlongest chainO
Zilliqa3K10 ~ 20chainPBFTO

DEXON

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
10K1chainDEXON Byzantine agreementO

DEXON is a scalable, low-latency, energy efficient and inter-chain operable DApp ecosystem. DEXON uses an efficient Byzantine agreement as its main consensus algorithm, of which throughput can scale linearly with the number of nodes while latency remains nearly constant. With the adoption of verifiable random function, DEXON can provide high performance while keeping the network decentralized (~ 100K nodes). With such high throughput and low latency, practical DApp can finally be developed and widely used.

Algorand

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
875< 60chainByzantine agreement

Algorand is designed for a large population ( ~ 500K nodes). They use a verifiable random function to protect nodes from DDoS attack, and it is the lottery that decides who have the right to propose a block or to vote for each round.

The consensus of Algorand is based on Byzantine agreement among samples from the whole set of nodes. This is the reason why Algorand can only tolerate less than one-third of the total number of nodes. For example, if it sets 1/5 as the maximum ratio of Byzantine nodes among all nodes, the ratio of Byzantine nodes in samples can be bounded by 1/3 with high probability.

They use gossip mechanism that costs a latency of for each message, which means its confirmation time becomes longer when the number of nodes increases and scatters around the world. With this limitation, the confirmation time will be around one minute if the number of nodes is expected to be 500K. Another factor that will affect the confirmation time is Byzantine behavior. If a Byzantine node wins the lottery and becomes a leader, the process of the Byzantine agreement will need more round to converge. On the other hand, DEXON's confirmation time is not affected by Byzantine behavior as long as the number of Byzantine nodes is less than one-third of total nodes.

If Algorand wants to increase its throughput, it must increase block size. However, increasing block size causes a longer network delay, increasing the confirmation time. This means Algorand is lack of scalability. On the other hand, DEXON increases throughput by increasing the number of nodes without affecting the confirmation time.

Bitcoin

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
73600chainlongest chain ruleX

Bitcoin is the first cryptocurrency that starts the era of blockchain. It is the most well-known and widely used cryptocurrency. However, it is infamous for its long confirmation time, low TPS and high transaction fee. DEXON solves all of them and at the same time provides DApp functionality, which Bitcoin does not have.

Cardano

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
250300chainOuroborosO

Cardano is the first project that provides a concrete mathematical proof on the security of PoS blockchain. Besides PoS, they also propose other promising ideas such as unbiased randomness with the commit-reveal scheme and using Nash Equilibrium to prevent selfish mining attack. However, its chain-based structure naturally limits its throughput, since chain-based structure can only process block linearly, and can be proved that it can not scale.

Another problem in Cardano consensus is that it highly depends on time synchronization. If some honest nodes are desynchronized (for example, NTP service hijack by an attacker), they do not know when is the starting time of a slot and will be treated as fail-stop nodes. They claimed desynchronized nodes could be corrected by some method introduced in the future, but it is not implemented yet.

Conflux

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
6400270DAGGHOST

Conflux is a graph-based PoW consensus based on GHOST protocol that fixed the Phantom blockchain. Conflux uses GHOST protocol to select the main chain in a graph and produces a total ordering of the graph by the main chain. Thus, it is generalized Bitcoin consensus, and they also point out that the bias problem in Phantom blockchain.

However, the latency is bounded by its PoW mechanism. It needs to wait for a period to select the correct and consistent main chain with high probability. Even if it switched to a PoS mechanism, the latency would still be unacceptably long since the GHOST protocol is a kind of longest chain rule consensus.

Dfinity

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
500 ~ 10005 ~ 10chainDfinityO

Dfinity is a permissioned blockchain and is designed for a large population (around 10K of nodes). Dfinity contains a randomness beacon which generates new randomness by a VRF (verifiable random function) with information from a new confirmed block. They use the randomness to select a leader and electors for a round. By hypergeometric distribution, Dfinity only samples hundred of nodes to notary a block instead of using all nodes, and this is correct with high probability. However, this reduces the tolerance ability to Byzantine nodes. For example, to achieve the majority of nodes is non-Byzantine with probability less than , it needs to sample at least 423 nodes from 10K nodes with maximum 1/3 Byzantine nodes. However, Dfinity is chain-based, so its throughput is limited.

EOS

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
3K165chainlongest chain & Byzantine fault toleranceO

EOS reaches high throughput and low latency. They have 21 so-called "supernodes," which are considered not decentralized. Also, at the time of writing, its Byzantine fault tolerance consensus is not implemented yet, so the confirmation time is about 165 seconds, not 1 or 2 seconds as they claimed.

Ethereum

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
20360chainlongest chainO

Ethereum is the first blockchain system that has a complete DApp ecosystem. It has a throughput higher and latency lower than Bitcoin, but still not enough for daily usages such as payment or gaming. A popular DApp can block the whole system, causing high transaction fee. Also, the latency now (several minutes) is not acceptable for real-time applications.

Hashgraph

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
200K20DAGHederaO

The consensus of Hashgraph is adapted Byzantine agreement on a graph, on the other hand, the core of DEXON consensus is a responsive Byzantine agreement algorithm. Their round-based structure costs a latency of for each round, which means its confirmation time becomes longer when the number of nodes increases. With this limitation, it cannot be fully decentralized, or the confirmation time can be minutes. Also, the liveness is not guaranteed in Hashgraph. Only correctness proof is provided. With Byzantine nodes presented in its network, it is possible that Hashgraph does not output any block. Meanwhile, DEXON's confirmation time does not increase when the number of nodes increases. Since DEXON consensus has responsiveness, the confirmation time only depends on the actual network speed, not some predefined paramters.

Hyperledger

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
4K< 1chainpluggableO

Hyperledger (specifically, Hyperledger Fabric) is a distributed ledger designed for enterprise use. It should be permissioned, low-latency, high-throughput and provides private transaction functionalities. Its consensus is modularized and pluggable. It can choose among consensus engines/algorithms such as Tendermint, PBFT, Kafka ordering or RAFT.

It is much easier to address consensus problem in a permissioned consortium settings with high throughput and low latency because the assumption of the environment is: the number of nodes is fixed, each identity is known, the goal of all nodes is the same, and the network environment is stable and fast, but the node does not fully trust to each other. It does fit for enterprises to use such settings, while DEXON aims to be more open and decentralized, providing high throughput and low latency at the same time.

IOTA

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
500 ~ 800> 180DAGlongest chain ruleX

IOTA follows the longest chain rule on a graph: a node randomly chooses and verifies two previous blocks and attaches its block to them. A block is confirmed if enough number of blocks followed it and the length of the connected chain is the longest. However, the rule is inefficient because the confirmation time is not guaranteed by a specific bound. Moreover, a block might be invalid if it is attached to a block that contains conflict transactions. That block has to be re-attached to other blocks. This causes a very long confirmation time. Furthermore, IOTA does not support smart contract due to the lack of total ordering among all blocks.

Kadena

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
10K20DAGChainwebO

Kadena aims to solve the scalability issue of blockchain. Each chain in Kadena includes others' block headers, forming a so-called Chainweb. Chainweb processes transactions in parallel. To perform cross-chain transactions, one has to provide Merkle proof to smart contract, and assets will be deleted from source chain and re-created on destination chain. Kadena also analyzes peer header relationships and uses specifically designed graphs that have a small diameter and large order to achieve low latency and high throughput.

The latency of Chainweb is , where is the diameter of a graph. When it scales up and increases the number of chains, the diameter of the graph also becomes larger, causing the latency to increase. Another problem is when proposing a block on a chain. The block has to include its peer's block headers. This means block proposing is blocking and not efficient, while in DEXON, a block actively acks any other newly proposed blocks, achieving fast non-blocking block proposing.

NANO

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
70001DAGDPoS votingX

NANO is the first project that introduces blocklattice as their data structure. Each account has its blockchain, and a transaction it proposed is recorded on its blockchain. When a blockchain fork happens, NANO starts DPoS voting to resolve it.

DEXON chain structure is entirely different from NANO's. In DEXON, instead of every account having its blockchain, each validator has a blockchain. This could save a lot of memory space compared to NANO. In DEXON, each vertex is a block, while in NANO, each vertex is half of a transaction (send tx or recv tx). From our viewpoint, their blocklattice is more like "tx-lattice," not blocklattice, and we consider blocklattice a general term that can be used by other projects, just like blockchain, since it is just a type of DAG.

DEXON's consensus algorithm is also completely different from NANO's. Validators in DEXON rely on DEXON fast Byzantine agreement algorithm to decide sequence of blocks and transactions, while NANO does not have consensus on order of transactions. Without ordering transactions, it can not support smart contract. Another problem is its DPoS to resolve fork. The voting process NANO used to resolve fork is mysterious. In its whitepaper, there is no detail about the voting process. The only thing we know is a majority voting with 4 rounds. Without further detail and security proof, we find it hard to believe that NANO is secure. Also, NANO needs PoW to prevent spam (penny) attack, increasing the cost of attack but also limiting its throughput and increasing its latency.

Omniledger

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
6K10chainByzCoinX

Omniledger aims to solve scalability problem without sacrificing security and decentralization. Its primary approach is sharding, which allows the throughput to scale linearly with the number of nodes. Omliledger also provides nice features such as ledger pruning, cross-shard transaction, and trust-but-verify validation.

The problem of Omniledger is that its latency could be large in a fully decentralized setting. The reason is that it uses ByzCoinX (which is an optimization of PBFT-like consensus algorithm) for intra-shard consensus and Atomix (DB-like atomic broadcast) for inter-shard transactions. This means the group size in a shard for communication cannot be too large, or the communication cost and latency will be large. To increase the number of nodes with limited shard size, the number of shards will increase, and the needs for cross-shard transactions will also increase. With atomic broadcast, a cross-shard transaction has to wait for every involved shard to be confirmed, and even a single shard failed will cause the transaction to fail. In DEXON, transactions only need to enter one shard and will be output immediately.

Omniledger also sacrifices some of the security. According to hypergeometric distribution, if the sampled Byzantine nodes in a shard must be less than one third, one can only tolerate Byzantine nodes much less than one third in the whole network, or sampling cannot be successful with high probability. This is why the number of Byzantine nodes Omniledger can tolerate is one fourth, not one-third of total nodes.

Ontology

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
5K20DAGOntorandO

Ontology consensus algorithm Ontorand uses randomness from the last block to generate new block proposer and validators. Its Byzantine agreement voting process (although not detailed enough) looks extremely similar to Algorand. Its verifiable random function which generates randomness in a block is exactly the same as Algorand. Without any citation and improvement from Algorand, Ontorand is nothing but a copycat. For the comparison to Algorand, please reference here.

Orbs Helix

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
10NAchainPBFTO

The top priority of Helix is fairness. It uses VRF (verifiable random function) as an unbiased random source to elect committee and leader. When running its core consensus (PBFT), all transactions are encrypted by users using threshold encryption. This means there is no way a node can censor or prioritize any transaction. After consensus is reached, the content of a block is then decrypted, and transactions are executed. Thus, the order of transactions cannot be biased, achieving fairness. Helix also uses VRF to decide which transaction can be put into a block. Because nodes cannot decide which transactions to be put into a block, transaction fees can be set to a constant.

Unfortunately, fairness does not come without cost. Threshold encryption not only increases computational cost but needs an extra phase of decryption. This increase the latency. What's worse, its chain structure is not scalable. To solve the scalability problem, Orbs introduces "intelligent sharding" (which we did not find any technical detail). A recent simulation shows that Helix has only 10 TPS (with unknown latency). With 100 shards, it can reach 1000 TPS, while DEXON has 1M+ TPS with a hundred nodes in one shard.

Phantom

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
NANADAGgreedy selection algorithm

Phantom is a DAG-based blockchain which is generalized from Bitcoin's longest chain rule on a chain to a DAG. Phantom is a proposal for Spectre, and they proposed a greedy algorithm called ghostDAG protocol to achieve total ordering. However, they did not prove the correctness and liveness of their algorithm or provide the simulation results about Phantom in the distributed setting. Another liveness attack on Phantom was individually proposed by the work from Li et al. and the work from Kiayias and Panagiotakos. They also claimed they would try to combine Phantom and Spectre in the future. We will update the information if they provide new and correct results.

In DEXON, the correctness and liveness of DEXON Byzantine agreement are both strictly proved.

Radix

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
3.55chainlogical clockO

Radix uses sharding technique to increase throughput. In order to reach consensus among different shards, a transaction needs to be gossipped and be validated by many nodes. Each node provides its local logical clock and appends its value to the transaction. Nodes can then use this logical clock vector to decide partial ordering between two conflict transactions. In case of a concurrent set, a node finds other transactions from its local storage or from its peer trying to decide partial ordering of transactions.

There is a fundamental problem in Radix: a partial ordering can never become total ordering without consensus algorithm. Some partial ordering of transactions in Radix can be decided by vector timestamps, but no matter how many transactions are involved, there always exists some cases that concurrent set can never be resolved. In other words, orders of some transactions may never be decided and will not be output by the system. What's worse, when a network is shortly partitioned or has a long network delay, nodes can have different local views. Since a node decides an ordering from other transactions from its local view, this will cause different ordering among nodes, resulting in a fork, and there is no consensus algorithm in Radix to address this issue.

To sum up, Radix does not have consensus. It can be used in private / permissioned settings but will not work in a real network environment.

Snowflake

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
13004DAGAvalanche

Snowflake consensus starts from a simple coloring method, adds additional counters and rules, and finally ends up a provably probabilistic secure consensus algorithm, Avalanche. All nodes converge to the same color, which means that they will agree on the same transaction set when conflict happens.

In order to resolve conflict transactions, nodes need to execute Avalanche algorithm on every transaction in a conflict set. So an attacker can spam the system with a large number of conflict transactions, resulting in the system to execute Avalanche algorithm hundreds of thousands of times, and the latency will grow significantly. DEXON will not suffer from such an attack. DEXON Byzantine agreement remains fast no matter how many conflict transactions there are.

Spectre

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
NA1 ~ 10DAGblock voting algorithmX

Spectre is a DAG-based digital ledger system that uses recursive block voting to decide which conflict block should be finalized. This consensus algorithm allows participants to propose block arbitrarily fast, which means its scalability and latency is bounded by the network. However, its lack of total ordering of blocks makes it impossible to execute a smart contract. That is the reason why they propose "Phantom," a consensus that is also DAG-based but with total ordering properties. We also compare DEXON to Phantom.

Stellar

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
1K ~ 10K2 ~ 5chainStellar ConsensusO

Stellar uses a generalized version of traditional Byzantine agreement protocol, which they called "federated Byzantine agreement." This consensus algorithm requires participants to choose their own quorum slices. If quorum intersection is satisfied, it is proved that all intact participants will reach consensus.

The only concern about this kind of consensus is that whether a node can remain intact (not affected by Byzantine nodes) depends on the choice of its quorum slices. In order to have a secure configuration with fast response and stable service, it is better for a node to choose nodes set up by reliable companies or banks as quorum slices, which may lead to semi-centralization.

Tendermint

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
NA1 ~ 3chainPBFT

Tendermint uses PBFT as their consensus algorithm. Although PBFT has low latency in permissioned settings, it can not be permissionless, because PBFT has a heavy communication cost of due to its two-phase commit. This means when the number of nodes increases, the required bandwidth of network will also increase quadratically, limiting the number nodes. DEXON uses cryptographic sortition sharding technique and configurable ack frequency to reduce the communication cost to .

Thunderella

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
NA1.5chainBFT + longest chain

Thunderella combines two different consensus algorithms and tries to achieve high security with good performance. With less than one-fourth of the committee are Byzantine nodes, it can achieve a low latency with BFT algorithm. With more than one fourth, it can fall back to any blockchain system that can tolerate less than Byzantine nodes.

If more than one-fourth of the committee is Byzantine node, Thunderella becomes as slow as a blockchain, while DEXON remains its low latency. Also, Thunderella is a chain-based system, and it can not scale.

TON

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
M+5DAGBFTO

TON (Telegram Open Network) is a blockchain system featuring high throughput with short confirmation time. To achieve this, they propose a new point of view called "Infinite Sharding Paradigm," which tries to push sharding to its extreme. In TON, there is a masterchain for general state finalization. Under a masterchain, there are several workchains to perform specific tasks for different cryptocurrencies and services. If a workchain is overloaded, under that it can have several shardchains to increase throughput. In each chain, validators run a BFT-based consensus algorithm with a DPoS mechanism to propose blocks. With this sharding design, TON claims it can reach several millions of TPS with 5 seconds latency.

One significant difference between TON and DEXON is that TON needs to run BFT consensus algorithm on several different levels of the chains. For masterchain, it requires all validators to participate in BFT algorithm. Since BFT algorithm is typically not scalable, we can only have a limited number of nodes to participate in masterchain. This can be considered a bit centralized. In DEXON, we do not require all nodes to run a single BFT algorithm; thus we can have hundreds of thousands of nodes participating in our system.

TON also has a finalization problem. It allows validators to modify invalid blocks without forking since it is more efficient and will only affect some history blocks. However, this design also allows an attacker to modify arbitrary history blocks if they can compromise the validator set. Typically in a system with BFT finalization, it should be impossible to modify history even if the current validator set is compromised. Even in traditional PoW scheme, launching a 51% attack and modifying history blocks has a much higher cost with low probability to success. This design may cause security issue in TON.

Vite

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
NA10DAGlongest chainO

Vite mainly fixes NANO's problem we mentioned in our comparison to NANO. It uses the same blocklattice with NANO, but additionally adds a new consensus mechanism (HDPoS) to construct a snapshot chain. This not only solves security issues in NANO but also orders transactions, making it capable to run smart contract. What's more, Vite inherits NANO's advantages, including nearly instant transactions with high TPS.

One of the difficult challenges to use a DAG structure is to decide the ordering of transactions. Vite has a global consensus group to run a consensus algorithm to create snapshot chain. This algorithm is important because it is the key to improve NANO's disadvantages on security and lack of total ordering. Unfortunately, we can not find any detail about the algorithm in their paper and do not know how transactions on blocklattice are picked and put into snapshot chain. Is this critical process secure and fair? To address this challenges, DEXON develops our own fast Byzantine agreement algorithm, and it is provably secure and reasonably fair.

Zilliqa

Throughput (TPS)Latency (seconds)Data StructureConsensusSmart Contract
3K10 ~ 20chainPBFTO

Zilliqa is an optimized PBFT. It uses EC-Schnorr multi-signature to aggregate signatures from nodes. This reduces communication cost from to . To address limited throughput in a chain-based system, Zilliqa uses sharding technique to process transactions in parallel. A specific shard collects micro blocks from normal shards to produce final blocks.

There are several drawbacks in Zilliqa. First of all, multi-signature aggregation is computationally costly. This is not a problem with ten-second finalization time, but in sub-second finalization time, it is not feasible with a large number of nodes in a shard. Second, Zilliqa uses a specific shard running consensus protocol to combine micro blocks from other shards. This doubles the latency. In DEXON, there is no specific shard to run another redundant consensus protocol. DEXON uses state sharding, which means each shard only stores state related to itself. This sharding mechanism is symmetric, which means every shard has the same contribution in terms of consensus, and this is considered more fair.

DEXON papers

Reserved Network IDs

NetworkID (or ChainID) is a mechanism to separate networks(or chains) owned by different organizations. DEXON foundation reserves these networkIDs:

  • 237: mainnet
  • 238: testnet
  • 239, 240: private testnet during development.

Reference

Exchange Integration Guide

This guide provides all the necessary details for integrating DEXON with your exchange.

Wallet

DEXON TX signature algorithm is exactly the same as Ethereum (secp256k1), you can use existing Ethereum wallet with DEXON.

RPC

DEXON RPC is compatible with Ethereum. In theory, you can use existing Ethereum module with DEXON by replacing the RPC endpoint:

NetworkRESTfulWebSocketChain ID
Mainnethttps://mainnet-rpc.dexon.orgwss://mainnet-rpc.dexon.org/ws237
Testnethttps://testnet-rpc.dexon.orgwss://testnet-rpc.dexon.org/ws238
Taipei Testnethttps://taipei-rpc.dexon.orgwss://taipei-rpc.dexon.org/ws239

Since DEXON produce around 1 block per second, it may incur a heavier load on your database infrastructure. Make sure you have enough DB instance to handle the load.

Starting a RPC Node

Refer to Running a RPC node for instructions to launch a RPC node by yourself.

Deposit Confirmation

DEXON consensus algorithm has explicit finality, meaning you only need to wait for 1 block confirmation to credit the deposit. If you really want to make sure, you can wait for 2 confirmations to be sure.

Explorer

Explorer link is as follows:

NetworkExplorer
Mainnethttps://dexscan.org
Testnethttps://testnet.dexscan.org
Taipei Testnethttps://taipei.dexscan.org